diff --git a/branches/s100/Applegate/Makefile b/branches/s100/Applegate/Makefile deleted file mode 100644 index 0f330c29..00000000 --- a/branches/s100/Applegate/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# Makefile 1/31/2013 dwg - - -TASM := ../XSource/bin/TASM -TASMTABS := . -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -all: zapple.bin cpm.bin bios.bin - -tasm80.tab: bin/TASM80.TAB - cp bin/TASM80.TAB tasm80.tab - -tasm85.tab: bin/TASM85.TAB - cp bin/TASM85.TAB tasm85.tab - -cpm.bin: cpm22.asm - $(ASMIMG) $< $@ - -bios.bin: bios.asm s100iobd.inc - $(ASMIMG) bios.asm $@ - -zapple.bin: zapple.asm zapple.z80 - $(ASMIMG) zapple.asm $@ - -clean: - rm -f *.lst *.bin diff --git a/branches/s100/Applegate/bios.asm b/branches/s100/Applegate/bios.asm deleted file mode 100644 index 4342ceec..00000000 --- a/branches/s100/Applegate/bios.asm +++ /dev/null @@ -1,1502 +0,0 @@ -;******************************************************** -; Bob's very simple BIOS. -; -; Work started in, oh, I don't know, probably 2008. - -; Work RE-started on 02/14/2013 -; -; Hardware description: -; -; Northstar ZPU -; CCS 2710 serial port. Console on first port. -; N8VEM 4MB RAM with only 1 MB installed -; N8VEM IDE with a CF card -; -; This is a merge of many pieces of code from all over -; the net, very little of it is mine other than some -; glue logic. So, here are some of the sources of info -; and code I borrowed from: -; -; www.speakeasy.org/~rzh/bios.mac -; http://www.s100computers.com/My%20System%20Pages/IDE%20Board/My%20IDE%20Card.htm -; -; These are some of my include files to make things easier -; for me. -; -#include "tasm.inc" -#include "cpm22.inc" -; -; Put out a bit of diagnostics -; - .echo "Building a BIOS for a RAM size of " - .echo RAMSIZE - .echo "K\n" -; -; Common CP/M items -; -DefaultDisk equ TDRIVE ;I like this name better -BDOSEntry equ (CCPBASE+CCPSIZE+6) -CPM_SECTOR_SIZE equ 128 -; -; Base ports of various I/O devices. -; -IDE_PORT EQU 030H ;IDE board -; -; Base memory locations of various things -; -CCPEntry EQU CCPBASE -CPM_VERSION .equ 22H ;CP/M version -; -; Constants -; -FALSE .equ 0 -TRUE .equ ~FALSE -; -; ASCII constants -; -CR .equ 0dh -LF .equ 0ah -BELL .equ 07h -EOF .equ 01ah ;CTRL-Z is CP/M EOF -; -; IDE board constants -; -IDEportA EQU IDE_PORT+0 ;Lower 8 bits of IDE interface (8255) -IDEportB EQU IDE_PORT+1 ;Upper 8 bits of IDE interface -IDEportC EQU IDE_PORT+2 ;Control lines for IDE interface -IDEportCtrl EQU IDE_PORT+3 ;8255 configuration port - -READcfg8255 EQU 10010010b ;Set 8255 IDEportC out, IDEportA/B input -WRITEcfg8255 EQU 10000000b ;Set all three 8255 ports output - -;IDE control lines for use with IDEportC. Change these 8 -;constants to reflect where each signal of the 8255 each of the -;IDE control signals is connected. All the control signals must -;be on the same port, but these 8 lines let you connect them to -;whichever pins on that port. - -IDEa0line EQU 01H ;direct from 8255 to IDE interface -IDEa1line EQU 02H ;direct from 8255 to IDE interface -IDEa2line EQU 04H ;direct from 8255 to IDE interface -IDEcs0line EQU 08H ;inverter between 8255 and IDE interface -IDEcs1line EQU 10H ;inverter between 8255 and IDE interface -IDEwrline EQU 20H ;inverter between 8255 and IDE interface -IDErdline EQU 40H ;inverter between 8255 and IDE interface -IDErstline EQU 80H ;inverter between 8255 and IDE interface -; -;Symbolic constants for the IDE Drive registers, which makes the -;code more readable than always specifying the address pins - -REGdata EQU IDEcs0line -REGerr EQU IDEcs0line + IDEa0line -REGseccnt EQU IDEcs0line + IDEa1line -REGsector EQU IDEcs0line + IDEa1line + IDEa0line -REGcylinderLSB EQU IDEcs0line + IDEa2line -REGcylinderMSB EQU IDEcs0line + IDEa2line + IDEa0line -REGshd EQU IDEcs0line + IDEa2line + IDEa1line ;(0EH) -REGcommand EQU IDEcs0line + IDEa2line + IDEa1line + IDEa0line ;(0FH) -REGstatus EQU IDEcs0line + IDEa2line + IDEa1line + IDEa0line -REGcontrol EQU IDEcs1line + IDEa2line + IDEa1line -REGastatus EQU IDEcs1line + IDEa2line + IDEa1line + IDEa0line - -;IDE Command Constants. These should never change. - -COMMANDrecal EQU 10H -COMMANDread EQU 20H -COMMANDwrite EQU 30H -COMMANDinit EQU 91H -COMMANDid EQU 0ECH -COMMANDspindown EQU 0E0H -COMMANDspinup EQU 0E1H -; -; -; IDE Status Register: -; bit 7: Busy 1=busy, 0=not busy -; bit 6: Ready 1=ready for command, 0=not ready yet -; bit 5: DF 1=fault occured insIDE drive -; bit 4: DSC 1=seek complete -; bit 3: DRQ 1=data request ready, 0=not ready to xfer yet -; bit 2: CORR 1=correctable error occured -; bit 1: IDX vendor specific -; bit 0: ERR 1=error occured -; -; - -; -; A Z80 JP instruction is manually put into a few locations -; by the BIOS, so here is an equate for that instruction. -; -JMP equ 0c3h - .page -;******************************************************** -; PRIMARY JUMP TABLE. ALL CALLS FROM CP/M TO THE CBIOS -; COME THROUGH THIS TABLE. -;******************************************************** -; - .org BIOSBASE -; - JP CBOOT ;COLD BOOT -WBOOTE: JP WBOOT ;WARM BOOT - JP CONST ;CONSOLE STATUS - JP CONIN ;CONSOLE CHARACTER IN - JP CONOUT ;CONSOLE CHARACTER OUT, - JP LIST ;LIST CHARACTER OUT - JP PUNCH ;PUNCH CHARACTER OUT - JP READER ;READER CHARACTER IN - JP HOME ;MOVE HEAD TO HOME POSITION - JP SELDSK ;SELECT DISK - JP SETTRK ;SET TRACK NUMBER - JP SETSEC ;SET SECTOR NUMBER - JP SETDMA ;SET DMA ADDRESS - JP READ ;READ DISK - JP WRITE ;WRITE DISK - JP LISTST ;RETURN LIST STATUS - JP SECTRA ;SECTOR TRANSLATE -; -;******************************************************** -; Sneaking little Bob trick. My program to write CP/M -; to the disk needs to know the end of the BIOS, so I -; decided to put the last memory location used by the -; BIOS into the two bytes before the CBOOT code. So the -; program can find the end by picking up the first JP -; address in the jump table, and backing up two bytes. -; - DW BIOS_END - .page -; -;******************************************************** -; -; This is the cold boot entry point, called from the first -; entry in the jump table. Control will be transfered here -; by the CP/M bootstrap loader. -; - -CBOOT: ld sp,0080h ;set stack pointer - call initser ;initialize the serial port - call IDEinit ;initialize the IDE interface - - - call msg - .db CR,LF,LF - .text "Bob's BIOS :)" - .db CR,LF - .text "??" - .text "K CP/M v2.2" - .db CR,LF, - .text "Drives:" - .db CR,LF - .text " A: = IDE" - .db CR,LF,LF,0 - -gocpm: di ;disable interrupts -; -; Reset the IOBYTE to go to the main terminal -; - ld a,00000001B - ld (IOBYTE),a -; -; Set the default drive to A: and user to 0 -; - xor a - ld (DefaultDisk),a -; - jp EnterCPM ;continue set-up -; -;******************************************************** -; WARNING... The warm boot code is NOT COMPLETE!!! -; -WBOOT: - call msg - TEXT "Entering WBOOT" - db CR,LF,0 - -; -; Need to add a lot of logic here to reload the CCP and -; BDOS from disk, but for now we know they're already -; loaded and no need to load again. - - - jp EnterCPM -; -;******************************************************** -; -; This routine is entered either from the cold or warm -; boot code. It sets up the JP instructions in the -; base page, and also sets the high-level disk driver's -; input/output address (also known as the DMA address). -; -EnterCPM: ld a,JMP ;Get machine code for JP - ld (0),a ;Set up Jp at location 0 - ld (ENTRY),a ;...and at location 5 -; - ld hl,WBOOTE ;Get BIOS vector address - ld (1),hl ;Put it at location 1 - - ld hl,BDOSEntry ;Get BDOS entry point address - ld (ENTRY+1),hl ;Put it at location 6 -; - ld bc,80H ;Set disk I/O address to default - call SETDMA ;Use normal BIOS routine -; - ei ;Ensure interrupts are enabled - ld a,(DefaultDisk) ;Transfer current default disk to - ld c,a ; Console Command Processor - jp CCPEntry ;Jump to CCP - - - -;******************************************************** -; Select the disk drive for future reads/writes. On entry -; C contains the drive index: C = 0 for A:, 1 for B:, etc. -; On Exit, HL contains the pointer to the disk parameter -; header (section 6.10 in the CP/M book) or 0000 if the -; requested drive is out of range. -;******************************************************** - -SELDSK: push bc - call msg - TEXT "SELDSK: " - db 0 - pop bc - push bc - ld a,c - add a,'A' - ld c,a - call CONOUT - call msg - db ':',CR,LF,0 - pop bc -; -; Temp patch... always do deblocking for now. Some day -; I might add a disk that doesn't need it, but for now -; we always need it. -; - push af - ld a,0ffh - ld (DeblockingRequired),a - pop af -; - ld hl,0 ;assume an error - ld a,c ;move drive into A - cp 1 ;compare to max drives - ret nc ;return if bad drive -; -; Compute offset to disk parameter table... drive * 16 -; - ld l,a - ld h,0 - add hl,hl ;*2 - add hl,hl ;*4 - add hl,hl ;*8 - add hl,hl ;*16 - ld de,DPBASE - add hl,de - ret -; -;******************************************************** -; FLOPPY DISK DPH TABLES. -;******************************************************** -; -; CP/M manual, 6.10, page145 -; -DPBASE: -IdeDPH: dw 0 ;no sector translation - dw 0 ;scratchpad - dw 0 - dw 0 - dw DirectoryBuffer - dw IdeDPB ;disk parameter block - dw IdeCSV ;checksum area - dw IdeALV - -IdeCSV: .FILL 0 ;no directory checksum; non-removable drive -IdeALV: .FILL 256,0 ;drive size / BLS / 8 - -;__________________________________________________________________________________________________ -; -; 8MB HARD DISK DRIVE, 65 TRKS, 1024 SECS/TRK, 128 BYTES/SEC -; BLOCKSIZE (BLS) = 4K, DIRECTORY ENTRIES = 128 -; SEC/TRK ENGINEERED SO THAT AFTER DEBLOCKING, SECTOR NUMBER OCCUPIES 1 BYTE (0-255) -; -; The SPT value was taken from the track count from MYIDE (an Andrew Lynch -; program) and then multiplied by 4 since there are 4 CP/M 128 byte sectors -; in each 512 byte physical sector. -; -; Too many magic numbers in here; add some EQUs for these and use real math -; to compute the values at assembly time. -; - .DB (4096 / 128) ; RECORDS PER BLOCK (BLS / 128) -IdeDPB: -; .DW 1024 ; SPT: SECTORS PER TRACK - .DW 32*4 ; SPT: Sectors per track, gotten from drive - .DB 5 ; BSH: BLOCK SHIFT FACTOR - .DB 31 ; BLM: BLOCK MASK - .DB 1 ; EXM: EXTENT MASK - .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((8MB - 128K OFF) / 4K BLS) - 1 = 2047 - .DW 511 ; DRM: DIR ENTRIES - 1 = 512 - 1 = 511 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 1 ; OFF: RESERVED TRACKS = 1 TRKS * (512 B/SEC * 1024 SEC/TRK) = 128K -; -DirectoryBuffer ds CPM_SECTOR_SIZE - - -; -; OLD CODE WARNING... -; This is my first attempt to calculate disk parameters. Left it all in -; here because it's the right way to do it, but needs debugging. -; -;SECSZ: equ 512 ;bytes per sector -;CPMSECS: equ (SECSZ/128) ;CP/M records per phys sector -;SECTORS: equ 64 ;sectors per track -;TRACKS: equ (65536/SECTORS/CPMSECS); -; -;SPT: equ (SECTORS*CPMSECS) -;BLS: equ 8192 -;BLM: equ (BLS/128-1) -; #if (BLS == 1024) -;BSH equ 3 -; #endif -; #if (BLS == 2048) -;BSH equ 4 -; #endif -; #if (BLS == 4096) -;BSH equ 5 -; #endif -; #if (BLS == 8192) -;BSH equ 6 -; #endif -; #if (BLS == 16384) -;BSH equ 7 -; #endif -;OFF: equ 1 -;DSM: equ (((TRACKS-OFF)*SECSZ*SECTORS/BLS)-1) -; #if (DSM < 256) -;EXM equ (BLS/1024-1) -; #else -;EXM equ (BLS/2048-1) -; #endif -;DRM: equ (1024-1);is this a good value? -; -;fldpb: .dw SPT ;CP/M records per track -; .db BSH ;allocation block shift -; .db BLM ;allocation block mask -; .db 0 ;extent mask -; .dw DSM ;max allocation block # -; .dw 255 ;max directory entry # -; .db 0f0h,0 ;directory allocation mask -; .dw 64 ;directory check alloc size -; .dw OFF ;number of reserved tracks - -;IdeDPB: dw SECTORS ;sectors per track -; db BSH -; db BLM -; db EXM -; dw DSM -; dw DRM -; db AL0 -; db AL1 -; dw CKS -; dw OFF - - -;dphbase0: .dw trans ;LOGICAL TO PHYSICAL XLATE TAB -; .dw 0 ;SCRATCH -; .dw 0 -; .dw 0 -; .dw DIRBUF ;DIRECTORY BUFFER -; .dw fldpb ;DISK PARAMETER BLOCK -; .dw chk00 ;CHECKSUM VECTOR -; .dw ALV0 ;ALLOCATION VECTOR -; -;dphbase1: .dw trans -; .dw 0 -; .dw 0 -; .dw 0 -; .dw DIRBUF -; .dw fldpb -; .dw chk01 -; .dw ALV1 -; -;******************************************************** -; Sector translation table. The IDE drive does not do -; translation but left it here for future use. Ie, it -; might be used later but could be removed for now. -; -trans: .db 0,1,2,3,4,5,6,7 - .db 8,9,10,11,12,13,14,15 - .db 16,17,18,19,20,21,22,23 - .db 24,25,26,27,28,29,30,31 -; -;******************************************************** -; CP/M DPB -; -; AGAIN, OLD CODE WARNING!!!! Some of this was carry-over -; from my previous attempt to read BoGUS format disks. -; BoGUS was a CP/M box made by Franklin Computer in 1984. -; There are about 3 in existance today. -; -; BoGUS = Bob Grieb's Underground System -; -; This has always been one of the most confusing bits of -; CP/M legacy. To make things a tad easier, here are some -; bits of data that will make reading section 6.10 of the -; "CP/M Operating System Manual" a bit clearer. -; -; The CF drive I'm using (Sandisk SDCFB-192) has the -; following raw parameters. Hex numbers first, decimal -; in parens: -; -; Cylinders: 02DE (734) -; Heads: 10 (16) -; Sectors: 20 (32) -; Sector size: (512) -; -; Total disk size = 734*16*32*512 = 192,413,696 bytes -; -; SPT = 128 Sectors per track -; BLS = -; 1 Reserved track - -; -; BLS = 2048 (why, I don't know) -; 9 physical sectors per track, 4 CP/M sectors each -; DOuble sided -; 2 reserved tracks -; -;TRACKS: .equ (80 * 2);total tracks (count both sides) -;SECTORS: .equ 9 ;sectors per track -;SECSZ: .equ 512 ;bytes per sector -;CPMSECS: .equ (SECSZ/128) ;CP/M records per phys sector -; -;SPT: .equ (SECTORS*CPMSECS) -;BLS: .equ 2048 ;ask Dave ask to why -;BSH: .equ 4 -;BLM: .equ ((BLS/128)-1) -;OFF: .equ 2 -;DSM: .equ (((TRACKS-OFF)*SECSZ*SECTORS/BLS)-1) -; -;fldpb: .dw SPT ;CP/M records per track -; .db BSH ;allocation block shift -; .db BLM ;allocation block mask -; .db 0 ;extent mask -; .dw DSM ;max allocation block # -; .dw 255 ;max directory entry # -; .db 0f0h,0 ;directory allocation mask -; .dw 64 ;directory check alloc size -; .dw OFF ;number of reserved tracks - - - - - -;******************************************************** -; SET TRACK FOR FUTURE READS OR WRITES TO TRACK 0. ALSO -; PARTIALLY RESET THE DISK SYSTEM TO ALLOW FOR CHANGED -; DISKS. -;******************************************************** - -HOME: call msg - .text "HOME" - db CR,LF,0 - - ld a,(MustWriteBuffer) ;unwritten data? - or a - jp nz,HomeNoWrite - ld (DataInDiskBuffer),a -HomeNoWrite: ld c,0 ;set to track 0 - jp SETTRK - - -;******************************************************** -; SET TRACK FOR FUTURE READS OR WRITES TO THAT PASSED -; IN REGISTER PAIR BC. -;******************************************************** - -SETTRK: ld l,c - ld h,b - ld (SelectedTrack),hl - -; call msg -; db "SETTRK: ",0 -; ld a,h -; call a_hex -; ld a,l -; call a_hex -; call crlf - - ret - -;******************************************************** -; SET SECTOR FOR FUTURE READS OR WRITES TO THAT PASSED -; IN REGISTER PAIR BC. -;******************************************************** - -SETSEC: ld a,c - ld (SelectedSector),a - -; push af -; call msg -; db "SETSEC: ",0 -; pop af -; call a_hex -; call crlf - ret - -;******************************************************** -; SET DMA ADDRESS FOR FUTURE READS OR WRITES TO THAT -; PASSED IN REGISTER PAIR BC. -;******************************************************** - -SETDMA: ld l,c - ld h,b - ld (DMAAddress),hl - -#IF 0 ;debug code - push hl ;DEBUG - call msg - db "SETDMA: ",0 - pop hl - push hl - ld a,h - call a_hex - ld a,l - call a_hex - call crlf - pop hl ;END DEBUG -#ENDIF - - ret - -;******************************************************** -; SECTOR TRANSLATION ROUTINE. THE ROUTINE ONLY -; TRANSLATES SECTORS ON THE USER TRACKS, SINCE CP/M -; ACCESSES THE SYSTEM TRACKS WITHOUT CALLING FOR -; TRANSLATION. -; BC contains the sector number to translate, and the -; translation table address is in DE. Returns result -; in HL. -;******************************************************** - -SECTRA: ld l,c ;no translation - ld h,b - ret - -;******************************************************** -; The main events... read and write routines! They share -; a lot of common code, so each of these is pretty small, -; falls into common area, then eventually splits again. -;******************************************************** - -READ: -; Read in the 128-byte CP/M sector specified by previous calls -; to select disk and to set track and sector. The sector will be read -; into the address specified in the previous call to set DMA address. -; -; If reading from a disk drive using sectors larger than 128 bytes, -; deblocking code will be used to "unpack" a 128-byte sector from -; the physical sector. - -; call msg -; db "READ",CR,LF,0 - ld a,(DeblockingRequired) ;Check if deblocking needed - or a ;(flag was set in SELDSK call) - jp z,ReadNoDeblock ;No, use normal nondeblocked - -; The deblocking algorithm used is such -; that a read operation can be viewed -; up until the actual data transfer as -; though it was the first write to an -; unallocated allocation block. - - xor a ;Set the record count to 0 - ld (UnallocatedRecordCount),a ; for first "write" - inc a ;Indicate that it is really a read - ld (ReadOperation),a ;that is to be performed - ld (MustPrereadSector),a ;and force a preread of the sector - ;to get it into the disk buffer - ld a,WriteUnallocated ;Fake deblocking code into responding - ld (WriteType),a ;as if this is the first write to an - ;unallocated allocation block. - jp PerformReadWrite ;Use common code to execute read - - - -WRITE: -; -; Write a 128-byte sector from the current DMA address to -; the previously selected disk, track, and sector. -; -; On arrival here, the BDOS will have set register C to indicate -; whether this write operation is to an already allocated allocation -; block (which means a preread of the sector may be needed), -; to the directory (in which case the data will be written to the -; disk immediately), or to the first 128-byte sector of a previously -; unallocated allocation block (in which case no preread is required). -; -; Only writes to the directory take place immediately. In all other -; cases, the data will be moved from the DMA address into the disk -; buffer, and only written out when circumstances force the -; transfer. The number of physical disk operations can therefore -; be reduced considerably. -; - - ld a,(DeblockingRequired) ;Check if deblocking is required - or a ;(flag set in SELDSK call) - jp z,WriteNoDeblock - - xor a ;Indicate that a write operation - ld (ReadOperation),a ; is required (i.e. NOT a read) - ld a,c ;Save the BDOS write type - ld (WriteType),a - cp WriteUnallocated ;Check if the first write to an - ; unallocated allocation block - jp nz,CheckUnallocatedBlock ;No, check if in the middle of - ; writing to an unallocated block - ;Yes, first write to unallocated - ; allocation block -- initialize - ; variables associated with - ; unallocated writes. - ld a,AllocationBlockSize/128 ;Get number of 128-byte - ; sectors and - ld (UnallocatedRecordCount),a ; set up a count. - ; - ld hl,SelectedDkTrkSec ;Copy disk, track and sector - ld de,UnallocatedDkTrkSec ; into unallocated variables - call MoveDkTrkSec - -; -; Check if this is not the first write to an unallocated -; allocation block -- if it is, the unallocated record count -; has just been set to the number of 128-byte sectors in the -; allocation block. -; -CheckUnallocatedBlock: - ld a,(UnallocatedRecordCount) - or a - jp z,RequestPreread ;No, this is a write to an - ; allocated block - ;Yes, this is a write to an - ; unallocated block - dec a ;Count down on number of 128-byte sectors - ; left unwritten to in allocation block - ld a,(UnallocatedRecordCount) ; and store back new value. - - ld hl,SelectedDkTrkSec ;Check if the selected disk, track, - ld de,UnallocatedDkTrkSec ; and sector are the same as for - call CompareDkTrkSec ; those in the unallocated block. - jp nz,RequestPreread ;No, a preread is required - ;Yes, no preread is needed. - ;Now is a convenient time to - ; update the current sector and see - ; if the track also needs updating. -; - ;By design, Compare$Dk$Trk$Sec - ; returns with - ; DE -> Unallocated$Sector - ex de,hl ; HL -> Unallocated$Sector - inc (hl) ;Update Unallocated$Sector - ld a,(hl) ;Check if sector now > maximum - cp CPMSecPerTrack ; on a track - jp c,NoTrackChange ;No (A < (HL) ) - ;Yes, - ld (hl),0 ;Reset sector to 0 - ld hl,(UnallocatedTrack) ;Increase track by 1 - inc hl - ld (UnallocatedTrack),hl -; -NoTrackChange: - ;Indicate to later code that - ; no preread is needed. - xor a - ld (MustPrereadSector),a ;Must$Preread$Sector=0 - jp PerformReadWrite - -RequestPreread: - xor a ;Indicate that this is not a write - ld (UnallocatedRecordCount),a ; into an unallocated block. - inc a - ld (MustPrereadSector),a ;Indicate that a preread of the - ; physical sector is required. -; -; -PerformReadWrite: ;Common code to execute both reads and - ; writes of 128-byte sectors. - xor a ;Assume that no disk errors will - ld (DiskErrorFlag),a ; occur - - ld a,(SelectedSector) ;Convert selected 128-byte sector - rra ; into physical sector by dividing by 4 - rra - and 3fh ;Remove any unwanted bits - ld (SelectedPhysicalSector),a - ; - ld hl,DataInDiskBuffer ;Check if disk buffer already has - ld a,(hl) ; data in it. - ld (hl),1 ;(Unconditionally indicate that - ; the buffer now has data in it) - or a ;Did it indeed have data in it? - jp z,ReadSectorIntoBuffer ;No, proceed to read a physical - ; sector into the buffer. - ; - ;The buffer does have a physical sector - ; in it. - ; Note: The disk, track, and PHYSICAL - ; sector in the buffer need to be - ; checked, hence the use of the - ; Compare$Dk$Trk subroutine. - ; - ld de,InBufferDkTrkSec ;Check if sector in buffer is the - ld hl,SelectedDkTrkSec ; same as that selected earlier - call CompareDkTrk ;Compare ONLY disk and track - jp nz,SectorNotInBuffer ;No, it must be read in - - ld a,(InBufferSector) ;Get physical sector in buffer - ld hl,SelectedPhysicalSector - cp (hl) ;Check if correct physical sector - jp z,SectorInBuffer ;Yes, it is already in memory -SectorNotInBuffer: - ;No, it will have to be read in - ; over current contents of buffer - ld a,(MustWriteBuffer) ;Check if buffer has data in that - or a ; must be written out first - call nz,WritePhysical ;Yes, write it out -; -ReadSectorIntoBuffer: - call SetInBufferDkTrkSec ;Set in buffer variables from - ; selected disk, track, and sector - ; to reflect which sector is in the - ; buffer now. - ld a,(MustPrereadSector) ;In practice, the sector need only - or a ; be physically read in if a preread - ; is required - call nz,ReadPhysical ;Yes, preread the sector - xor a ;Reset the flag to reflect buffer - ld (MustWriteBuffer),a ; contents. -; -SectorInBuffer: ;Selected sector on correct track and - ; disk is already in the buffer. - ;Convert the selected CP/M (128-byte) - ; sector into a relative address down - ; the buffer. - ld a,(SelectedSector) ;Get selected sector number - and SectorMask ;Mask off only the least significant bits - ld l,a ;Multiply by 128 by shifting 16-bit value - ld h,0 ; left 7 bits - add hl,hl ;* 2 - add hl,hl ;* 4 - add hl,hl ;* 8 - add hl,hl ;* 16 - add hl,hl ;* 32 - add hl,hl ;* 64 - add hl,hl ;* 128 -; - ld de,DiskBuffer ;Get base address of disk buffer - add hl,de ;Add on sector number * 128 - ;HL -> 128-byte sector number start - ; address in disk buffer - ex de,hl ;DE -> sector in disk buffer - ld hl,(DMAAddress) ;Get DMA address set in SETDMA call - ex de,hl ;Assume a read operation, so - ; DE -> DMA address - ; HL -> sector in disk buffer - ld c,128/8 ;Because of the faster method used - ; to move data in and out of the - ; disk buffer, (eight bytes moved per - ; loop iteration) the count need only - ; be 1/8th of normal. - ;At this point -- - ; C = loop count - ; DE -> DMA address - ; HL -> sector in disk buffer - ld a,(ReadOperation) ;Determine whether data is to be moved - or a ; out of the buffer (read) or into the - jp nz,BufferMove ; buffer (write) - ;Writing into buffer - ;(A must be 0 get here) - inc a ;Set flag to force a write - ld (MustWriteBuffer),a ; of the disk buffer later on. - ex de,hl ;Make DE -> sector in disk buffer - ; HL -> DMA address -; -; -BufferMove: ;The following move loop moves eight bytes - ; at a time from (HL) to (DE), C contains - ; the loop count. - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - ld a,(hl) ;Get byte from source - ld (de),a ;Put into destination - inc de ;Update pointers - inc hl - - dec c ;Count down on loop counter - jp nz,BufferMove ;Repeat until CP/M sector moved - ; - ld a,(WriteType) ;If write to directory, write out - cp WriteDirectory ; buffer immediately - ld a,(DiskErrorFlag) ;Get error flag in case delayed write or read - ret nz ;Return if delayed write or read - ; - or a ;Check if any disk errors have occured - ret nz ;Yes, abandon attempt to write to directory - ; - xor a ;Clear flag that indicates buffer must be - ld (MustWriteBuffer),a ; written out - call WritePhysical ;Write buffer out to physical sector - ld a,(DiskErrorFlag) ;Return error flag to caller - ret -; -; -SetInBufferDkTrkSec: ;Indicate selected disk, track, and - ; sector now residing in buffer - ld a,(SelectedDisk) - ld (InBufferDisk),a - - ld hl,(SelectedTrack) - ld (InBufferTrack),hl - - ld a,(SelectedPhysicalSector) - ld (InBufferSector),a - - ret -; -CompareDkTrk: ;Compares just the disk and track - ; pointed to by DE and HL - ld c,3 ;Disk (1), track (2) - jp CompareDkTrkSecLoop ;Use common code - -CompareDkTrkSec: ;Compares the disk, track, and sector - ; variables pointed to by DE and HL - ld c,4 ;Disk (1), track (2), and sector (1) -CompareDkTrkSecLoop: - ld a,(de) ;Get comparitor - cp (hl) ;Compare with comparand - ret nz ;Abandon comparison if inequality found - inc de ;Update comparitor pointer - inc hl ;Update comparand pointer - dec c ;Count down on loop count - ret z ;Return (with zero flag set) - jp CompareDkTrkSecLoop -; -; Moves the disk, track and sector -; variables pointed at by HL to -; those pointed at by DE -; -MoveDkTrkSec: ld c,4 ;Disk (1), track (2), and sector (1) -MoveDkTrkSecLoop: - ld a,(hl) ;Get source byte - ld (de),a ;Store in destination - inc de ;Update pointers - inc hl - dec c ;Count down on byte count - ret z ;Return if all bytes moved - jp MoveDkTrkSecLoop - - - - - -; -; Should not get here with the IDE! -; - -ReadNoDeblock: - call msg - db "ERROR - ReadNoDeblock",CR,LF,0 - ret - -WriteNoDeblock: - call msg - db "ERROR - WriteNoDeblock",CR,LF,0 - ret - - - -; -; Here's the big high-level view of the logic here. It's -; rather involved since a lot of decisions needs to be made. -; -; First, the variables: -; -; DRIVE = This is the drive the user has selected. It may not -; be the same drive currently in use. -; -; TRACK = This is the track the user wants to use, 0-79. It -; may not be the current track we're on. -; -; SECTOR = The CP/M logic sector the user wants to use. 0 - 35. -; Again, this might not be the same as the current one. -; -; CURDRV = This is the currently selected drive OR NODRIVE if -; none selected yet. If NODRIVE that implies this is -; the first disk access. -; -; CURTRK = Track where the current drive has its head located. -; NOTRACK implies the location is unknown. -; -; CURSEC = Current physical sector with the side bit (bit 0) still -; included. -; - -; So here's the drive select logic... -; -; if (DRIVE != CURDRV) - a new drive is being selected -; if (CURDRV != NODRIVE) - if a valid drive is already selected -; Save the current track into the drive data area. -; Load the new drive's data from the drive data area. -; if (CURTRK == NOTRACK) - first time for this disk -; Home disk -; set CURTRK to 0 -; else -; save track to FDC -; else -; Home disk -; set CURTRK to 0 -; -; ...followed by the track select logic... -; -; if (TRACK != CURTRK) -; seek to TRACK -; set CURTRK to TRACK -; -; ...and then compute physical sector and side... -; -; divide sector by 4 for temp sector -; if bit 0 is set then select side 0, else select side 1 -; divide the temp sector by 2. This is now CURSEC. -; load CURSEC into the sector register -; -; Perform read or write operation -; - - - - - -; -;******************************************************** -; Initilze the 8255 and drive then do a hard reset on the drive, -; -IDEinit: ld a,READcfg8255 ;10010010b - OUT (IDEportCtrl),a ;Config 8255 chip, READ mode - - ld a,IDErstline - OUT (IDEportC),a ;Hard reset the disk drive - - ld B,020H ;<<<<< fine tune later -ResetDelay: DJNZ ResetDelay ;Delay (reset pulse width) - xor a - out (IDEportC),a ;No IDE control lines asserted - - ld D,11100000b ;Data for IDE SDH reg (512bytes, LBA mode,single drive,head 0000) - ;For Trk,Sec,head (non LBA) use 10100000 - ;Note. Cannot get LBA mode to work with an old Seagate Medalist 6531 drive. - ;have to use teh non-LBA mode. (Common for old hard disks). - - ld E,REGshd ;00001110,(0EH) for CS0,A2,A1, - CALL IDEwr8D ;Write byte to select the MASTER device -; - ld B,0FFH ;<<< May need to adjust delay time -WaitInit: ld E,REGstatus ;Get status after initilization - CALL IDErd8D ;Check Status (info in [D]) - BIT 7,D - jp z,DoneInit ;Return if ready bit is zero - ld A,2 - CALL DELAYX ;Long delay, drive has to get up to speed - DJNZ WaitInit - CALL SHOWerrors ;Ret with NZ flag set if error (probably no drive) - RET -DoneInit: xor A - RET -; -DELAYX: ld (DELAYStore),a - PUSH BC - ld bc,0FFFFH ;<<< May need to adjust delay time to allow cold drive to -DELAY2: LD a,(DELAYStore) ; get up to speed. -DELAY1: dec a - jp nz,DELAY1 - dec bc - ld A,C - or b - jp nz,DELAY2 - POP BC - RET -; -;******************************************************** -; Read a sector, specified by the 4 bytes in LBA -; Z on success, NZ call error routine if problem -; -ReadPhysical: ld hl,DiskBuffer - ld a,042h - ld b,0 -rpfill ld (hl),a - inc hl - ld (hl),a - inc hl - djnz rpfill - - call msg - db "ReadPhysical",CR,LF,0 - - CALL wrlba ;Tell which sector we want to read from. - ;Note: Translate first in case of an error otherewise we - ;will get stuck on bad sector - CALL IDEwaitnotbusy ;make sure drive is ready - jp c,SHOWerrors ;Returned with NZ set if error - - ld D,COMMANDread - ld E,REGcommand - CALL IDEwr8D ;Send sec read command to drive. - CALL IDEwaitdrq ;wait until it's got the data - jp c,SHOWerrors -; - ld hl,DiskBuffer ;DMA address - ld B,0 ;Read 512 bytes to [HL] (256X2 bytes) -MoreRD16: ld A,REGdata ;REG regsiter address - OUT (IDEportC),a - - OR IDErdline ;08H+40H, Pulse RD line - OUT (IDEportC),a - - IN a,(IDEportA) ;Read the lower byte first (Note early versions had high byte then low byte - ld (hl),a ;this made sector data incompatable with other controllers). - inc hl - IN a,(IDEportB) ;THEN read the upper byte - ld (hl),A - inc hl - - ld A,REGdata ;Deassert RD line - OUT (IDEportC),a - DJNZ MoreRD16 - - ld E,REGstatus - CALL IDErd8D - ld A,D - BIT 0,A - call nz,SHOWerrors ;If error display status - RET -; -;******************************************************** -;Write a sector, specified by the 3 bytes in LBA (@ IX+0)", -;Z on success, NZ to error routine if problem -; -WritePhysical: -; call msg -; db "WritePhysical",CR,LF,0 - - CALL wrlba ;Tell which sector we want to read from. - ;Note: Translate first in case of an error otherewise we - ;will get stuck on bad sector - CALL IDEwaitnotbusy ;make sure drive is ready - jp c,SHOWerrors - - ld D,COMMANDwrite - ld E,REGcommand - CALL IDEwr8D ;tell drive to write a sector - CALL IDEwaitdrq ;wait unit it wants the data - jp c,SHOWerrors -; - ld hl,DiskBuffer - ld B,0 ;256X2 bytes - - ld A,WRITEcfg8255 - OUT (IDEportCtrl),a -WRSEC1: ld A,(hl) - inc hl - OUT (IDEportA),a ;Write the lower byte first (Note early versions had high byte then low byte - ld A,(hl) ;this made sector data incompatable with other controllers). - inc hl - OUT (IDEportB),a ;THEN High byte on B - ld A,REGdata - PUSH af - OUT (IDEportC),a ;Send write command - OR IDEwrline ;Send WR pulse - OUT (IDEportC),a - POP af - OUT (IDEportC),a - DJNZ WRSEC1 - - ld A,READcfg8255 ;Set 8255 back to read mode - OUT (IDEportCtrl),a - - ld E,REGstatus - CALL IDErd8D - ld A,D - BIT 0,A - call nz,SHOWerrors ;If error display status - RET -; -;******************************************************** -; Write the logical block address to the drive's registers -; Note we do not need to set the upper nibble of the LBA -; It will always be 0 for these small drives. Use the -; physical sector number which has already been divided -; down from the logical sector number. -; -wrlba: ld hl,(SelectedPhysicalSector) - ld a,l - inc a ;Sectors are numbered 1 to MAXSEC - ld (DRIVESEC),a ;For Diagnostic Display Only - ld D,A - ld E,REGsector ;Send info to drive - call IDEwr8D - ;Note: For drive we will have 0 - MAXSEC sectors only -; ld hl,TRK - ld hl,(SelectedTrack) - ld A,L - ld (DRIVETRK),a - ld D,L ;Send Low TRK# - ld E,REGcylinderLSB - call IDEwr8D - - ld A,H - ld (DRIVETRK+1),a - ld D,H ;Send High TRK# - ld E,REGcylinderMSB - call IDEwr8D - - ld D,1 ;For now, one sector at a time - ld E,REGseccnt - call IDEwr8D - -;DEBUG - call msg - .text "wrlba - Track " - .db 0 - ld a,(DRIVETRK+1) - call a_hex - ld a,(DRIVETRK) - call a_hex - call msg - .db ", Sector ",0 - ld a,(DRIVESEC) - call a_hex - call msg - .db CR,LF,0 -;END DEBUG - RET -; -;******************************************************** -;ie Drive READY if 01000000 -; -IDEwaitnotbusy: ld B,0FFH - ld A,0FFH ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives - ld (DELAYStore),a - -MoreWait: ld E,REGstatus ;wait for RDY bit to be set - CALL IDErd8D - ld A,D - and 11000000B - xor 01000000B - jp z,DoneNotBusy - DJNZ MoreWait - ld a,(DELAYStore) ;Check timeout delay - dec A - ld (DELAYStore),a - jp nz,MoreWait - scf ;Set carry to indicqate an error - ret -DoneNotBusy: or A ;Clear carry it indicate no error - RET -; -;Wait for the drive to be ready to transfer data. -;Returns the drive's status in Acc -; -IDEwaitdrq: ld B,0FFH - ld A,0FFH ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives - ld (DELAYStore),a - -MoreDRQ: ld E,REGstatus ;wait for DRQ bit to be set - CALL IDErd8D - ld A,D - and 10001000B - cp 00001000B - jp z,DoneDRQ - DJNZ MoreDRQ - ld a,(DELAYStore) ;Check timeout delay - dec A - ld (DELAYStore),a - jp nz,MoreDRQ - scf ;Set carry to indicate error - RET -DoneDRQ: OR A ;Clear carry - RET -; -;******************************************************** -; Low Level 8 bit R/W to the drive controller. These are -; the routines that talk directly to the drive controller -; registers, via the 8255 chip. Note the 16 bit I/O to -; the drive (which is only for SEC R/W) is done directly -; in the read/write functions for speed reasons. -; -; READ 8 bits from IDE register in [E], return info in [D] -; -IDErd8D: ld A,E - OUT (IDEportC),a ;drive address onto control lines - - OR IDErdline ;RD pulse pin (40H) - OUT (IDEportC),a ;assert read pin - - IN a,(IDEportA) - ld D,A ;return with data in [D] - - xor A - OUT (IDEportC),a ;Zero all port C lines - ret -; -; WRITE Data in [D] to IDE register in [E] -; -IDEwr8D: ld A,WRITEcfg8255 ;Set 8255 to write mode - OUT (IDEportCtrl),a - - ld A,D ;Get data put it in 8255 A port - OUT (IDEportA),a - - ld A,E ;select IDE register - OUT (IDEportC),a - - OR IDEwrline ;lower WR line - OUT (IDEportC),a - NOP - - xor A ;Deselect all lines including WR line - OUT (IDEportC),a - - ld A,READcfg8255 ;Config 8255 chip, read mode on return - OUT (IDEportCtrl),a - RET - - -SHOWerrors: call msg - .TEXT "SHOWerrors called" - .db CR,LF,0 - - .page -;******************************************************** -; Input/Output devices. For now, just call the TTY -; functions, but later I'll add iobyte support. -; -CONST: jp ttystat -CONIN: jp ttyin -CONOUT: jp ttyout -; -;******************************************************** -; Message output subroutines. msghl will print the null- -; terminated message pointed to by HL. msg will -; print the null terminated string immediately following -; the "call MSG" line. -; -msg: ex (sp),hl - call msghl - ex (sp),hl - ret -; -msghl: ld a,(hl) - or a - ret z - ld c,a - call CONOUT - inc hl - jr msghl -; -;******************************************************** -; Display the contents of A as two hex digits -; -a_hex: push af - rrca - rrca - rrca - rrca - call ahex2 - pop af -ahex2: and 0fh - add a,90h - daa - adc a,40h - daa - ld c,a - jr ttyout -; -;******************************************************** -; Do a CR/LF -; -crlf: ld c,CR - call ttyout - ld c,LF - jr ttyout - .page -; -;******************************************************** -; Other I/O devices. Make them all do nothing for now. -; -LIST: jp ttyout -PUNCH: ret -READER: ld a,EOF - ret -LISTST: ld a,TRUE - ret - -#include "ccs2710.inc" - - - -; stuff from bios.mac - -InBufferDkTrkSec: ;Variables for physical sector - ; currently in Disk$Buffer in memory -InBufferDisk: db 0 ; These are moved and compared -InBufferTrack: dw 0 ; as a group, so do not alter -InBufferSector: db 0 ; these lines. -; -DataInDiskBuffer: db 0 ;When nonzero, the disk buffer has - ; data from the disk in it. -MustWriteBuffer: db 0 ;Nonzero when data has been - ; written into Disk$Buffer but - ; not yet written out to disk - -DMAAddress: dw 0 - -WriteType db 0 - - ;These are the values handed over by the BDOS - ; when it calls the WRITE operation. - ;The allocated/unallocated indicates whether the - ; BDOS is set to write to an unallocated allocation - ; block (it only indicates this for the first - ; 128-byte sector write) or to an allocation block - ; that has already been allocated to a file. - ;The BDOS also indicates if it is set to write to - ; the file directory. - ; -WriteAllocated equ 0 -WriteDirectory equ 1 -WriteUnallocated equ 2 - -; -;Variables for selected disk, track, and sector -; (Selected by SELDSK, SETTRK,n and SETSEC) -; -; Note that these are in a specific order, so do not change -; the size nor order without checking where other pieces of -; code are affected! -; -SelectedDkTrkSec: -SelectedDisk: db 0 ; These are moved and -SelectedTrack: dw 0 ; compared as a group so -SelectedSector: db 0 ; do not alter order. -SelectedPhysicalSector: db 0 ;Selected physical sector derived - ; from selected (CP/M) sector by - ; shifting it right the number of - ; bits specified by - ; Sector$Bit$Shift -; -SelectedDiskType: db 0 ;Set by SELDSK to indicate either - ; 8" or 5 1/4" floppy -SelectedDiskDeblock: db 0 ;Set by SELDSK to indicate whether - ; deblocking is required. - -UnallocatedDkTrkSec: ;Parameters for writing to a previously - ; unallocated allocation block. -UnallocatedDisk: db 0 ; These are moved and compared -UnallocatedTrack: dw 0 ; as a group so do not alter -UnallocatedSector: db 0 ; these lines. - -UnallocatedRecordCount: db 0 ;Number of unallocated "records" - ; in current previously unallocated - ; allocation block. - -DiskErrorFlag: db 0 ;Nonzero to indicate an error - ; that could not be recovered - ; by the disk drivers. BDOS will - ; output a "bad sector" message. - -; -;Flags used inside the deblocking code - -MustPrereadSector: db 0 ;Nonzero if a physical sector must - ; be read into the disk buffer - ; either before a write to an - ; allocated block can occur, or - ; for a normal CP/M 128-byte - ; sector read -ReadOperation: db 0 ;Nonzero when a CP/M 128-byte - ; sector is to be read -DeblockingRequired: db 0 ;Nonzero when the selected disk - ; needs deblocking (set in SELDSK) -DiskType: db 0 ;Indicates 8" or 5 1/4" floppy - ; selected (set in SELDSK). - - -; -; This is the actual sector size -; for the 5 1/4" mini-floppy diskettes. -; The 8" diskettes use 128-byte sectors. -; Declare the physical disk buffer for the -; 5 1/4" diskettes -; -; This is the low level buffer used to hold a sector of data. -; -PhysicalSectorSize equ 512 -DiskBuffer: ds PhysicalSectorSize -; -; Data written to, or read from, the mini-floppy drive is transferred -; via a physical buffer that is actually 512 bytes long (it was -; declared at the front of the BIOS and holds the "one-time" -; initialization code used for the cold boot procedure). -; -; The blocking/deblocking code attempts to minimize the amount -; of actual disk I/O by storing the disk, track, and physical sector -; currently residing in the Physical Buffer. If a read request is for -; a 128-byte CP/M "sector" that already is in the physical buffer, -; then no disk access occurs. -; -; -AllocationBlockSize equ 2048 -PhysicalSecPerTrack equ 18 -CPMSecPerPhysical equ PhysicalSectorSize/128 -CPMSecPerTrack equ CPMSecPerPhysical*PhysicalSecPerTrack -SectorMask equ CPMSecPerPhysical-1 -SectorBitShift equ 2 ;LOG2(CPM$Sec$Per$Physical) - - - -; stuff from MYIDE - -DELAYStore: DS 1 -DRIVESEC: db 0 -DRIVETRK: dw 0 - -; -; This MUST BE the last label! -; -BIOS_END .equ * - - .end diff --git a/branches/s100/Applegate/ccs2710.inc b/branches/s100/Applegate/ccs2710.inc deleted file mode 100644 index 553ee3cb..00000000 --- a/branches/s100/Applegate/ccs2710.inc +++ /dev/null @@ -1,77 +0,0 @@ - .page -;******************************************************** -; These are I/O functions for the CCS 2710 four-port -; serial I/O board. -; -; Bob Applegate, 02/16/2008 -; -SIObase .equ 0E0H -; -SIODATA .equ SIObase -SIOBAUDL .equ SIObase ;also used for baud rate -SIOINTEN .equ SIObase+1 -SIOBAUDH .equ SIObase+1 ;ditto -SIOIDENT .equ SIObase+2 -SIOLCTRL .equ SIObase+3 -SIOMDMCT .equ SIObase+4 -SIOLSTAT .equ SIObase+5 -SIOMDMST .equ SIObase+6 -BAUD03 .equ 0180H ;divisor for 300 baud -BAUD12 .equ 060H ;1200 baud -BAUD_2400 .equ 030h ;2400 baud -BAUD96 .equ 00CH ;9600 baud -DATRDY .equ 01H ;rec'd data ready -TXMTY .equ 20H ;transmitter holding reg empty -HSMSK .equ 20H - -BAUD_RATE .equ BAUD_2400 - -; -; This function initializes the main console port for the -; default baud rate. -; -initser: ld a,0fH - out (SIOMDMCT),a - ld a,083H ;enable divisor latch access - out (SIOLCTRL),a - ld a,BAUD_RATE / 256 ;get hi byte - out (SIOBAUDH),a - ld a,BAUD_RATE % 256 ;get low byte - out (SIOBAUDL),a - ld a,03H ;8 data bits, one stop bit, no parity - out (SIOLCTRL),a - xor a ;clear acc - out (SIOINTEN),a ;disable ints - out (SIOLSTAT),a ;clear status - in a,(SIODATA) ;clear out any garbage in rec'd data reg - ret -; -; TTY output of character in C. Modifies A. -; -ttyout: IN A,(SIOLSTAT) ;was A,TTS, read status port - AND TXMTY ;check buffer empty bit - JR Z,ttyout ;branch if not empty - LD A,C - OUT (SIODATA),A ;was TTO,A, send out character - RET ;thassit -; -; Check to see if a character is ready to be read from the TTY. -; Returns TRUE (0ffh) in A is there is a character waiting, or -; FALSE (0) if there is nothing. -; -ttystat: IN A,(SIOLSTAT) ;was A,TTS - AND DATRDY - LD A,TRUE ;was FALSE - RET NZ - CPL - RET -; -; This gets the next character from the TTY and returns it in A. -; This will block if there is nothing waiting. -; -ttyin: IN A,(SIOLSTAT) ;read status reg - AND DATRDY ;look for data ready - JR Z,ttyin ;wait for char - IN a,(SIODATA) ;read character - RET - .page diff --git a/branches/s100/Applegate/convert.py b/branches/s100/Applegate/convert.py deleted file mode 100755 index 3b53fa25..00000000 --- a/branches/s100/Applegate/convert.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/python -# Written by Douglas Goodall 17:25 Wed, Jan 30, 2013 -# load cpm.bin and bios.bin then jump - -import sys -import os -import serial - -# passing in a string either "12" or "0x12" -# return value is string of hex digits only (no 0x) -def safebyte(parm): - xyz = parm - myord = ord(xyz) - hexdata = hex(myord) - newstr = hexdata - if (hexdata[0] == '0'): - if(hexdata[1] == 'x'): - newstr = hexdata[2] - if(len(hexdata)>3): - newstr = newstr + hexdata[3] - return newstr - -# passing in a string either "1234" of "0x1234" -# return value is string of hex digits only (1234) (no 0x) -def safeword(parm): - xyz = parm - myint = int(xyz) - hexdata = hex(myint) - newstr = hexdata - if (hexdata[0] == '0'): - if(hexdata[1] == 'x'): - newstr = hexdata[2] - if(len(hexdata)>3): - newstr = newstr + hexdata[3] - if(len(hexdata)>4): - newstr = newstr + hexdata[4] - if(len(hexdata)>5): - newstr = newstr + hexdata[5] - return newstr - -def loadngo(filename): - statinfo = os.stat(filename) - filelen = statinfo.st_size - infile = open(filename,'rb') - filedata = infile.read() - infile.close() - outfile = open("cpm.trans","w") - -# ser = serial.Serial('/dev/cu.PL2303-0000201D', 19200, timeout=10) -# ser.write("\n\n") - outfile.write("sa400\n") -# print ser.read(12); - for x in range(1,filelen): - outfile.write(safebyte(filedata[x-1])) - outfile.write(" ") - outfile.write("\n") - outfile.close() -# print ser.read(12) -# ser.close() - -print "*******************************************************************" -print "loadcpm.py 1/30/2013 dwg - load&go S-100 CP/M using master-yoda ROM" -print "*******************************************************************" -#loadngo("cpm.bin") -ser = serial.Serial('/dev/cu.PL2303-0000201D', 19200, timeout=1) -ser.read(128) -ser.read(128) -ser.write("\n") -ser.close() -loadngo("cpm.bin") - diff --git a/branches/s100/Applegate/cpm.trans b/branches/s100/Applegate/cpm.trans deleted file mode 100644 index b6335325..00000000 --- a/branches/s100/Applegate/cpm.trans +++ /dev/null @@ -1,2 +0,0 @@ -sa400 -c3 5c a7 c3 58 a7 7f 0 43 6f 70 79 72 69 67 68 74 20 31 39 37 39 20 28 63 29 20 62 79 20 44 69 67 69 74 61 6c 20 52 65 73 65 61 72 63 68 20 20 20 20 20 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 a4 0 0 5f e 2 c3 5 0 c5 cd 8c a4 c1 c9 3e d cd 92 a4 3e a c3 92 a4 3e 20 c3 92 a4 c5 cd 98 a4 e1 7e b7 c8 23 e5 cd 8c a4 e1 c3 ac a4 e d c3 5 0 5f e e c3 5 0 cd 5 0 32 ee ab 3c c9 e f c3 c3 a4 af 32 ed ab 11 cd ab c3 cb a4 e 10 c3 c3 a4 e 11 c3 c3 a4 e 12 c3 c3 a4 11 cd ab c3 df a4 e 13 c3 5 0 cd 5 0 b7 c9 e 14 c3 f4 a4 11 cd ab c3 f9 a4 e 15 c3 f4 a4 e 16 c3 c3 a4 e 17 c3 5 0 1e ff e 20 c3 5 0 cd 13 a5 87 87 87 87 21 ef ab b6 32 4 0 c9 3a ef ab 32 4 0 c9 fe 61 d8 fe 7b d0 e6 5f c9 3a ab ab b7 ca 96 a5 3a ef ab b7 3e 0 c4 bd a4 11 ac ab cd cb a4 ca 96 a5 3a bb ab 3d 32 cc ab 11 ac ab cd f9 a4 c2 96 a5 11 7 a4 21 80 0 6 80 cd 42 a8 21 ba ab 36 0 23 35 11 ac ab cd da a4 ca 96 a5 3a ef ab b7 c4 bd a4 21 8 a4 cd ac a4 cd c2 a5 ca a7 a5 cd dd a5 c3 82 a7 cd dd a5 cd 1a a5 e a 11 6 a4 cd 5 0 cd 29 a5 21 7 a4 46 23 78 b7 ca ba a5 7e cd 30 a5 77 5 c3 ab a5 77 21 8 a4 22 88 a4 c9 e b cd 5 0 b7 c8 e 1 cd 5 0 b7 c9 e 19 c3 5 0 11 80 0 e 1a c3 5 0 21 ab ab 7e b7 c8 36 0 af cd bd a4 11 ac ab cd ef a4 3a ef ab c3 bd a4 11 28 a7 21 0 ac 6 6 1a be c2 cf a7 13 23 5 c2 fd a5 c9 cd 98 a4 2a 8a a4 7e fe 20 ca 22 a6 b7 ca 22 a6 e5 cd 8c a4 e1 23 c3 f a6 3e 3f cd 8c a4 cd 98 a4 cd dd a5 c3 82 a7 1a b7 c8 fe 20 da 9 a6 c8 fe 3d c8 fe 5f c8 fe 2e c8 fe 3a c8 fe 3b c8 fe 3c c8 fe 3e c8 c9 1a b7 c8 fe 20 c0 13 c3 4f a6 85 6f d0 24 c9 3e 0 21 cd ab cd 59 a6 e5 e5 af 32 f0 ab 2a 88 a4 eb cd 4f a6 eb 22 8a a4 eb e1 1a b7 ca 89 a6 de 40 47 13 1a fe 3a ca 90 a6 1b 3a ef ab 77 c3 96 a6 78 32 f0 ab 70 13 6 8 cd 30 a6 ca b9 a6 23 fe 2a c2 a9 a6 36 3f c3 ab a6 77 13 5 c2 98 a6 cd 30 a6 ca c0 a6 13 c3 af a6 23 36 20 5 c2 b9 a6 6 3 fe 2e c2 e9 a6 13 cd 30 a6 ca e9 a6 23 fe 2a c2 d9 a6 36 3f c3 db a6 77 13 5 c2 c8 a6 cd 30 a6 ca f0 a6 13 c3 df a6 23 36 20 5 c2 e9 a6 6 3 23 36 0 5 c2 f2 a6 eb 22 88 a4 e1 1 b 0 23 7e fe 3f c2 9 a7 4 d c2 1 a7 78 b7 c9 44 49 52 20 45 52 41 20 54 59 50 45 53 41 56 45 52 45 4e 20 55 53 45 52 0 16 0 0 0 0 21 10 a7 e 0 79 fe 6 d0 11 ce ab 6 4 1a be c2 4f a7 13 23 5 c2 3c a7 1a fe 20 c2 54 a7 79 c9 23 5 c2 4f a7 c c3 33 a7 af 32 7 a4 31 ab ab c5 79 1f 1f 1f 1f e6 f 5f cd 15 a5 cd b8 a4 32 ab ab c1 79 e6 f 32 ef ab cd bd a4 3a 7 a4 b7 c2 98 a7 31 ab ab cd 98 a4 cd d0 a5 c6 41 cd 8c a4 3e 3e cd 8c a4 cd 39 a5 11 80 0 cd d8 a5 cd d0 a5 32 ef ab cd 5e a6 c4 9 a6 3a f0 ab b7 c2 a5 aa cd 2e a7 21 c1 a7 5f 16 0 19 19 7e 23 66 6f e9 77 a8 1f a9 5d a9 ad a9 10 aa 8e aa a5 aa 21 f3 76 22 0 a4 21 0 a4 e9 1 df a7 c3 a7 a4 52 65 61 64 20 65 72 72 6f 72 0 1 f0 a7 c3 a7 a4 4e 6f 20 66 69 6c 65 0 cd 5e a6 3a f0 ab b7 c2 9 a6 21 ce ab 1 b 0 7e fe 20 ca 33 a8 23 d6 30 fe a d2 9 a6 57 78 e6 e0 c2 9 a6 78 7 7 7 80 da 9 a6 80 da 9 a6 82 da 9 a6 47 d c2 8 a8 c9 7e fe 20 c2 9 a6 23 d c2 33 a8 78 c9 6 3 7e 12 23 13 5 c2 42 a8 c9 21 80 0 81 cd 59 a6 7e c9 af 32 cd ab 3a f0 ab b7 c8 3d 21 ef ab be c8 c3 bd a4 3a f0 ab b7 c8 3d 21 ef ab be c8 3a ef ab c3 bd a4 cd 5e a6 cd 54 a8 21 ce ab 7e fe 20 c2 8f a8 6 b 36 3f 23 5 c2 88 a8 1e 0 d5 cd e9 a4 cc ea a7 ca 1b a9 3a ee ab f f f e6 60 4f 3e a cd 4b a8 17 da f a9 d1 7b 1c d5 e6 3 f5 c2 cc a8 cd 98 a4 c5 cd d0 a5 c1 c6 41 cd 92 a4 3e 3a cd 92 a4 c3 d4 a8 cd a2 a4 3e 3a cd 92 a4 cd a2 a4 6 1 78 cd 4b a8 e6 7f fe 20 c2 f9 a8 f1 f5 fe 3 c2 f7 a8 3e 9 cd 4b a8 e6 7f fe 20 ca e a9 3e 20 cd 92 a4 4 78 fe c d2 e a9 fe 9 c2 d9 a8 cd a2 a4 c3 d9 a8 f1 cd c2 a5 c2 1b a9 cd e4 a4 c3 98 a8 d1 c3 86 ab cd 5e a6 fe b c2 42 a9 1 52 a9 cd a7 a4 cd 39 a5 21 7 a4 35 c2 82 a7 23 7e fe 59 c2 82 a7 23 22 88 a4 cd 54 a8 11 cd ab cd ef a4 3c cc ea a7 c3 86 ab 41 6c 6c 20 28 79 2f 6e 29 3f 0 cd 5e a6 c2 9 a6 cd 54 a8 cd d0 a4 ca a7 a9 cd 98 a4 21 f1 ab 36 ff 21 f1 ab 7e fe 80 da 87 a9 e5 cd fe a4 e1 c2 a0 a9 af 77 34 21 80 0 cd 59 a6 7e fe 1a ca 86 ab cd 8c a4 cd c2 a5 c2 86 ab c3 74 a9 3d ca 86 ab cd d9 a7 cd 66 a8 c3 9 a6 cd f8 a7 f5 cd 5e a6 c2 9 a6 cd 54 a8 11 cd ab d5 cd ef a4 d1 cd 9 a5 ca fb a9 af 32 ed ab f1 6f 26 0 29 11 0 1 7c b5 ca f1 a9 2b e5 21 80 0 19 e5 cd d8 a5 11 cd ab cd 4 a5 d1 e1 c2 fb a9 c3 d4 a9 11 cd ab cd da a4 3c c2 1 aa 1 7 aa cd a7 a4 cd d5 a5 c3 86 ab 4e 6f 20 73 70 61 63 65 0 cd 5e a6 c2 9 a6 3a f0 ab f5 cd 54 a8 cd e9 a4 c2 79 aa 21 cd ab 11 dd ab 6 10 cd 42 a8 2a 88 a4 eb cd 4f a6 fe 3d ca 3f aa fe 5f c2 73 aa eb 23 22 88 a4 cd 5e a6 c2 73 aa f1 47 21 f0 ab 7e b7 ca 59 aa b8 70 c2 73 aa 70 af 32 cd ab cd e9 a4 ca 6d aa 11 cd ab cd e a5 c3 86 ab cd ea a7 c3 86 ab cd 66 a8 c3 9 a6 1 82 aa cd a7 a4 c3 86 ab 46 69 6c 65 20 65 78 69 73 74 73 0 cd f8 a7 fe 10 d2 9 a6 5f 3a ce ab fe 20 ca 9 a6 cd 15 a5 c3 89 ab cd f5 a5 3a ce ab fe 20 c2 c4 aa 3a f0 ab b7 ca 89 ab 3d 32 ef ab cd 29 a5 cd bd a4 c3 89 ab 11 d6 ab 1a fe 20 c2 9 a6 d5 cd 54 a8 d1 21 83 ab cd 40 a8 cd d0 a4 ca 6b ab 21 0 1 e5 eb cd d8 a5 11 cd ab cd f9 a4 c2 1 ab e1 11 80 0 19 11 0 a4 7d 93 7c 9a d2 71 ab c3 e1 aa e1 3d c2 71 ab cd 66 a8 cd 5e a6 21 f0 ab e5 7e 32 cd ab 3e 10 cd 60 a6 e1 7e 32 dd ab af 32 ed ab 11 5c 0 21 cd ab 6 21 cd 42 a8 21 8 a4 7e b7 ca 3e ab fe 20 ca 3e ab 23 c3 30 ab 6 0 11 81 0 7e 12 b7 ca 4f ab 4 23 13 c3 43 ab 78 32 80 0 cd 98 a4 cd d5 a5 cd 1a a5 cd 0 1 31 ab ab cd 29 a5 cd bd a4 c3 82 a7 cd 66 a8 c3 9 a6 1 7a ab cd a7 a4 c3 86 ab 42 61 64 20 6c 6f 61 64 0 43 4f 4d cd 66 a8 cd 5e a6 3a ce ab d6 20 21 f0 ab b6 c2 9 a6 c3 82 a7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 24 24 24 20 20 20 20 20 53 55 42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 20 20 20 20 20 20 20 20 20 20 0 0 0 0 0 20 20 20 20 20 20 20 20 20 20 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 0 0 0 0 c3 11 ac 99 ac a5 ac ab ac b1 ac eb 22 43 af eb 7b 32 d6 b9 21 0 0 22 45 af 39 22 f af 31 41 af af 32 e0 b9 32 de b9 21 74 b9 e5 79 fe 29 d0 4b 21 47 ac 5f 16 0 19 19 5e 23 56 2a 43 af eb e9 3 ba c8 ae 90 ad ce ae 12 ba f ba d4 ae ed ae f3 ae f8 ae e1 ad fe ae 7e b8 83 b8 45 b8 9c b8 a5 b8 ab b8 c8 b8 d7 b8 e0 b8 e6 b8 ec b8 f5 b8 fe b8 4 b9 a b9 11 b9 2c b1 17 b9 1d b9 26 b9 2d b9 41 b9 47 b9 4d b9 e b8 53 b9 4 af 4 af 9b b9 21 ca ac cd e5 ac fe 3 ca 0 0 c9 21 d5 ac c3 b4 ac 21 e1 ac c3 b4 ac 21 dc ac cd e5 ac c3 0 0 42 64 6f 73 20 45 72 72 20 4f 6e 20 20 3a 20 24 42 61 64 20 53 65 63 74 6f 72 24 53 65 6c 65 63 74 24 46 69 6c 65 20 52 2f 4f 24 e5 cd c9 ad 3a 42 af c6 41 32 c6 ac 1 ba ac cd d3 ad c1 cd d3 ad 21 e af 7e 36 0 b7 c0 c3 9 ba cd fb ac cd 14 ad d8 f5 4f cd 90 ad f1 c9 fe d c8 fe a c8 fe 9 c8 fe 8 c8 fe 20 c9 3a e af b7 c2 45 ad cd 6 ba e6 1 c8 cd 9 ba fe 13 c2 42 ad cd 9 ba fe 3 ca 0 0 af c9 32 e af 3e 1 c9 3a a af b7 c2 62 ad c5 cd 23 ad c1 c5 cd c ba c1 c5 3a d af b7 c4 f ba c1 79 21 c af fe 7f c8 34 fe 20 d0 35 7e b7 c8 79 fe 8 c2 79 ad 35 c9 fe a c0 36 0 c9 79 cd 14 ad d2 90 ad f5 e 5e cd 48 ad f1 f6 40 4f 79 fe 9 c2 48 ad e 20 cd 48 ad 3a c af e6 7 c2 96 ad c9 cd ac ad e 20 cd c ba e 8 c3 c ba e 23 cd 48 ad cd c9 ad 3a c af 21 b af be d0 e 20 cd 48 ad c3 b9 ad e d cd 48 ad e a c3 48 ad a fe 24 c8 3 c5 4f cd 90 ad c1 c3 d3 ad 3a c af 32 b af 2a 43 af 4e 23 e5 6 0 c5 e5 cd fb ac e6 7f e1 c1 fe d ca c1 ae fe a ca c1 ae fe 8 c2 16 ae 78 b7 ca ef ad 5 3a c af 32 a af c3 70 ae fe 7f c2 26 ae 78 b7 ca ef ad 7e 5 2b c3 a9 ae fe 5 c2 37 ae c5 e5 cd c9 ad af 32 b af c3 f1 ad fe 10 c2 48 ae e5 21 d af 3e 1 96 77 e1 c3 ef ad fe 18 c2 5f ae e1 3a b af 21 c af be d2 e1 ad 35 cd a4 ad c3 4e ae fe 15 c2 6b ae cd b1 ad e1 c3 e1 ad fe 12 c2 a6 ae c5 cd b1 ad c1 e1 e5 c5 78 b7 ca 8a ae 23 4e 5 c5 e5 cd 7f ad e1 c1 c3 78 ae e5 3a a af b7 ca f1 ad 21 c af 96 32 a af cd a4 ad 21 a af 35 c2 99 ae c3 f1 ad 23 77 4 c5 e5 4f cd 7f ad e1 c1 7e fe 3 78 c2 bd ae fe 1 ca 0 0 b9 da ef ad e1 70 e d c3 48 ad cd 6 ad c3 1 af cd 15 ba c3 1 af 79 3c ca e0 ae 3c ca 6 ba c3 c ba cd 6 ba b7 ca 91 b9 cd 9 ba c3 1 af 3a 3 0 c3 1 af 21 3 0 71 c9 eb 4d 44 c3 d3 ad cd 23 ad 32 45 af c9 3e 1 c3 1 af 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 b ac 5e 23 56 eb e9 c d c8 1a 77 13 23 c3 50 af 3a 42 af 4f cd 1b ba 7c b5 c8 5e 23 56 23 22 b3 b9 23 23 22 b5 b9 23 23 22 b7 b9 23 23 eb 22 d0 b9 21 b9 b9 e 8 cd 4f af 2a bb b9 eb 21 c1 b9 e f cd 4f af 2a c6 b9 7c 21 dd b9 36 ff b7 ca 9d af 36 0 3e ff b7 c9 cd 18 ba af 2a b5 b9 77 23 77 2a b7 b9 77 23 77 c9 cd 27 ba c3 bb af cd 2a ba b7 c8 21 9 ac c3 4a af 2a ea b9 e 2 cd ea b0 22 e5 b9 22 ec b9 21 e5 b9 4e 23 46 2a b7 b9 5e 23 56 2a b5 b9 7e 23 66 6f 79 93 78 9a d2 fa af e5 2a c1 b9 7b 95 5f 7a 9c 57 e1 2b c3 e4 af e5 2a c1 b9 19 da f b0 79 95 78 9c da f b0 eb e1 23 c3 fa af e1 c5 d5 e5 eb 2a ce b9 19 44 4d cd 1e ba d1 2a b5 b9 73 23 72 d1 2a b7 b9 73 23 72 c1 79 93 4f 78 9a 47 2a d0 b9 eb cd 30 ba 4d 44 c3 21 ba 21 c3 b9 4e 3a e3 b9 b7 1f d c2 45 b0 47 3e 8 96 4f 3a e2 b9 d ca 5c b0 b7 17 c3 53 b0 80 c9 2a 43 af 11 10 0 19 9 3a dd b9 b7 ca 71 b0 6e 26 0 c9 9 5e 23 56 eb c9 cd 3e b0 4f 6 0 cd 5e b0 22 e5 b9 c9 2a e5 b9 7d b4 c9 3a c3 b9 2a e5 b9 29 3d c2 90 b0 22 e7 b9 3a c4 b9 4f 3a e3 b9 a1 b5 6f 22 e5 b9 c9 2a 43 af 11 c 0 19 c9 2a 43 af 11 f 0 19 eb 21 11 0 19 c9 cd ae b0 7e 32 e3 b9 eb 7e 32 e1 b9 cd a6 b0 3a c5 b9 a6 32 e2 b9 c9 cd ae b0 3a d5 b9 fe 2 c2 de b0 af 4f 3a e3 b9 81 77 eb 3a e1 b9 77 c9 c d c8 7c b7 1f 67 7d 1f 6f c3 eb b0 e 80 2a b9 b9 af 86 23 d c2 fd b0 c9 c d c8 29 c3 5 b1 c5 3a 42 af 4f 21 1 0 cd 4 b1 c1 79 b5 6f 78 b4 67 c9 2a ad b9 3a 42 af 4f cd ea b0 7d e6 1 c9 21 ad b9 4e 23 46 cd b b1 22 ad b9 2a c8 b9 23 eb 2a b3 b9 73 23 72 c9 cd 5e b1 11 9 0 19 7e 17 d0 21 f ac c3 4a af cd 1e b1 c8 21 d ac c3 4a af 2a b9 b9 3a e9 b9 85 6f d0 24 c9 2a 43 af 11 e 0 19 7e c9 cd 69 b1 36 0 c9 cd 69 b1 f6 80 77 c9 2a ea b9 eb 2a b3 b9 7b 96 23 7a 9e c9 cd 7f b1 d8 13 72 2b 73 c9 7b 95 6f 7a 9c 67 c9 e ff 2a ec b9 eb 2a cc b9 cd 95 b1 d0 c5 cd f7 b0 2a bd b9 eb 2a ec b9 19 c1 c ca c4 b1 be c8 cd 7f b1 d0 cd 2c b1 c9 77 c9 cd 9c b1 cd e0 b1 e 1 cd b8 af c3 da b1 cd e0 b1 cd b2 af 21 b1 b9 c3 e3 b1 21 b9 b9 4e 23 46 c3 24 ba 2a b9 b9 eb 2a b1 b9 e 80 c3 4f af 21 ea b9 7e 23 be c0 3c c9 21 ff ff 22 ea b9 c9 2a c8 b9 eb 2a ea b9 23 22 ea b9 cd 95 b1 d2 19 b2 c3 fe b1 3a ea b9 e6 3 6 5 87 5 c2 20 b2 32 e9 b9 b7 c0 c5 cd c3 af cd d4 b1 c1 c3 9e b1 79 e6 7 3c 5f 57 79 f f f e6 1f 4f 78 87 87 87 87 87 b1 4f 78 f f f e6 1f 47 2a bf b9 9 7e 7 1d c2 56 b2 c9 d5 cd 35 b2 e6 fe c1 b1 f 15 c2 64 b2 77 c9 cd 5e b1 11 10 0 19 c5 e 11 d1 d c8 d5 3a dd b9 b7 ca 88 b2 c5 e5 4e 6 0 c3 8e b2 d c5 4e 23 46 e5 79 b0 ca 9d b2 2a c6 b9 7d 91 7c 98 d4 5c b2 e1 23 c1 c3 75 b2 2a c6 b9 e 3 cd ea b0 23 44 4d 2a bf b9 36 0 23 b 78 b1 c2 b1 b2 2a ca b9 eb 2a bf b9 73 23 72 cd a1 af 2a b3 b9 36 3 23 36 0 cd fe b1 e ff cd 5 b2 cd f5 b1 c8 cd 5e b1 3e e5 be ca d2 b2 3a 41 af be c2 f6 b2 23 7e d6 24 c2 f6 b2 3d 32 45 af e 1 cd 6b b2 cd 8c b1 c3 d2 b2 3a d4 b9 c3 1 af c5 f5 3a c5 b9 2f 47 79 a0 4f f1 a0 91 e6 1f c1 c9 3e ff 32 d4 b9 21 d8 b9 71 2a 43 af 22 d9 b9 cd fe b1 cd a1 af e 0 cd 5 b2 cd f5 b1 ca 94 b3 2a d9 b9 eb 1a fe e5 ca 4a b3 d5 cd 7f b1 d1 d2 94 b3 cd 5e b1 3a d8 b9 4f 6 0 79 b7 ca 83 b3 1a fe 3f ca 7c b3 78 fe d ca 7c b3 fe c 1a ca 73 b3 96 e6 7f c2 2d b3 c3 7c b3 c5 4e cd 7 b3 c1 c2 2d b3 13 23 4 d c3 53 b3 3a ea b9 e6 3 32 45 af 21 d4 b9 7e 17 d0 af 77 c9 cd fe b1 3e ff c3 1 af cd 54 b1 e c cd 18 b3 cd f5 b1 c8 cd 44 b1 cd 5e b1 36 e5 e 0 cd 6b b2 cd c6 b1 cd 2d b3 c3 a4 b3 50 59 79 b0 ca d1 b3 b d5 c5 cd 35 b2 1f d2 ec b3 c1 d1 2a c6 b9 7b 95 7a 9c d2 f4 b3 13 c5 d5 42 4b cd 35 b2 1f d2 ec b3 d1 c1 c3 c0 b3 17 3c cd 64 b2 e1 d1 c9 79 b0 c2 c0 b3 21 0 0 c9 e 0 1e 20 d5 6 0 2a 43 af 9 eb cd 5e b1 c1 cd 4f af cd c3 af c3 c6 b1 cd 54 b1 e c cd 18 b3 2a 43 af 7e 11 10 0 19 77 cd f5 b1 c8 cd 44 b1 e 10 1e c cd 1 b4 cd 2d b3 c3 27 b4 e c cd 18 b3 cd f5 b1 c8 e 0 1e c cd 1 b4 cd 2d b3 c3 40 b4 e f cd 18 b3 cd f5 b1 c8 cd a6 b0 7e f5 e5 cd 5e b1 eb 2a 43 af e 20 d5 cd 4f af cd 78 b1 d1 21 c 0 19 4e 21 f 0 19 46 e1 f1 77 79 be 78 ca 8b b4 3e 0 da 8b b4 3e 80 2a 43 af 11 f 0 19 77 c9 7e 23 b6 2b c0 1a 77 13 23 1a 77 1b 2b c9 af 32 45 af 32 ea b9 32 eb b9 cd 1e b1 c0 cd 69 b1 e6 80 c0 e f cd 18 b3 cd f5 b1 c8 1 10 0 cd 5e b1 9 eb 2a 43 af 9 e 10 3a dd b9 b7 ca e8 b4 7e b7 1a c2 db b4 77 b7 c2 e1 b4 7e 12 be c2 1f b5 c3 fd b4 cd 94 b4 eb cd 94 b4 eb 1a be c2 1f b5 13 23 1a be c2 1f b5 d 13 23 d c2 cd b4 1 ec ff 9 eb 9 1a be da 17 b5 77 1 3 0 9 eb 9 7e 12 3e ff 32 d2 b9 c3 10 b4 21 45 af 35 c9 cd 54 b1 2a 43 af e5 21 ac b9 22 43 af e 1 cd 18 b3 cd f5 b1 e1 22 43 af c8 eb 21 f 0 19 e 11 af 77 23 d c2 46 b5 21 d 0 19 77 cd 8c b1 cd fd b3 c3 78 b1 af 32 d2 b9 cd a2 b4 cd f5 b1 c8 2a 43 af 1 c 0 9 7e 3c e6 1f 77 ca 83 b5 47 3a c5 b9 a0 21 d2 b9 a6 ca 8e b5 c3 ac b5 1 2 0 9 34 7e e6 f ca b6 b5 e f cd 18 b3 cd f5 b1 c2 ac b5 3a d3 b9 3c ca b6 b5 cd 24 b5 cd f5 b1 ca b6 b5 c3 af b5 cd 5a b4 cd bb b0 af c3 1 af cd 5 af c3 78 b1 3e 1 32 d5 b9 3e ff 32 d3 b9 cd bb b0 3a e3 b9 21 e1 b9 be da e6 b5 fe 80 c2 fb b5 cd 5a b5 af 32 e3 b9 3a 45 af b7 c2 fb b5 cd 77 b0 cd 84 b0 ca fb b5 cd 8a b0 cd d1 af cd b2 af c3 d2 b0 c3 5 af 3e 1 32 d5 b9 3e 0 32 d3 b9 cd 54 b1 2a 43 af cd 47 b1 cd bb b0 3a e3 b9 fe 80 d2 5 af cd 77 b0 cd 84 b0 e 0 c2 6e b6 cd 3e b0 32 d7 b9 1 0 0 b7 ca 3b b6 4f b cd 5e b0 44 4d cd be b3 7d b4 c2 48 b6 3e 2 c3 1 af 22 e5 b9 eb 2a 43 af 1 10 0 9 3a dd b9 b7 3a d7 b9 ca 64 b6 cd 64 b1 73 c3 6c b6 4f 6 0 9 9 73 23 72 e 2 3a 45 af b7 c0 c5 cd 8a b0 3a d5 b9 3d 3d c2 bb b6 c1 c5 79 3d 3d c2 bb b6 e5 2a b9 b9 57 77 23 14 f2 8c b6 cd e0 b1 2a e7 b9 e 2 22 e5 b9 c5 cd d1 af c1 cd b8 af 2a e5 b9 e 0 3a c4 b9 47 a5 b8 23 c2 9a b6 e1 22 e5 b9 cd da b1 cd d1 af c1 c5 cd b8 af c1 3a e3 b9 21 e1 b9 be da d2 b6 77 34 e 2 0 0 21 0 0 f5 cd 69 b1 e6 7f 77 f1 fe 7f c2 0 b7 3a d5 b9 fe 1 c2 0 b7 cd d2 b0 cd 5a b5 21 45 af 7e b7 c2 fe b6 3d 32 e3 b9 36 0 c3 d2 b0 af 32 d5 b9 c5 2a 43 af eb 21 21 0 19 7e e6 7f f5 7e 17 23 7e 17 e6 1f 4f 7e 1f 1f 1f 1f e6 f 47 f1 23 6e 2c 2d 2e 6 c2 8b b7 21 20 0 19 77 21 c 0 19 79 96 c2 47 b7 21 e 0 19 78 96 e6 7f ca 7f b7 c5 d5 cd a2 b4 d1 c1 2e 3 3a 45 af 3c ca 84 b7 21 c 0 19 71 21 e 0 19 70 cd 51 b4 3a 45 af 3c c2 7f b7 c1 c5 2e 4 c ca 84 b7 cd 24 b5 2e 5 3a 45 af 3c ca 84 b7 c1 af c3 1 af e5 cd 69 b1 36 c0 e1 c1 7d 32 45 af c3 78 b1 e ff cd 3 b7 cc c1 b5 c9 e 0 cd 3 b7 cc 3 b6 c9 eb 19 4e 6 0 21 c 0 19 7e f e6 80 81 4f 3e 0 88 47 7e f e6 f 80 47 21 e 0 19 7e 87 87 87 87 f5 80 47 f5 e1 7d e1 b5 e6 1 c9 e c cd 18 b3 2a 43 af 11 21 0 19 e5 72 23 72 23 72 cd f5 b1 ca c b8 cd 5e b1 11 f 0 cd a5 b7 e1 e5 5f 79 96 23 78 9e 23 7b 9e da 6 b8 73 2b 70 2b 71 cd 2d b3 c3 e4 b7 e1 c9 2a 43 af 11 20 0 cd a5 b7 21 21 0 19 71 23 70 23 77 c9 2a af b9 3a 42 af 4f cd ea b0 e5 eb cd 59 af e1 cc 47 af 7d 1f d8 2a af b9 4d 44 cd b b1 22 af b9 c3 a3 b2 3a d6 b9 21 42 af be c8 77 c3 21 b8 3e ff 32 de b9 2a 43 af 7e e6 1f 3d 32 d6 b9 fe 1e d2 75 b8 3a 42 af 32 df b9 7e 32 e0 b9 e6 e0 77 cd 45 b8 3a 41 af 2a 43 af b6 77 c9 3e 22 c3 1 af 21 0 0 22 ad b9 22 af b9 af 32 42 af 21 80 0 22 b1 b9 cd da b1 c3 21 b8 cd 72 b1 cd 51 b8 c3 51 b4 cd 51 b8 c3 a2 b4 e 0 eb 7e fe 3f ca c2 b8 cd a6 b0 7e fe 3f c4 72 b1 cd 51 b8 e f cd 18 b3 c3 e9 b1 2a d9 b9 22 43 af cd 51 b8 cd 2d b3 c3 e9 b1 cd 51 b8 cd 9c b3 c3 1 b3 cd 51 b8 c3 bc b5 cd 51 b8 c3 fe b5 cd 72 b1 cd 51 b8 c3 24 b5 cd 51 b8 cd 16 b4 c3 1 b3 2a af b9 c3 29 b9 3a 42 af c3 1 af eb 22 b1 b9 c3 da b1 2a bf b9 c3 29 b9 2a ad b9 c3 29 b9 cd 51 b8 cd 3b b4 c3 1 b3 2a bb b9 22 45 af c9 3a d6 b9 fe ff c2 3b b9 3a 41 af c3 1 af e6 1f 32 41 af c9 cd 51 b8 c3 93 b7 cd 51 b8 c3 9c b7 cd 51 b8 c3 d2 b7 2a 43 af 7d 2f 5f 7c 2f 2a af b9 a4 57 7d a3 5f 2a ad b9 eb 22 af b9 7d a3 6f 7c a2 67 22 ad b9 c9 3a de b9 b7 ca 91 b9 2a 43 af 36 0 3a e0 b9 b7 ca 91 b9 77 3a df b9 32 d6 b9 cd 45 b8 2a f af f9 2a 45 af 7d 44 c9 cd 51 b8 3e 2 32 d5 b9 e 0 cd 7 b7 cc 3 b6 c9 e5 0 0 0 0 80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 0 c3 0 diff --git a/branches/s100/Applegate/cpm22.asm b/branches/s100/Applegate/cpm22.asm deleted file mode 100644 index 1a8b2766..00000000 --- a/branches/s100/Applegate/cpm22.asm +++ /dev/null @@ -1,3746 +0,0 @@ -;************************************************************** -;* -;* C P / M version 2 . 2 -;* -;* Reconstructed from memory image on February 27, 1981 -;* -;* by Clark A. Calkins -;* -;************************************************************** -; -#include "tasm.inc" - -#include "cpm22.inc" - -; -;IOBYTE EQU 3 ;i/o definition byte. -;TDRIVE EQU 4 ;current drive name and user number. -;ENTRY EQU 5 ;entry point for the cp/m bdos. -TFCB EQU 5CH ;default file control block. -TBUFF EQU 80H ;i/o buffer and command line storage. -TBASE EQU 100H ;transiant program storage area. -; -; Set control character equates. -; -CNTRLC EQU 3 ;control-c -CNTRLE EQU 05H ;control-e -BS EQU 08H ;backspace -TAB EQU 09H ;tab -LF EQU 0AH ;line feed -FF EQU 0CH ;form feed -CR EQU 0DH ;carriage return -CNTRLP EQU 10H ;control-p -CNTRLR EQU 12H ;control-r -CNTRLS EQU 13H ;control-s -CNTRLU EQU 15H ;control-u -CNTRLX EQU 18H ;control-x -CNTRLZ EQU 1AH ;control-z (end-of-file mark) -DEL EQU 7FH ;rubout -; -; Set origin for CP/M -; - ORG CCPBASE -; ORG (RAMSIZE-7)*1024 -; -CBASE: JP COMMAND ;execute command processor (ccp). - JP CLEARBUF ;entry to empty input buffer before starting ccp. - -; -; Standard cp/m ccp input buffer. Format is (max length), -; (actual length), (char #1), (char #2), (char #3), etc. -; -INBUFF: DEFB 127 ;length of input buffer. - DEFB 0 ;current length of contents. - TEXT "Copyright" - TEXT " 1979 (c) by Digital Research " - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -INPOINT:DEFW INBUFF+2 ;input line pointer -NAMEPNT:DEFW 0 ;input line pointer used for error message. Points to -; ;start of name in error. -; -; Routine to print (A) on the console. All registers used. -; -PRINT: LD E,A ;setup bdos call. - LD C,2 - JP ENTRY -; -; Routine to print (A) on the console and to save (BC). -; -PRINTB: PUSH BC - CALL PRINT - POP BC - RET -; -; Routine to send a carriage return, line feed combination -; to the console. -; -CRLF: LD A,CR - CALL PRINTB - LD A,LF - JP PRINTB -; -; Routine to send one space to the console and save (BC). -; -SPACE: LD A,' ' - JP PRINTB -; -; Routine to print character string pointed to be (BC) on the -; console. It must terminate with a null byte. -; -PLINE: PUSH BC - CALL CRLF - POP HL -PLINE2: LD A,(HL) - OR A - RET Z - INC HL - PUSH HL - CALL PRINT - POP HL - JP PLINE2 -; -; Routine to reset the disk system. -; -RESDSK: LD C,13 - JP ENTRY -; -; Routine to select disk (A). -; -DSKSEL: LD E,A - LD C,14 - JP ENTRY -; -; Routine to call bdos and save the return code. The zero -; flag is set on a return of 0ffh. -; -ENTRY1: CALL ENTRY - LD (RTNCODE),A ;save return code. - INC A ;set zero if 0ffh returned. - RET -; -; Routine to open a file. (DE) must point to the FCB. -; -OPEN: LD C,15 - JP ENTRY1 -; -; Routine to open file at (FCB). -; -OPENFCB:XOR A ;clear the record number byte at fcb+32 - LD (FCB+32),A - LD DE,FCB - JP OPEN -; -; Routine to close a file. (DE) points to FCB. -; -CLOSE: LD C,16 - JP ENTRY1 -; -; Routine to search for the first file with ambigueous name -; (DE). -; -SRCHFST:LD C,17 - JP ENTRY1 -; -; Search for the next ambigeous file name. -; -SRCHNXT:LD C,18 - JP ENTRY1 -; -; Search for file at (FCB). -; -SRCHFCB:LD DE,FCB - JP SRCHFST -; -; Routine to delete a file pointed to by (DE). -; -DELETE: LD C,19 - JP ENTRY -; -; Routine to call the bdos and set the zero flag if a zero -; status is returned. -; -ENTRY2: CALL ENTRY - OR A ;set zero flag if appropriate. - RET -; -; Routine to read the next record from a sequential file. -; (DE) points to the FCB. -; -RDREC: LD C,20 - JP ENTRY2 -; -; Routine to read file at (FCB). -; -READFCB:LD DE,FCB - JP RDREC -; -; Routine to write the next record of a sequential file. -; (DE) points to the FCB. -; -WRTREC: LD C,21 - JP ENTRY2 -; -; Routine to create the file pointed to by (DE). -; -CREATE: LD C,22 - JP ENTRY1 -; -; Routine to rename the file pointed to by (DE). Note that -; the new name starts at (DE+16). -; -RENAM: LD C,23 - JP ENTRY -; -; Get the current user code. -; -GETUSR: LD E,0FFH -; -; Routne to get or set the current user code. -; If (E) is FF then this is a GET, else it is a SET. -; -GETSETUC: LD C,32 - JP ENTRY -; -; Routine to set the current drive byte at (TDRIVE). -; -SETCDRV:CALL GETUSR ;get user number - ADD A,A ;and shift into the upper 4 bits. - ADD A,A - ADD A,A - ADD A,A - LD HL,CDRIVE ;now add in the current drive number. - OR (HL) - LD (TDRIVE),A ;and save. - RET -; -; Move currently active drive down to (TDRIVE). -; -MOVECD: LD A,(CDRIVE) - LD (TDRIVE),A - RET -; -; Routine to convert (A) into upper case ascii. Only letters -; are affected. -; -UPPER: CP 'a' ;check for letters in the range of 'a' to 'z'. - RET C - CP '{' - RET NC - AND 5FH ;convert it if found. - RET -; -; Routine to get a line of input. We must check to see if the -; user is in (BATCH) mode. If so, then read the input from file -; ($$$.SUB). At the end, reset to console input. -; -GETINP: LD A,(BATCH) ;if =0, then use console input. - OR A - JP Z,GETINP1 -; -; Use the submit file ($$$.sub) which is prepared by a -; SUBMIT run. It must be on drive (A) and it will be deleted -; if and error occures (like eof). -; - LD A,(CDRIVE) ;select drive 0 if need be. - OR A - LD A,0 ;always use drive A for submit. - CALL NZ,DSKSEL ;select it if required. - LD DE,BATCHFCB - CALL OPEN ;look for it. - JP Z,GETINP1 ;if not there, use normal input. - LD A,(BATCHFCB+15) ;get last record number+1. - DEC A - LD (BATCHFCB+32),A - LD DE,BATCHFCB - CALL RDREC ;read last record. - JP NZ,GETINP1 ;quit on end of file. -; -; Move this record into input buffer. -; - LD DE,INBUFF+1 - LD HL,TBUFF ;data was read into buffer here. - LD B,128 ;all 128 characters may be used. - CALL HL2DE ;(HL) to (DE), (B) bytes. - LD HL,BATCHFCB+14 - LD (HL),0 ;zero out the 's2' byte. - INC HL ;and decrement the record count. - DEC (HL) - LD DE,BATCHFCB ;close the batch file now. - CALL CLOSE - JP Z,GETINP1 ;quit on an error. - LD A,(CDRIVE) ;re-select previous drive if need be. - OR A - CALL NZ,DSKSEL ;don't do needless selects. -; -; Print line just read on console. -; - LD HL,INBUFF+2 - CALL PLINE2 - CALL CHKCON ;check console, quit on a key. - JP Z,GETINP2 ;jump if no key is pressed. -; -; Terminate the submit job on any keyboard input. Delete this -; file such that it is not re-started and jump to normal keyboard -; input section. -; - CALL DELBATCH ;delete the batch file. - JP CMMND1 ;and restart command input. -; -; Get here for normal keyboard input. Delete the submit file -; incase there was one. -; -GETINP1:CALL DELBATCH ;delete file ($$$.sub). - CALL SETCDRV ;reset active disk. - LD C,10 ;get line from console device. - LD DE,INBUFF - CALL ENTRY - CALL MOVECD ;reset current drive (again). -; -; Convert input line to upper case. -; -GETINP2:LD HL,INBUFF+1 - LD B,(HL) ;(B)=character counter. -GETINP3:INC HL - LD A,B ;end of the line? - OR A - JP Z,GETINP4 - LD A,(HL) ;convert to upper case. - CALL UPPER - LD (HL),A - DEC B ;adjust character count. - JP GETINP3 -GETINP4:LD (HL),A ;add trailing null. - LD HL,INBUFF+2 - LD (INPOINT),HL ;reset input line pointer. - RET -; -; Routine to check the console for a key pressed. The zero -; flag is set is none, else the character is returned in (A). -; -CHKCON: LD C,11 ;check console. - CALL ENTRY - OR A - RET Z ;return if nothing. - LD C,1 ;else get character. - CALL ENTRY - OR A ;clear zero flag and return. - RET -; -; Routine to get the currently active drive number. -; -GETDSK: LD C,25 - JP ENTRY -; -; Set the stabdard dma address. -; -STDDMA: LD DE,TBUFF -; -; Routine to set the dma address to (DE). -; -DMASET: LD C,26 - JP ENTRY -; -; Delete the batch file created by SUBMIT. -; -DELBATCH: LD HL,BATCH ;is batch active? - LD A,(HL) - OR A - RET Z - LD (HL),0 ;yes, de-activate it. - XOR A - CALL DSKSEL ;select drive 0 for sure. - LD DE,BATCHFCB ;and delete this file. - CALL DELETE - LD A,(CDRIVE) ;reset current drive. - JP DSKSEL -; -; Check to two strings at (PATTRN1) and (PATTRN2). They must be -; the same or we halt.... -; -VERIFY: LD DE,PATTRN1 ;these are the serial number bytes. - LD HL,PATTRN2 ;ditto, but how could they be different? - LD B,6 ;6 bytes each. -VERIFY1:LD A,(DE) - CP (HL) - JP NZ,HALT ;jump to halt routine. - INC DE - INC HL - DEC B - JP NZ,VERIFY1 - RET -; -; Print back file name with a '?' to indicate a syntax error. -; -SYNERR: CALL CRLF ;end current line. - LD HL,(NAMEPNT) ;this points to name in error. -SYNERR1:LD A,(HL) ;print it until a space or null is found. - CP ' ' - JP Z,SYNERR2 - OR A - JP Z,SYNERR2 - PUSH HL - CALL PRINT - POP HL - INC HL - JP SYNERR1 -SYNERR2:LD A,'?' ;add trailing '?'. - CALL PRINT - CALL CRLF - CALL DELBATCH ;delete any batch file. - JP CMMND1 ;and restart from console input. -; -; Check character at (DE) for legal command input. Note that the -; zero flag is set if the character is a delimiter. -; -CHECK: LD A,(DE) - OR A - RET Z - CP ' ' ;control characters are not legal here. - JP C,SYNERR - RET Z ;check for valid delimiter. - CP '=' - RET Z - CP '_' - RET Z - CP '.' - RET Z - CP ':' - RET Z - CP 3bH ;semicolon; TASM can't do it in a quote - RET Z - CP '<' - RET Z - CP '>' - RET Z - RET -; -; Get the next non-blank character from (DE). -; -NONBLANK: LD A,(DE) - OR A ;string ends with a null. - RET Z - CP ' ' - RET NZ - INC DE - JP NONBLANK -; -; Add (HL)=(HL)+(A) -; -ADDHL: ADD A,L - LD L,A - RET NC ;take care of any carry. - INC H - RET -; -; Convert the first name in (FCB). -; -CONVFST:LD A,0 -; -; Format a file name (convert * to '?', etc.). On return, -; (A)=0 is an unambigeous name was specified. Enter with (A) equal to -; the position within the fcb for the name (either 0 or 16). -; -CONVERT:LD HL,FCB - CALL ADDHL - PUSH HL - PUSH HL - XOR A - LD (CHGDRV),A ;initialize drive change flag. - LD HL,(INPOINT) ;set (HL) as pointer into input line. - EX DE,HL - CALL NONBLANK ;get next non-blank character. - EX DE,HL - LD (NAMEPNT),HL ;save pointer here for any error message. - EX DE,HL - POP HL - LD A,(DE) ;get first character. - OR A - JP Z,CONVRT1 - SBC A,'A'-1 ;might be a drive name, convert to binary. - LD B,A ;and save. - INC DE ;check next character for a ':'. - LD A,(DE) - CP ':' - JP Z,CONVRT2 - DEC DE ;nope, move pointer back to the start of the line. -CONVRT1:LD A,(CDRIVE) - LD (HL),A - JP CONVRT3 -CONVRT2:LD A,B - LD (CHGDRV),A ;set change in drives flag. - LD (HL),B - INC DE -; -; Convert the basic file name. -; -CONVRT3:LD B,08H -CONVRT4:CALL CHECK - JP Z,CONVRT8 - INC HL - CP '*' ;note that an '*' will fill the remaining - JP NZ,CONVRT5 ;field with '?'. - LD (HL),'?' - JP CONVRT6 -CONVRT5:LD (HL),A - INC DE -CONVRT6:DEC B - JP NZ,CONVRT4 -CONVRT7:CALL CHECK ;get next delimiter. - JP Z,GETEXT - INC DE - JP CONVRT7 -CONVRT8:INC HL ;blank fill the file name. - LD (HL),' ' - DEC B - JP NZ,CONVRT8 -; -; Get the extension and convert it. -; -GETEXT: LD B,03H - CP '.' - JP NZ,GETEXT5 - INC DE -GETEXT1:CALL CHECK - JP Z,GETEXT5 - INC HL - CP '*' - JP NZ,GETEXT2 - LD (HL),'?' - JP GETEXT3 -GETEXT2:LD (HL),A - INC DE -GETEXT3:DEC B - JP NZ,GETEXT1 -GETEXT4:CALL CHECK - JP Z,GETEXT6 - INC DE - JP GETEXT4 -GETEXT5:INC HL - LD (HL),' ' - DEC B - JP NZ,GETEXT5 -GETEXT6:LD B,3 -GETEXT7:INC HL - LD (HL),0 - DEC B - JP NZ,GETEXT7 - EX DE,HL - LD (INPOINT),HL ;save input line pointer. - POP HL -; -; Check to see if this is an ambigeous file name specification. -; Set the (A) register to non zero if it is. -; - LD BC,11 ;set name length. -GETEXT8:INC HL - LD A,(HL) - CP '?' ;any question marks? - JP NZ,GETEXT9 - INC B ;count them. -GETEXT9:DEC C - JP NZ,GETEXT8 - LD A,B - OR A - RET -; -; CP/M command table. Note commands can be either 3 or 4 characters long. -; -NUMCMDS EQU 6 ;number of commands -CMDTBL: DEFB "DIR " - DEFB "ERA " - DEFB "TYPE" - DEFB "SAVE" - DEFB "REN " - DEFB "USER" -; -; The following six bytes must agree with those at (PATTRN2) -; or cp/m will HALT. Why? -; -PATTRN1:DEFB 0,22,0,0,0,0 ;(* serial number bytes *). -; -; Search the command table for a match with what has just -; been entered. If a match is found, then we jump to the -; proper section. Else jump to (UNKNOWN). -; On return, the (C) register is set to the command number -; that matched (or NUMCMDS+1 if no match). -; -SEARCH: LD HL,CMDTBL - LD C,0 -SEARCH1:LD A,C - CP NUMCMDS ;this commands exists. - RET NC - LD DE,FCB+1 ;check this one. - LD B,4 ;max command length. -SEARCH2:LD A,(DE) - CP (HL) - JP NZ,SEARCH3 ;not a match. - INC DE - INC HL - DEC B - JP NZ,SEARCH2 - LD A,(DE) ;allow a 3 character command to match. - CP ' ' - JP NZ,SEARCH4 - LD A,C ;set return register for this command. - RET -SEARCH3:INC HL - DEC B - JP NZ,SEARCH3 -SEARCH4:INC C - JP SEARCH1 -; -; Set the input buffer to empty and then start the command -; processor (ccp). -; -CLEARBUF: XOR A - LD (INBUFF+1),A ;second byte is actual length. -; -;************************************************************** -;* -;* -;* C C P - C o n s o l e C o m m a n d P r o c e s s o r -;* -;************************************************************** -;* -COMMAND:LD SP,CCPSTACK ;setup stack area. - PUSH BC ;note that (C) should be equal to: - LD A,C ;(uuuudddd) where 'uuuu' is the user number - RRA ;and 'dddd' is the drive number. - RRA - RRA - RRA - AND 0FH ;isolate the user number. - LD E,A - CALL GETSETUC ;and set it. - CALL RESDSK ;reset the disk system. - LD (BATCH),A ;clear batch mode flag. - POP BC - LD A,C - AND 0FH ;isolate the drive number. - LD (CDRIVE),A ;and save. - CALL DSKSEL ;...and select. - LD A,(INBUFF+1) - OR A ;anything in input buffer already? - JP NZ,CMMND2 ;yes, we just process it. -; -; Entry point to get a command line from the console. -; -CMMND1: LD SP,CCPSTACK ;set stack straight. - CALL CRLF ;start a new line on the screen. - CALL GETDSK ;get current drive. - ADD A,'A' - CALL PRINT ;print current drive. - LD A,'>' - CALL PRINT ;and add prompt. - CALL GETINP ;get line from user. -; -; Process command line here. -; -CMMND2: LD DE,TBUFF - CALL DMASET ;set standard dma address. - CALL GETDSK - LD (CDRIVE),A ;set current drive. - CALL CONVFST ;convert name typed in. - CALL NZ,SYNERR ;wild cards are not allowed. - LD A,(CHGDRV) ;if a change in drives was indicated, - OR A ;then treat this as an unknown command - JP NZ,UNKNOWN ;which gets executed. - CALL SEARCH ;else search command table for a match. -; -; Note that an unknown command returns -; with (A) pointing to the last address -; in our table which is (UNKNOWN). -; - LD HL,CMDADR ;now, look thru our address table for command (A). - LD E,A ;set (DE) to command number. - LD D,0 - ADD HL,DE - ADD HL,DE ;(HL)=(CMDADR)+2*(command number). - LD A,(HL) ;now pick out this address. - INC HL - LD H,(HL) - LD L,A - JP (HL) ;now execute it. -; -; CP/M command address table. -; -CMDADR: DEFW DIRECT,ERASE,TYPE,SAVE - DEFW RENAME,USER,UNKNOWN -; -; Halt the system. Reason for this is unknown at present. -; -HALT: LD HL,76F3H ;'DI HLT' instructions. - LD (CBASE),HL - LD HL,CBASE - JP (HL) -; -; Read error while TYPEing a file. -; -RDERROR:LD BC,RDERR - JP PLINE -RDERR: DEFB "Read error",0 -; -; Required file was not located. -; -NONE: LD BC,NOFILE - JP PLINE -NOFILE: DEFB "No file",0 -; -; Decode a command of the form 'A>filename number{ filename}. -; Note that a drive specifier is not allowed on the first file -; name. On return, the number is in register (A). Any error -; causes 'filename?' to be printed and the command is aborted. -; -DECODE: CALL CONVFST ;convert filename. - LD A,(CHGDRV) ;do not allow a drive to be specified. - OR A - JP NZ,SYNERR - LD HL,FCB+1 ;convert number now. - LD BC,11 ;(B)=sum register, (C)=max digit count. -DECODE1:LD A,(HL) - CP ' ' ;a space terminates the numeral. - JP Z,DECODE3 - INC HL - SUB '0' ;make binary from ascii. - CP 10 ;legal digit? - JP NC,SYNERR - LD D,A ;yes, save it in (D). - LD A,B ;compute (B)=(B)*10 and check for overflow. - AND 0E0H - JP NZ,SYNERR - LD A,B - RLCA - RLCA - RLCA ;(A)=(B)*8 - ADD A,B ;.......*9 - JP C,SYNERR - ADD A,B ;.......*10 - JP C,SYNERR - ADD A,D ;add in new digit now. -DECODE2:JP C,SYNERR - LD B,A ;and save result. - DEC C ;only look at 11 digits. - JP NZ,DECODE1 - RET -DECODE3:LD A,(HL) ;spaces must follow (why?). - CP ' ' - JP NZ,SYNERR - INC HL -DECODE4:DEC C - JP NZ,DECODE3 - LD A,B ;set (A)=the numeric value entered. - RET -; -; Move 3 bytes from (HL) to (DE). Note that there is only -; one reference to this at (A2D5h). -; -MOVE3: LD B,3 -; -; Move (B) bytes from (HL) to (DE). -; -HL2DE: LD A,(HL) - LD (DE),A - INC HL - INC DE - DEC B - JP NZ,HL2DE - RET -; -; Compute (HL)=(TBUFF)+(A)+(C) and get the byte that's here. -; -EXTRACT:LD HL,TBUFF - ADD A,C - CALL ADDHL - LD A,(HL) - RET -; -; Check drive specified. If it means a change, then the new -; drive will be selected. In any case, the drive byte of the -; fcb will be set to null (means use current drive). -; -DSELECT:XOR A ;null out first byte of fcb. - LD (FCB),A - LD A,(CHGDRV) ;a drive change indicated? - OR A - RET Z - DEC A ;yes, is it the same as the current drive? - LD HL,CDRIVE - CP (HL) - RET Z - JP DSKSEL ;no. Select it then. -; -; Check the drive selection and reset it to the previous -; drive if it was changed for the preceeding command. -; -RESETDR:LD A,(CHGDRV) ;drive change indicated? - OR A - RET Z - DEC A ;yes, was it a different drive? - LD HL,CDRIVE - CP (HL) - RET Z - LD A,(CDRIVE) ;yes, re-select our old drive. - JP DSKSEL -; -;************************************************************** -;* -;* D I R E C T O R Y C O M M A N D -;* -;************************************************************** -; -DIRECT: CALL CONVFST ;convert file name. - CALL DSELECT ;select indicated drive. - LD HL,FCB+1 ;was any file indicated? - LD A,(HL) - CP ' ' - JP NZ,DIRECT2 - LD B,11 ;no. Fill field with '?' - same as *.*. -DIRECT1:LD (HL),'?' - INC HL - DEC B - JP NZ,DIRECT1 -DIRECT2:LD E,0 ;set initial cursor position. - PUSH DE - CALL SRCHFCB ;get first file name. - CALL Z,NONE ;none found at all? -DIRECT3:JP Z,DIRECT9 ;terminate if no more names. - LD A,(RTNCODE) ;get file's position in segment (0-3). - RRCA - RRCA - RRCA - AND 60H ;(A)=position*32 - LD C,A - LD A,10 - CALL EXTRACT ;extract the tenth entry in fcb. - RLA ;check system file status bit. - JP C,DIRECT8 ;we don't list them. - POP DE - LD A,E ;bump name count. - INC E - PUSH DE - AND 03H ;at end of line? - PUSH AF - JP NZ,DIRECT4 - CALL CRLF ;yes, end this line and start another. - PUSH BC - CALL GETDSK ;start line with ('A:'). - POP BC - ADD A,'A' - CALL PRINTB - LD A,':' - CALL PRINTB - JP DIRECT5 -DIRECT4:CALL SPACE ;add seperator between file names. - LD A,':' - CALL PRINTB -DIRECT5:CALL SPACE - LD B,1 ;'extract' each file name character at a time. -DIRECT6:LD A,B - CALL EXTRACT - AND 7FH ;strip bit 7 (status bit). - CP ' ' ;are we at the end of the name? - JP NZ,DRECT65 - POP AF ;yes, don't print spaces at the end of a line. - PUSH AF - CP 3 - JP NZ,DRECT63 - LD A,9 ;first check for no extension. - CALL EXTRACT - AND 7FH - CP ' ' - JP Z,DIRECT7 ;don't print spaces. -DRECT63:LD A,' ' ;else print them. -DRECT65:CALL PRINTB - INC B ;bump to next character psoition. - LD A,B - CP 12 ;end of the name? - JP NC,DIRECT7 - CP 9 ;nope, starting extension? - JP NZ,DIRECT6 - CALL SPACE ;yes, add seperating space. - JP DIRECT6 -DIRECT7:POP AF ;get the next file name. -DIRECT8:CALL CHKCON ;first check console, quit on anything. - JP NZ,DIRECT9 - CALL SRCHNXT ;get next name. - JP DIRECT3 ;and continue with our list. -DIRECT9:POP DE ;restore the stack and return to command level. - JP GETBACK -; -;************************************************************** -;* -;* E R A S E C O M M A N D -;* -;************************************************************** -; -ERASE: CALL CONVFST ;convert file name. - CP 11 ;was '*.*' entered? - JP NZ,ERASE1 - LD BC,YESNO ;yes, ask for confirmation. - CALL PLINE - CALL GETINP - LD HL,INBUFF+1 - DEC (HL) ;must be exactly 'y'. - JP NZ,CMMND1 - INC HL - LD A,(HL) - CP 'Y' - JP NZ,CMMND1 - INC HL - LD (INPOINT),HL ;save input line pointer. -ERASE1: CALL DSELECT ;select desired disk. - LD DE,FCB - CALL DELETE ;delete the file. - INC A - CALL Z,NONE ;not there? - JP GETBACK ;return to command level now. -YESNO: DEFB "All (y/n)?",0 -; -;************************************************************** -;* -;* T Y P E C O M M A N D -;* -;************************************************************** -; -TYPE: CALL CONVFST ;convert file name. - JP NZ,SYNERR ;wild cards not allowed. - CALL DSELECT ;select indicated drive. - CALL OPENFCB ;open the file. - JP Z,TYPE5 ;not there? - CALL CRLF ;ok, start a new line on the screen. - LD HL,NBYTES ;initialize byte counter. - LD (HL),0FFH ;set to read first sector. -TYPE1: LD HL,NBYTES -TYPE2: LD A,(HL) ;have we written the entire sector? - CP 128 - JP C,TYPE3 - PUSH HL ;yes, read in the next one. - CALL READFCB - POP HL - JP NZ,TYPE4 ;end or error? - XOR A ;ok, clear byte counter. - LD (HL),A -TYPE3: INC (HL) ;count this byte. - LD HL,TBUFF ;and get the (A)th one from the buffer (TBUFF). - CALL ADDHL - LD A,(HL) - CP CNTRLZ ;end of file mark? - JP Z,GETBACK - CALL PRINT ;no, print it. - CALL CHKCON ;check console, quit if anything ready. - JP NZ,GETBACK - JP TYPE1 -; -; Get here on an end of file or read error. -; -TYPE4: DEC A ;read error? - JP Z,GETBACK - CALL RDERROR ;yes, print message. -TYPE5: CALL RESETDR ;and reset proper drive - JP SYNERR ;now print file name with problem. -; -;************************************************************** -;* -;* S A V E C O M M A N D -;* -;************************************************************** -; -SAVE: CALL DECODE ;get numeric number that follows SAVE. - PUSH AF ;save number of pages to write. - CALL CONVFST ;convert file name. - JP NZ,SYNERR ;wild cards not allowed. - CALL DSELECT ;select specified drive. - LD DE,FCB ;now delete this file. - PUSH DE - CALL DELETE - POP DE - CALL CREATE ;and create it again. - JP Z,SAVE3 ;can't create? - XOR A ;clear record number byte. - LD (FCB+32),A - POP AF ;convert pages to sectors. - LD L,A - LD H,0 - ADD HL,HL ;(HL)=number of sectors to write. - LD DE,TBASE ;and we start from here. -SAVE1: LD A,H ;done yet? - OR L - JP Z,SAVE2 - DEC HL ;nope, count this and compute the start - PUSH HL ;of the next 128 byte sector. - LD HL,128 - ADD HL,DE - PUSH HL ;save it and set the transfer address. - CALL DMASET - LD DE,FCB ;write out this sector now. - CALL WRTREC - POP DE ;reset (DE) to the start of the last sector. - POP HL ;restore sector count. - JP NZ,SAVE3 ;write error? - JP SAVE1 -; -; Get here after writing all of the file. -; -SAVE2: LD DE,FCB ;now close the file. - CALL CLOSE - INC A ;did it close ok? - JP NZ,SAVE4 -; -; Print out error message (no space). -; -SAVE3: LD BC,NOSPACE - CALL PLINE -SAVE4: CALL STDDMA ;reset the standard dma address. - JP GETBACK -NOSPACE:DEFB "No space",0 -; -;************************************************************** -;* -;* R E N A M E C O M M A N D -;* -;************************************************************** -; -RENAME: CALL CONVFST ;convert first file name. - JP NZ,SYNERR ;wild cards not allowed. - LD A,(CHGDRV) ;remember any change in drives specified. - PUSH AF - CALL DSELECT ;and select this drive. - CALL SRCHFCB ;is this file present? - JP NZ,RENAME6 ;yes, print error message. - LD HL,FCB ;yes, move this name into second slot. - LD DE,FCB+16 - LD B,16 - CALL HL2DE - LD HL,(INPOINT) ;get input pointer. - EX DE,HL - CALL NONBLANK ;get next non blank character. - CP '=' ;only allow an '=' or '_' seperator. - JP Z,RENAME1 - CP '_' - JP NZ,RENAME5 -RENAME1:EX DE,HL - INC HL ;ok, skip seperator. - LD (INPOINT),HL ;save input line pointer. - CALL CONVFST ;convert this second file name now. - JP NZ,RENAME5 ;again, no wild cards. - POP AF ;if a drive was specified, then it - LD B,A ;must be the same as before. - LD HL,CHGDRV - LD A,(HL) - OR A - JP Z,RENAME2 - CP B - LD (HL),B - JP NZ,RENAME5 ;they were different, error. -RENAME2:LD (HL),B ; reset as per the first file specification. - XOR A - LD (FCB),A ;clear the drive byte of the fcb. -RENAME3:CALL SRCHFCB ;and go look for second file. - JP Z,RENAME4 ;doesn't exist? - LD DE,FCB - CALL RENAM ;ok, rename the file. - JP GETBACK -; -; Process rename errors here. -; -RENAME4:CALL NONE ;file not there. - JP GETBACK -RENAME5:CALL RESETDR ;bad command format. - JP SYNERR -RENAME6:LD BC,EXISTS ;destination file already exists. - CALL PLINE - JP GETBACK -EXISTS: DEFB "File exists",0 -; -;************************************************************** -;* -;* U S E R C O M M A N D -;* -;************************************************************** -; -USER: CALL DECODE ;get numeric value following command. - CP 16 ;legal user number? - JP NC,SYNERR - LD E,A ;yes but is there anything else? - LD A,(FCB+1) - CP ' ' - JP Z,SYNERR ;yes, that is not allowed. - CALL GETSETUC ;ok, set user code. - JP GETBACK1 -; -;************************************************************** -;* -;* T R A N S I A N T P R O G R A M C O M M A N D -;* -;************************************************************** -; -UNKNOWN:CALL VERIFY ;check for valid system (why?). - LD A,(FCB+1) ;anything to execute? - CP ' ' - JP NZ,UNKWN1 - LD A,(CHGDRV) ;nope, only a drive change? - OR A - JP Z,GETBACK1 ;neither??? - DEC A - LD (CDRIVE),A ;ok, store new drive. - CALL MOVECD ;set (TDRIVE) also. - CALL DSKSEL ;and select this drive. - JP GETBACK1 ;then return. -; -; Here a file name was typed. Prepare to execute it. -; -UNKWN1: LD DE,FCB+9 ;an extension specified? - LD A,(DE) - CP ' ' - JP NZ,SYNERR ;yes, not allowed. -UNKWN2: PUSH DE - CALL DSELECT ;select specified drive. - POP DE - LD HL,COMFILE ;set the extension to 'COM'. - CALL MOVE3 - CALL OPENFCB ;and open this file. - JP Z,UNKWN9 ;not present? -; -; Load in the program. -; - LD HL,TBASE ;store the program starting here. -UNKWN3: PUSH HL - EX DE,HL - CALL DMASET ;set transfer address. - LD DE,FCB ;and read the next record. - CALL RDREC - JP NZ,UNKWN4 ;end of file or read error? - POP HL ;nope, bump pointer for next sector. - LD DE,128 - ADD HL,DE - LD DE,CBASE ;enough room for the whole file? - LD A,L - SUB E - LD A,H - SBC A,D - JP NC,UNKWN0 ;no, it can't fit. - JP UNKWN3 -; -; Get here after finished reading. -; -UNKWN4: POP HL - DEC A ;normal end of file? - JP NZ,UNKWN0 - CALL RESETDR ;yes, reset previous drive. - CALL CONVFST ;convert the first file name that follows - LD HL,CHGDRV ;command name. - PUSH HL - LD A,(HL) ;set drive code in default fcb. - LD (FCB),A - LD A,16 ;put second name 16 bytes later. - CALL CONVERT ;convert second file name. - POP HL - LD A,(HL) ;and set the drive for this second file. - LD (FCB+16),A - XOR A ;clear record byte in fcb. - LD (FCB+32),A - LD DE,TFCB ;move it into place at(005Ch). - LD HL,FCB - LD B,33 - CALL HL2DE - LD HL,INBUFF+2 ;now move the remainder of the input -UNKWN5: LD A,(HL) ;line down to (0080h). Look for a non blank. - OR A ;or a null. - JP Z,UNKWN6 - CP ' ' - JP Z,UNKWN6 - INC HL - JP UNKWN5 -; -; Do the line move now. It ends in a null byte. -; -UNKWN6: LD B,0 ;keep a character count. - LD DE,TBUFF+1 ;data gets put here. -UNKWN7: LD A,(HL) ;move it now. - LD (DE),A - OR A - JP Z,UNKWN8 - INC B - INC HL - INC DE - JP UNKWN7 -UNKWN8: LD A,B ;now store the character count. - LD (TBUFF),A - CALL CRLF ;clean up the screen. - CALL STDDMA ;set standard transfer address. - CALL SETCDRV ;reset current drive. - CALL TBASE ;and execute the program. -; -; Transiant programs return here (or reboot). -; - LD SP,BATCH ;set stack first off. - CALL MOVECD ;move current drive into place (TDRIVE). - CALL DSKSEL ;and reselect it. - JP CMMND1 ;back to comand mode. -; -; Get here if some error occured. -; -UNKWN9: CALL RESETDR ;inproper format. - JP SYNERR -UNKWN0: LD BC,BADLOAD ;read error or won't fit. - CALL PLINE - JP GETBACK -BADLOAD:DEFB "Bad load",0 -COMFILE:DEFB "COM" ;command file extension. -; -; Get here to return to command level. We will reset the -; previous active drive and then either return to command -; level directly or print error message and then return. -; -GETBACK:CALL RESETDR ;reset previous drive. -GETBACK1: CALL CONVFST ;convert first name in (FCB). - LD A,(FCB+1) ;if this was just a drive change request, - SUB ' ' ;make sure it was valid. - LD HL,CHGDRV - OR (HL) - JP NZ,SYNERR - JP CMMND1 ;ok, return to command level. -; -; ccp stack area. -; - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -CCPSTACK EQU $ ;end of ccp stack area. -; -; Batch (or SUBMIT) processing information storage. -; -BATCH: DEFB 0 ;batch mode flag (0=not active). -BATCHFCB: DEFB 0 - TEXT "$$$ SUB" - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; File control block setup by the CCP. -; -FCB: DEFB 0 - TEXT " " - DEFB 0,0,0,0,0, - TEXT " " - DEFB 0,0,0,0,0 -RTNCODE:DEFB 0 ;status returned from bdos call. -CDRIVE: DEFB 0 ;currently active drive. -CHGDRV: DEFB 0 ;change in drives flag (0=no change). -NBYTES: DEFW 0 ;byte counter used by TYPE. -; -; Room for expansion? -; - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; Note that the following six bytes must match those at -; (PATTRN1) or cp/m will HALT. Why? -; -PATTRN2:DEFB 0,22,0,0,0,0 ;(* serial number bytes *). -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE: JP FBASE1 -; -; Bdos error table. -; -BADSCTR:DEFW ERROR1 ;bad sector on read or write. -BADSLCT:DEFW ERROR2 ;bad disk select. -RODISK: DEFW ERROR3 ;disk is read only. -ROFILE: DEFW ERROR4 ;file is read only. -; -; Entry into bdos. (DE) or (E) are the parameters passed. The -; function number desired is in register (C). -; -FBASE1: EX DE,HL ;save the (DE) parameters. - LD (PARAMS),HL - EX DE,HL - LD A,E ;and save register (E) in particular. - LD (EPARAM),A - LD HL,0 - LD (STATUS),HL ;clear return status. - ADD HL,SP - LD (USRSTACK),HL ;save users stack pointer. - LD SP,STKAREA ;and set our own. - XOR A ;clear auto select storage space. - LD (AUTOFLAG),A - LD (AUTO),A - LD HL,GOBACK ;set return address. - PUSH HL - LD A,C ;get function number. - CP NFUNCTS ;valid function number? - RET NC - LD C,E ;keep single register function here. - LD HL,FUNCTNS ;now look thru the function table. - LD E,A - LD D,0 ;(DE)=function number. - ADD HL,DE - ADD HL,DE ;(HL)=(start of table)+2*(function number). - LD E,(HL) - INC HL - LD D,(HL) ;now (DE)=address for this function. - LD HL,(PARAMS) ;retrieve parameters. - EX DE,HL ;now (DE) has the original parameters. - JP (HL) ;execute desired function. -; -; BDOS function jump table. -; -NFUNCTS EQU 41 ;number of functions in followin table. -; -FUNCTNS:DEFW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - DEFW SETIOB,PRTSTR,RDBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - DEFW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - DEFW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - DEFW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - DEFW RTN,WTSPECL -; -; Bdos error message section. -; -ERROR1: LD HL,BADSEC ;bad sector message. - CALL PRTERR ;print it and get a 1 char responce. - CP CNTRLC ;re-boot request (control-c)? - JP Z,0 ;yes. - RET ;no, return to retry i/o function. -; -ERROR2: LD HL,BADSEL ;bad drive selected. - JP ERROR5 -; -ERROR3: LD HL,DISKRO ;disk is read only. - JP ERROR5 -; -ERROR4: LD HL,FILERO ;file is read only. -; -ERROR5: CALL PRTERR - JP 0 ;always reboot on these errors. -; -BDOSERR:DEFB "Bdos Err On " -BDOSDRV:DEFB " : $" -BADSEC: DEFB "Bad Sector$" -BADSEL: DEFB "Select$" -FILERO: DEFB "File " -DISKRO: DEFB "R/O$" -; -; Print bdos error message. -; -PRTERR: PUSH HL ;save second message pointer. - CALL OUTCRLF ;send (cr)(lf). - LD A,(ACTIVE) ;get active drive. - ADD A,'A' ;make ascii. - LD (BDOSDRV),A ;and put in message. - LD BC,BDOSERR ;and print it. - CALL PRTMESG - POP BC ;print second message line now. - CALL PRTMESG -; -; Get an input character. We will check our 1 character -; buffer first. This may be set by the console status routine. -; -GETCHAR:LD HL,CHARBUF ;check character buffer. - LD A,(HL) ;anything present already? - LD (HL),0 ;...either case clear it. - OR A - RET NZ ;yes, use it. - JP CONIN ;nope, go get a character responce. -; -; Input and echo a character. -; -GETECHO:CALL GETCHAR ;input a character. - CALL CHKCHAR ;carriage control? - RET C ;no, a regular control char so don't echo. - PUSH AF ;ok, save character now. - LD C,A - CALL OUTCON ;and echo it. - POP AF ;get character and return. - RET -; -; Check character in (A). Set the zero flag on a carriage -; control character and the carry flag on any other control -; character. -; -CHKCHAR:CP CR ;check for carriage return, line feed, backspace, - RET Z ;or a tab. - CP LF - RET Z - CP TAB - RET Z - CP BS - RET Z - CP ' ' ;other control char? Set carry flag. - RET -; -; Check the console during output. Halt on a control-s, then -; reboot on a control-c. If anything else is ready, clear the -; zero flag and return (the calling routine may want to do -; something). -; -CKCONSOL: LD A,(CHARBUF) ;check buffer. - OR A ;if anything, just return without checking. - JP NZ,CKCON2 - CALL CONST ;nothing in buffer. Check console. - AND 01H ;look at bit 0. - RET Z ;return if nothing. - CALL CONIN ;ok, get it. - CP CNTRLS ;if not control-s, return with zero cleared. - JP NZ,CKCON1 - CALL CONIN ;halt processing until another char - CP CNTRLC ;is typed. Control-c? - JP Z,0 ;yes, reboot now. - XOR A ;no, just pretend nothing was ever ready. - RET -CKCON1: LD (CHARBUF),A ;save character in buffer for later processing. -CKCON2: LD A,1 ;set (A) to non zero to mean something is ready. - RET -; -; Output (C) to the screen. If the printer flip-flop flag -; is set, we will send character to printer also. The console -; will be checked in the process. -; -OUTCHAR:LD A,(OUTFLAG) ;check output flag. - OR A ;anything and we won't generate output. - JP NZ,OUTCHR1 - PUSH BC - CALL CKCONSOL ;check console (we don't care whats there). - POP BC - PUSH BC - CALL CONOUT ;output (C) to the screen. - POP BC - PUSH BC - LD A,(PRTFLAG) ;check printer flip-flop flag. - OR A - CALL NZ,LIST ;print it also if non-zero. - POP BC -OUTCHR1:LD A,C ;update cursors position. - LD HL,CURPOS - CP DEL ;rubouts don't do anything here. - RET Z - INC (HL) ;bump line pointer. - CP ' ' ;and return if a normal character. - RET NC - DEC (HL) ;restore and check for the start of the line. - LD A,(HL) - OR A - RET Z ;ingnore control characters at the start of the line. - LD A,C - CP BS ;is it a backspace? - JP NZ,OUTCHR2 - DEC (HL) ;yes, backup pointer. - RET -OUTCHR2:CP LF ;is it a line feed? - RET NZ ;ignore anything else. - LD (HL),0 ;reset pointer to start of line. - RET -; -; Output (A) to the screen. If it is a control character -; (other than carriage control), use ^x format. -; -SHOWIT: LD A,C - CALL CHKCHAR ;check character. - JP NC,OUTCON ;not a control, use normal output. - PUSH AF - LD C,'^' ;for a control character, preceed it with '^'. - CALL OUTCHAR - POP AF - OR '@' ;and then use the letter equivelant. - LD C,A -; -; Function to output (C) to the console device and expand tabs -; if necessary. -; -OUTCON: LD A,C - CP TAB ;is it a tab? - JP NZ,OUTCHAR ;use regular output. -OUTCON1:LD C,' ' ;yes it is, use spaces instead. - CALL OUTCHAR - LD A,(CURPOS) ;go until the cursor is at a multiple of 8 - - AND 07H ;position. - JP NZ,OUTCON1 - RET -; -; Echo a backspace character. Erase the prevoius character -; on the screen. -; -BACKUP: CALL BACKUP1 ;backup the screen 1 place. - LD C,' ' ;then blank that character. - CALL CONOUT -BACKUP1:LD C,BS ;then back space once more. - JP CONOUT -; -; Signal a deleted line. Print a '#' at the end and start -; over. -; -NEWLINE:LD C,'#' - CALL OUTCHAR ;print this. - CALL OUTCRLF ;start new line. -NEWLN1: LD A,(CURPOS) ;move the cursor to the starting position. - LD HL,STARTING - CP (HL) - RET NC ;there yet? - LD C,' ' - CALL OUTCHAR ;nope, keep going. - JP NEWLN1 -; -; Output a (cr) (lf) to the console device (screen). -; -OUTCRLF:LD C,CR - CALL OUTCHAR - LD C,LF - JP OUTCHAR -; -; Print message pointed to by (BC). It will end with a '$'. -; -PRTMESG:LD A,(BC) ;check for terminating character. - CP '$' - RET Z - INC BC - PUSH BC ;otherwise, bump pointer and print it. - LD C,A - CALL OUTCON - POP BC - JP PRTMESG -; -; Function to execute a buffered read. -; -RDBUFF: LD A,(CURPOS) ;use present location as starting one. - LD (STARTING),A - LD HL,(PARAMS) ;get the maximum buffer space. - LD C,(HL) - INC HL ;point to first available space. - PUSH HL ;and save. - LD B,0 ;keep a character count. -RDBUF1: PUSH BC - PUSH HL -RDBUF2: CALL GETCHAR ;get the next input character. - AND 7FH ;strip bit 7. - POP HL ;reset registers. - POP BC - CP CR ;en of the line? - JP Z,RDBUF17 - CP LF - JP Z,RDBUF17 - CP BS ;how about a backspace? - JP NZ,RDBUF3 - LD A,B ;yes, but ignore at the beginning of the line. - OR A - JP Z,RDBUF1 - DEC B ;ok, update counter. - LD A,(CURPOS) ;if we backspace to the start of the line, - LD (OUTFLAG),A ;treat as a cancel (control-x). - JP RDBUF10 -RDBUF3: CP DEL ;user typed a rubout? - JP NZ,RDBUF4 - LD A,B ;ignore at the start of the line. - OR A - JP Z,RDBUF1 - LD A,(HL) ;ok, echo the prevoius character. - DEC B ;and reset pointers (counters). - DEC HL - JP RDBUF15 -RDBUF4: CP CNTRLE ;physical end of line? - JP NZ,RDBUF5 - PUSH BC ;yes, do it. - PUSH HL - CALL OUTCRLF - XOR A ;and update starting position. - LD (STARTING),A - JP RDBUF2 -RDBUF5: CP CNTRLP ;control-p? - JP NZ,RDBUF6 - PUSH HL ;yes, flip the print flag filp-flop byte. - LD HL,PRTFLAG - LD A,1 ;PRTFLAG=1-PRTFLAG - SUB (HL) - LD (HL),A - POP HL - JP RDBUF1 -RDBUF6: CP CNTRLX ;control-x (cancel)? - JP NZ,RDBUF8 - POP HL -RDBUF7: LD A,(STARTING) ;yes, backup the cursor to here. - LD HL,CURPOS - CP (HL) - JP NC,RDBUFF ;done yet? - DEC (HL) ;no, decrement pointer and output back up one space. - CALL BACKUP - JP RDBUF7 -RDBUF8: CP CNTRLU ;cntrol-u (cancel line)? - JP NZ,RDBUF9 - CALL NEWLINE ;start a new line. - POP HL - JP RDBUFF -RDBUF9: CP CNTRLR ;control-r? - JP NZ,RDBUF14 -RDBUF10:PUSH BC ;yes, start a new line and retype the old one. - CALL NEWLINE - POP BC - POP HL - PUSH HL - PUSH BC -RDBUF11:LD A,B ;done whole line yet? - OR A - JP Z,RDBUF12 - INC HL ;nope, get next character. - LD C,(HL) - DEC B ;count it. - PUSH BC - PUSH HL - CALL SHOWIT ;and display it. - POP HL - POP BC - JP RDBUF11 -RDBUF12:PUSH HL ;done with line. If we were displaying - LD A,(OUTFLAG) ;then update cursor position. - OR A - JP Z,RDBUF2 - LD HL,CURPOS ;because this line is shorter, we must - SUB (HL) ;back up the cursor (not the screen however) - LD (OUTFLAG),A ;some number of positions. -RDBUF13:CALL BACKUP ;note that as long as (OUTFLAG) is non - LD HL,OUTFLAG ;zero, the screen will not be changed. - DEC (HL) - JP NZ,RDBUF13 - JP RDBUF2 ;now just get the next character. -; -; Just a normal character, put this in our buffer and echo. -; -RDBUF14:INC HL - LD (HL),A ;store character. - INC B ;and count it. -RDBUF15:PUSH BC - PUSH HL - LD C,A ;echo it now. - CALL SHOWIT - POP HL - POP BC - LD A,(HL) ;was it an abort request? - CP CNTRLC ;control-c abort? - LD A,B - JP NZ,RDBUF16 - CP 1 ;only if at start of line. - JP Z,0 -RDBUF16:CP C ;nope, have we filled the buffer? - JP C,RDBUF1 -RDBUF17:POP HL ;yes end the line and return. - LD (HL),B - LD C,CR - JP OUTCHAR ;output (cr) and return. -; -; Function to get a character from the console device. -; -GETCON: CALL GETECHO ;get and echo. - JP SETSTAT ;save status and return. -; -; Function to get a character from the tape reader device. -; -GETRDR: CALL READER ;get a character from reader, set status and return. - JP SETSTAT -; -; Function to perform direct console i/o. If (C) contains (FF) -; then this is an input request. If (C) contains (FE) then -; this is a status request. Otherwise we are to output (C). -; -DIRCIO: LD A,C ;test for (FF). - INC A - JP Z,DIRC1 - INC A ;test for (FE). - JP Z,CONST - JP CONOUT ;just output (C). -DIRC1: CALL CONST ;this is an input request. - OR A - JP Z,GOBACK1 ;not ready? Just return (directly). - CALL CONIN ;yes, get character. - JP SETSTAT ;set status and return. -; -; Function to return the i/o byte. -; -GETIOB: LD A,(IOBYTE) - JP SETSTAT -; -; Function to set the i/o byte. -; -SETIOB: LD HL,IOBYTE - LD (HL),C - RET -; -; Function to print the character string pointed to by (DE) -; on the console device. The string ends with a '$'. -; -PRTSTR: EX DE,HL - LD C,L - LD B,H ;now (BC) points to it. - JP PRTMESG -; -; Function to interigate the console device. -; -GETCSTS:CALL CKCONSOL -; -; Get here to set the status and return to the cleanup -; section. Then back to the user. -; -SETSTAT:LD (STATUS),A -RTN: RET -; -; Set the status to 1 (read or write error code). -; -IOERR1: LD A,1 - JP SETSTAT -; -OUTFLAG:DEFB 0 ;output flag (non zero means no output). -STARTING: DEFB 2 ;starting position for cursor. -CURPOS: DEFB 0 ;cursor position (0=start of line). -PRTFLAG:DEFB 0 ;printer flag (control-p toggle). List if non zero. -CHARBUF:DEFB 0 ;single input character buffer. -; -; Stack area for BDOS calls. -; -USRSTACK: DEFW 0 ;save users stack pointer here. -; - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA EQU $ ;end of stack area. -; -USERNO: DEFB 0 ;current user number. -ACTIVE: DEFB 0 ;currently active drive. -PARAMS: DEFW 0 ;save (DE) parameters here on entry. -STATUS: DEFW 0 ;status returned from bdos function. -; -; Select error occured, jump to error routine. -; -SLCTERR:LD HL,BADSLCT -; -; Jump to (HL) indirectly. -; -JUMPHL: LD E,(HL) - INC HL - LD D,(HL) ;now (DE) contain the desired address. - EX DE,HL - JP (HL) -; -; Block move. (DE) to (HL), (C) bytes total. -; -DE2HL: INC C ;is count down to zero? -DE2HL1: DEC C - RET Z ;yes, we are done. - LD A,(DE) ;no, move one more byte. - LD (HL),A - INC DE - INC HL - JP DE2HL1 ;and repeat. -; -; Select the desired drive. -; -SELECT: LD A,(ACTIVE) ;get active disk. - LD C,A - CALL SELDSK ;select it. - LD A,H ;valid drive? - OR L ;valid drive? - RET Z ;return if not. -; -; Here, the BIOS returned the address of the parameter block -; in (HL). We will extract the necessary pointers and save them. -; - LD E,(HL) ;yes, get address of translation table into (DE). - INC HL - LD D,(HL) - INC HL - LD (SCRATCH1),HL ;save pointers to scratch areas. - INC HL - INC HL - LD (SCRATCH2),HL ;ditto. - INC HL - INC HL - LD (SCRATCH3),HL ;ditto. - INC HL - INC HL - EX DE,HL ;now save the translation table address. - LD (XLATE),HL - LD HL,DIRBUF ;put the next 8 bytes here. - LD C,8 ;they consist of the directory buffer - CALL DE2HL ;pointer, parameter block pointer, - LD HL,(DISKPB) ;check and allocation vectors. - EX DE,HL - LD HL,SECTORS ;move parameter block into our ram. - LD C,15 ;it is 15 bytes long. - CALL DE2HL - LD HL,(DSKSIZE) ;check disk size. - LD A,H ;more than 256 blocks on this? - LD HL,BIGDISK - LD (HL),0FFH ;set to samll. - OR A - JP Z,SELECT1 - LD (HL),0 ;wrong, set to large. -SELECT1:LD A,0FFH ;clear the zero flag. - OR A - RET -; -; Routine to home the disk track head and clear pointers. -; -HOMEDRV:CALL HOME ;home the head. - XOR A - LD HL,(SCRATCH2) ;set our track pointer also. - LD (HL),A - INC HL - LD (HL),A - LD HL,(SCRATCH3) ;and our sector pointer. - LD (HL),A - INC HL - LD (HL),A - RET -; -; Do the actual disk read and check the error return status. -; -DOREAD: CALL READ - JP IORET -; -; Do the actual disk write and handle any bios error. -; -DOWRITE:CALL WRITE -IORET: OR A - RET Z ;return unless an error occured. - LD HL,BADSCTR ;bad read/write on this sector. - JP JUMPHL -; -; Routine to select the track and sector that the desired -; block number falls in. -; -TRKSEC: LD HL,(FILEPOS) ;get position of last accessed file - LD C,2 ;in directory and compute sector #. - CALL SHIFTR ;sector #=file-position/4. - LD (BLKNMBR),HL ;save this as the block number of interest. - LD (CKSUMTBL),HL ;what's it doing here too? -; -; if the sector number has already been set (BLKNMBR), enter -; at this point. -; -TRKSEC1:LD HL,BLKNMBR - LD C,(HL) ;move sector number into (BC). - INC HL - LD B,(HL) - LD HL,(SCRATCH3) ;get current sector number and - LD E,(HL) ;move this into (DE). - INC HL - LD D,(HL) - LD HL,(SCRATCH2) ;get current track number. - LD A,(HL) ;and this into (HL). - INC HL - LD H,(HL) - LD L,A -TRKSEC2:LD A,C ;is desired sector before current one? - SUB E - LD A,B - SBC A,D - JP NC,TRKSEC3 - PUSH HL ;yes, decrement sectors by one track. - LD HL,(SECTORS) ;get sectors per track. - LD A,E - SUB L - LD E,A - LD A,D - SBC A,H - LD D,A ;now we have backed up one full track. - POP HL - DEC HL ;adjust track counter. - JP TRKSEC2 -TRKSEC3:PUSH HL ;desired sector is after current one. - LD HL,(SECTORS) ;get sectors per track. - ADD HL,DE ;bump sector pointer to next track. - JP C,TRKSEC4 - LD A,C ;is desired sector now before current one? - SUB L - LD A,B - SBC A,H - JP C,TRKSEC4 - EX DE,HL ;not yes, increment track counter - POP HL ;and continue until it is. - INC HL - JP TRKSEC3 -; -; here we have determined the track number that contains the -; desired sector. -; -TRKSEC4:POP HL ;get track number (HL). - PUSH BC - PUSH DE - PUSH HL - EX DE,HL - LD HL,(OFFSET) ;adjust for first track offset. - ADD HL,DE - LD B,H - LD C,L - CALL SETTRK ;select this track. - POP DE ;reset current track pointer. - LD HL,(SCRATCH2) - LD (HL),E - INC HL - LD (HL),D - POP DE - LD HL,(SCRATCH3) ;reset the first sector on this track. - LD (HL),E - INC HL - LD (HL),D - POP BC - LD A,C ;now subtract the desired one. - SUB E ;to make it relative (1-# sectors/track). - LD C,A - LD A,B - SBC A,D - LD B,A - LD HL,(XLATE) ;translate this sector according to this table. - EX DE,HL - CALL SECTRN ;let the bios translate it. - LD C,L - LD B,H - JP SETSEC ;and select it. -; -; Compute block number from record number (SAVNREC) and -; extent number (SAVEXT). -; -GETBLOCK: LD HL,BLKSHFT ;get logical to physical conversion. - LD C,(HL) ;note that this is base 2 log of ratio. - LD A,(SAVNREC) ;get record number. -GETBLK1:OR A ;compute (A)=(A)/2^BLKSHFT. - RRA - DEC C - JP NZ,GETBLK1 - LD B,A ;save result in (B). - LD A,8 - SUB (HL) - LD C,A ;compute (C)=8-BLKSHFT. - LD A,(SAVEXT) -GETBLK2:DEC C ;compute (A)=SAVEXT*2^(8-BLKSHFT). - JP Z,GETBLK3 - OR A - RLA - JP GETBLK2 -GETBLK3:ADD A,B - RET -; -; Routine to extract the (BC) block byte from the fcb pointed -; to by (PARAMS). If this is a big-disk, then these are 16 bit -; block numbers, else they are 8 bit numbers. -; Number is returned in (HL). -; -EXTBLK: LD HL,(PARAMS) ;get fcb address. - LD DE,16 ;block numbers start 16 bytes into fcb. - ADD HL,DE - ADD HL,BC - LD A,(BIGDISK) ;are we using a big-disk? - OR A - JP Z,EXTBLK1 - LD L,(HL) ;no, extract an 8 bit number from the fcb. - LD H,0 - RET -EXTBLK1:ADD HL,BC ;yes, extract a 16 bit number. - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ;return in (HL). - RET -; -; Compute block number. -; -COMBLK: CALL GETBLOCK - LD C,A - LD B,0 - CALL EXTBLK - LD (BLKNMBR),HL - RET -; -; Check for a zero block number (unused). -; -CHKBLK: LD HL,(BLKNMBR) - LD A,L ;is it zero? - OR H - RET -; -; Adjust physical block (BLKNMBR) and convert to logical -; sector (LOGSECT). This is the starting sector of this block. -; The actual sector of interest is then added to this and the -; resulting sector number is stored back in (BLKNMBR). This -; will still have to be adjusted for the track number. -; -LOGICAL:LD A,(BLKSHFT) ;get log2(physical/logical sectors). - LD HL,(BLKNMBR) ;get physical sector desired. -LOGICL1:ADD HL,HL ;compute logical sector number. - DEC A ;note logical sectors are 128 bytes long. - JP NZ,LOGICL1 - LD (LOGSECT),HL ;save logical sector. - LD A,(BLKMASK) ;get block mask. - LD C,A - LD A,(SAVNREC) ;get next sector to access. - AND C ;extract the relative position within physical block. - OR L ;and add it too logical sector. - LD L,A - LD (BLKNMBR),HL ;and store. - RET -; -; Set (HL) to point to extent byte in fcb. -; -SETEXT: LD HL,(PARAMS) - LD DE,12 ;it is the twelth byte. - ADD HL,DE - RET -; -; Set (HL) to point to record count byte in fcb and (DE) to -; next record number byte. -; -SETHLDE:LD HL,(PARAMS) - LD DE,15 ;record count byte (#15). - ADD HL,DE - EX DE,HL - LD HL,17 ;next record number (#32). - ADD HL,DE - RET -; -; Save current file data from fcb. -; -STRDATA:CALL SETHLDE - LD A,(HL) ;get and store record count byte. - LD (SAVNREC),A - EX DE,HL - LD A,(HL) ;get and store next record number byte. - LD (SAVNXT),A - CALL SETEXT ;point to extent byte. - LD A,(EXTMASK) ;get extent mask. - AND (HL) - LD (SAVEXT),A ;and save extent here. - RET -; -; Set the next record to access. If (MODE) is set to 2, then -; the last record byte (SAVNREC) has the correct number to access. -; For sequential access, (MODE) will be equal to 1. -; -SETNREC:CALL SETHLDE - LD A,(MODE) ;get sequential flag (=1). - CP 2 ;a 2 indicates that no adder is needed. - JP NZ,STNREC1 - XOR A ;clear adder (random access?). -STNREC1:LD C,A - LD A,(SAVNREC) ;get last record number. - ADD A,C ;increment record count. - LD (HL),A ;and set fcb's next record byte. - EX DE,HL - LD A,(SAVNXT) ;get next record byte from storage. - LD (HL),A ;and put this into fcb as number of records used. - RET -; -; Shift (HL) right (C) bits. -; -SHIFTR: INC C -SHIFTR1:DEC C - RET Z - LD A,H - OR A - RRA - LD H,A - LD A,L - RRA - LD L,A - JP SHIFTR1 -; -; Compute the check-sum for the directory buffer. Return -; integer sum in (A). -; -CHECKSUM: LD C,128 ;length of buffer. - LD HL,(DIRBUF) ;get its location. - XOR A ;clear summation byte. -CHKSUM1:ADD A,(HL) ;and compute sum ignoring carries. - INC HL - DEC C - JP NZ,CHKSUM1 - RET -; -; Shift (HL) left (C) bits. -; -SHIFTL: INC C -SHIFTL1:DEC C - RET Z - ADD HL,HL ;shift left 1 bit. - JP SHIFTL1 -; -; Routine to set a bit in a 16 bit value contained in (BC). -; The bit set depends on the current drive selection. -; -SETBIT: PUSH BC ;save 16 bit word. - LD A,(ACTIVE) ;get active drive. - LD C,A - LD HL,1 - CALL SHIFTL ;shift bit 0 into place. - POP BC ;now 'or' this with the original word. - LD A,C - OR L - LD L,A ;low byte done, do high byte. - LD A,B - OR H - LD H,A - RET -; -; Extract the write protect status bit for the current drive. -; The result is returned in (A), bit 0. -; -GETWPRT:LD HL,(WRTPRT) ;get status bytes. - LD A,(ACTIVE) ;which drive is current? - LD C,A - CALL SHIFTR ;shift status such that bit 0 is the - LD A,L ;one of interest for this drive. - AND 01H ;and isolate it. - RET -; -; Function to write protect the current disk. -; -WRTPRTD:LD HL,WRTPRT ;point to status word. - LD C,(HL) ;set (BC) equal to the status. - INC HL - LD B,(HL) - CALL SETBIT ;and set this bit according to current drive. - LD (WRTPRT),HL ;then save. - LD HL,(DIRSIZE) ;now save directory size limit. - INC HL ;remember the last one. - EX DE,HL - LD HL,(SCRATCH1) ;and store it here. - LD (HL),E ;put low byte. - INC HL - LD (HL),D ;then high byte. - RET -; -; Check for a read only file. -; -CHKROFL:CALL FCB2HL ;set (HL) to file entry in directory buffer. -CKROF1: LD DE,9 ;look at bit 7 of the ninth byte. - ADD HL,DE - LD A,(HL) - RLA - RET NC ;return if ok. - LD HL,ROFILE ;else, print error message and terminate. - JP JUMPHL -; -; Check the write protect status of the active disk. -; -CHKWPRT:CALL GETWPRT - RET Z ;return if ok. - LD HL,RODISK ;else print message and terminate. - JP JUMPHL -; -; Routine to set (HL) pointing to the proper entry in the -; directory buffer. -; -FCB2HL: LD HL,(DIRBUF) ;get address of buffer. - LD A,(FCBPOS) ;relative position of file. -; -; Routine to add (A) to (HL). -; -ADDA2HL:ADD A,L - LD L,A - RET NC - INC H ;take care of any carry. - RET -; -; Routine to get the 's2' byte from the fcb supplied in -; the initial parameter specification. -; -GETS2: LD HL,(PARAMS) ;get address of fcb. - LD DE,14 ;relative position of 's2'. - ADD HL,DE - LD A,(HL) ;extract this byte. - RET -; -; Clear the 's2' byte in the fcb. -; -CLEARS2:CALL GETS2 ;this sets (HL) pointing to it. - LD (HL),0 ;now clear it. - RET -; -; Set bit 7 in the 's2' byte of the fcb. -; -SETS2B7:CALL GETS2 ;get the byte. - OR 80H ;and set bit 7. - LD (HL),A ;then store. - RET -; -; Compare (FILEPOS) with (SCRATCH1) and set flags based on -; the difference. This checks to see if there are more file -; names in the directory. We are at (FILEPOS) and there are -; (SCRATCH1) of them to check. -; -MOREFLS:LD HL,(FILEPOS) ;we are here. - EX DE,HL - LD HL,(SCRATCH1) ;and don't go past here. - LD A,E ;compute difference but don't keep. - SUB (HL) - INC HL - LD A,D - SBC A,(HL) ;set carry if no more names. - RET -; -; Call this routine to prevent (SCRATCH1) from being greater -; than (FILEPOS). -; -CHKNMBR:CALL MOREFLS ;SCRATCH1 too big? - RET C - INC DE ;yes, reset it to (FILEPOS). - LD (HL),D - DEC HL - LD (HL),E - RET -; -; Compute (HL)=(DE)-(HL) -; -SUBHL: LD A,E ;compute difference. - SUB L - LD L,A ;store low byte. - LD A,D - SBC A,H - LD H,A ;and then high byte. - RET -; -; Set the directory checksum byte. -; -SETDIR: LD C,0FFH -; -; Routine to set or compare the directory checksum byte. If -; (C)=0ffh, then this will set the checksum byte. Else the byte -; will be checked. If the check fails (the disk has been changed), -; then this disk will be write protected. -; -CHECKDIR: LD HL,(CKSUMTBL) - EX DE,HL - LD HL,(ALLOC1) - CALL SUBHL - RET NC ;ok if (CKSUMTBL) > (ALLOC1), so return. - PUSH BC - CALL CHECKSUM ;else compute checksum. - LD HL,(CHKVECT) ;get address of checksum table. - EX DE,HL - LD HL,(CKSUMTBL) - ADD HL,DE ;set (HL) to point to byte for this drive. - POP BC - INC C ;set or check ? - JP Z,CHKDIR1 - CP (HL) ;check them. - RET Z ;return if they are the same. - CALL MOREFLS ;not the same, do we care? - RET NC - CALL WRTPRTD ;yes, mark this as write protected. - RET -CHKDIR1:LD (HL),A ;just set the byte. - RET -; -; Do a write to the directory of the current disk. -; -DIRWRITE: CALL SETDIR ;set checksum byte. - CALL DIRDMA ;set directory dma address. - LD C,1 ;tell the bios to actually write. - CALL DOWRITE ;then do the write. - JP DEFDMA -; -; Read from the directory. -; -DIRREAD:CALL DIRDMA ;set the directory dma address. - CALL DOREAD ;and read it. -; -; Routine to set the dma address to the users choice. -; -DEFDMA: LD HL,USERDMA ;reset the default dma address and return. - JP DIRDMA1 -; -; Routine to set the dma address for directory work. -; -DIRDMA: LD HL,DIRBUF -; -; Set the dma address. On entry, (HL) points to -; word containing the desired dma address. -; -DIRDMA1:LD C,(HL) - INC HL - LD B,(HL) ;setup (BC) and go to the bios to set it. - JP SETDMA -; -; Move the directory buffer into user's dma space. -; -MOVEDIR:LD HL,(DIRBUF) ;buffer is located here, and - EX DE,HL - LD HL,(USERDMA) ; put it here. - LD C,128 ;this is its length. - JP DE2HL ;move it now and return. -; -; Check (FILEPOS) and set the zero flag if it equals 0ffffh. -; -CKFILPOS: LD HL,FILEPOS - LD A,(HL) - INC HL - CP (HL) ;are both bytes the same? - RET NZ - INC A ;yes, but are they each 0ffh? - RET -; -; Set location (FILEPOS) to 0ffffh. -; -STFILPOS: LD HL,0FFFFH - LD (FILEPOS),HL - RET -; -; Move on to the next file position within the current -; directory buffer. If no more exist, set pointer to 0ffffh -; and the calling routine will check for this. Enter with (C) -; equal to 0ffh to cause the checksum byte to be set, else we -; will check this disk and set write protect if checksums are -; not the same (applies only if another directory sector must -; be read). -; -NXENTRY:LD HL,(DIRSIZE) ;get directory entry size limit. - EX DE,HL - LD HL,(FILEPOS) ;get current count. - INC HL ;go on to the next one. - LD (FILEPOS),HL - CALL SUBHL ;(HL)=(DIRSIZE)-(FILEPOS) - JP NC,NXENT1 ;is there more room left? - JP STFILPOS ;no. Set this flag and return. -NXENT1: LD A,(FILEPOS) ;get file position within directory. - AND 03H ;only look within this sector (only 4 entries fit). - LD B,5 ;convert to relative position (32 bytes each). -NXENT2: ADD A,A ;note that this is not efficient code. - DEC B ;5 'ADD A's would be better. - JP NZ,NXENT2 - LD (FCBPOS),A ;save it as position of fcb. - OR A - RET NZ ;return if we are within buffer. - PUSH BC - CALL TRKSEC ;we need the next directory sector. - CALL DIRREAD - POP BC - JP CHECKDIR -; -; Routine to to get a bit from the disk space allocation -; map. It is returned in (A), bit position 0. On entry to here, -; set (BC) to the block number on the disk to check. -; On return, (D) will contain the original bit position for -; this block number and (HL) will point to the address for it. -; -CKBITMAP: LD A,C ;determine bit number of interest. - AND 07H ;compute (D)=(E)=(C and 7)+1. - INC A - LD E,A ;save particular bit number. - LD D,A -; -; compute (BC)=(BC)/8. -; - LD A,C - RRCA ;now shift right 3 bits. - RRCA - RRCA - AND 1FH ;and clear bits 7,6,5. - LD C,A - LD A,B - ADD A,A ;now shift (B) into bits 7,6,5. - ADD A,A - ADD A,A - ADD A,A - ADD A,A - OR C ;and add in (C). - LD C,A ;ok, (C) ha been completed. - LD A,B ;is there a better way of doing this? - RRCA - RRCA - RRCA - AND 1FH - LD B,A ;and now (B) is completed. -; -; use this as an offset into the disk space allocation -; table. -; - LD HL,(ALOCVECT) - ADD HL,BC - LD A,(HL) ;now get correct byte. -CKBMAP1:RLCA ;get correct bit into position 0. - DEC E - JP NZ,CKBMAP1 - RET -; -; Set or clear the bit map such that block number (BC) will be marked -; as used. On entry, if (E)=0 then this bit will be cleared, if it equals -; 1 then it will be set (don't use anyother values). -; -STBITMAP: PUSH DE - CALL CKBITMAP ;get the byte of interest. - AND 0FEH ;clear the affected bit. - POP BC - OR C ;and now set it acording to (C). -; -; entry to restore the original bit position and then store -; in table. (A) contains the value, (D) contains the bit -; position (1-8), and (HL) points to the address within the -; space allocation table for this byte. -; -STBMAP1:RRCA ;restore original bit position. - DEC D - JP NZ,STBMAP1 - LD (HL),A ;and stor byte in table. - RET -; -; Set/clear space used bits in allocation map for this file. -; On entry, (C)=1 to set the map and (C)=0 to clear it. -; -SETFILE:CALL FCB2HL ;get address of fcb - LD DE,16 - ADD HL,DE ;get to block number bytes. - PUSH BC - LD C,17 ;check all 17 bytes (max) of table. -SETFL1: POP DE - DEC C ;done all bytes yet? - RET Z - PUSH DE - LD A,(BIGDISK) ;check disk size for 16 bit block numbers. - OR A - JP Z,SETFL2 - PUSH BC ;only 8 bit numbers. set (BC) to this one. - PUSH HL - LD C,(HL) ;get low byte from table, always - LD B,0 ;set high byte to zero. - JP SETFL3 -SETFL2: DEC C ;for 16 bit block numbers, adjust counter. - PUSH BC - LD C,(HL) ;now get both the low and high bytes. - INC HL - LD B,(HL) - PUSH HL -SETFL3: LD A,C ;block used? - OR B - JP Z,SETFL4 - LD HL,(DSKSIZE) ;is this block number within the - LD A,L ;space on the disk? - SUB C - LD A,H - SBC A,B - CALL NC,STBITMAP ;yes, set the proper bit. -SETFL4: POP HL ;point to next block number in fcb. - INC HL - POP BC - JP SETFL1 -; -; Construct the space used allocation bit map for the active -; drive. If a file name starts with '$' and it is under the -; current user number, then (STATUS) is set to minus 1. Otherwise -; it is not set at all. -; -BITMAP: LD HL,(DSKSIZE) ;compute size of allocation table. - LD C,3 - CALL SHIFTR ;(HL)=(HL)/8. - INC HL ;at lease 1 byte. - LD B,H - LD C,L ;set (BC) to the allocation table length. -; -; Initialize the bitmap for this drive. Right now, the first -; two bytes are specified by the disk parameter block. However -; a patch could be entered here if it were necessary to setup -; this table in a special mannor. For example, the bios could -; determine locations of 'bad blocks' and set them as already -; 'used' in the map. -; - LD HL,(ALOCVECT) ;now zero out the table now. -BITMAP1:LD (HL),0 - INC HL - DEC BC - LD A,B - OR C - JP NZ,BITMAP1 - LD HL,(ALLOC0) ;get initial space used by directory. - EX DE,HL - LD HL,(ALOCVECT) ;and put this into map. - LD (HL),E - INC HL - LD (HL),D -; -; End of initialization portion. -; - CALL HOMEDRV ;now home the drive. - LD HL,(SCRATCH1) - LD (HL),3 ;force next directory request to read - INC HL ;in a sector. - LD (HL),0 - CALL STFILPOS ;clear initial file position also. -BITMAP2:LD C,0FFH ;read next file name in directory - CALL NXENTRY ;and set checksum byte. - CALL CKFILPOS ;is there another file? - RET Z - CALL FCB2HL ;yes, get its address. - LD A,0E5H - CP (HL) ;empty file entry? - JP Z,BITMAP2 - LD A,(USERNO) ;no, correct user number? - CP (HL) - JP NZ,BITMAP3 - INC HL - LD A,(HL) ;yes, does name start with a '$'? - SUB '$' - JP NZ,BITMAP3 - DEC A ;yes, set atatus to minus one. - LD (STATUS),A -BITMAP3:LD C,1 ;now set this file's space as used in bit map. - CALL SETFILE - CALL CHKNMBR ;keep (SCRATCH1) in bounds. - JP BITMAP2 -; -; Set the status (STATUS) and return. -; -STSTATUS: LD A,(FNDSTAT) - JP SETSTAT -; -; Check extents in (A) and (C). Set the zero flag if they -; are the same. The number of 16k chunks of disk space that -; the directory extent covers is expressad is (EXTMASK+1). -; No registers are modified. -; -SAMEXT: PUSH BC - PUSH AF - LD A,(EXTMASK) ;get extent mask and use it to - CPL ;to compare both extent numbers. - LD B,A ;save resulting mask here. - LD A,C ;mask first extent and save in (C). - AND B - LD C,A - POP AF ;now mask second extent and compare - AND B ;with the first one. - SUB C - AND 1FH ;(* only check buts 0-4 *) - POP BC ;the zero flag is set if they are the same. - RET ;restore (BC) and return. -; -; Search for the first occurence of a file name. On entry, -; register (C) should contain the number of bytes of the fcb -; that must match. -; -FINDFST:LD A,0FFH - LD (FNDSTAT),A - LD HL,COUNTER ;save character count. - LD (HL),C - LD HL,(PARAMS) ;get filename to match. - LD (SAVEFCB),HL ;and save. - CALL STFILPOS ;clear initial file position (set to 0ffffh). - CALL HOMEDRV ;home the drive. -; -; Entry to locate the next occurence of a filename within the -; directory. The disk is not expected to have been changed. If -; it was, then it will be write protected. -; -FINDNXT:LD C,0 ;write protect the disk if changed. - CALL NXENTRY ;get next filename entry in directory. - CALL CKFILPOS ;is file position = 0ffffh? - JP Z,FNDNXT6 ;yes, exit now then. - LD HL,(SAVEFCB) ;set (DE) pointing to filename to match. - EX DE,HL - LD A,(DE) - CP 0E5H ;empty directory entry? - JP Z,FNDNXT1 ;(* are we trying to reserect erased entries? *) - PUSH DE - CALL MOREFLS ;more files in directory? - POP DE - JP NC,FNDNXT6 ;no more. Exit now. -FNDNXT1:CALL FCB2HL ;get address of this fcb in directory. - LD A,(COUNTER) ;get number of bytes (characters) to check. - LD C,A - LD B,0 ;initialize byte position counter. -FNDNXT2:LD A,C ;are we done with the compare? - OR A - JP Z,FNDNXT5 - LD A,(DE) ;no, check next byte. - CP '?' ;don't care about this character? - JP Z,FNDNXT4 - LD A,B ;get bytes position in fcb. - CP 13 ;don't care about the thirteenth byte either. - JP Z,FNDNXT4 - CP 12 ;extent byte? - LD A,(DE) - JP Z,FNDNXT3 - SUB (HL) ;otherwise compare characters. - AND 7FH - JP NZ,FINDNXT ;not the same, check next entry. - JP FNDNXT4 ;so far so good, keep checking. -FNDNXT3:PUSH BC ;check the extent byte here. - LD C,(HL) - CALL SAMEXT - POP BC - JP NZ,FINDNXT ;not the same, look some more. -; -; So far the names compare. Bump pointers to the next byte -; and continue until all (C) characters have been checked. -; -FNDNXT4:INC DE ;bump pointers. - INC HL - INC B - DEC C ;adjust character counter. - JP FNDNXT2 -FNDNXT5:LD A,(FILEPOS) ;return the position of this entry. - AND 03H - LD (STATUS),A - LD HL,FNDSTAT - LD A,(HL) - RLA - RET NC - XOR A - LD (HL),A - RET -; -; Filename was not found. Set appropriate status. -; -FNDNXT6:CALL STFILPOS ;set (FILEPOS) to 0ffffh. - LD A,0FFH ;say not located. - JP SETSTAT -; -; Erase files from the directory. Only the first byte of the -; fcb will be affected. It is set to (E5). -; -ERAFILE:CALL CHKWPRT ;is disk write protected? - LD C,12 ;only compare file names. - CALL FINDFST ;get first file name. -ERAFIL1:CALL CKFILPOS ;any found? - RET Z ;nope, we must be done. - CALL CHKROFL ;is file read only? - CALL FCB2HL ;nope, get address of fcb and - LD (HL),0E5H ;set first byte to 'empty'. - LD C,0 ;clear the space from the bit map. - CALL SETFILE - CALL DIRWRITE ;now write the directory sector back out. - CALL FINDNXT ;find the next file name. - JP ERAFIL1 ;and repeat process. -; -; Look through the space allocation map (bit map) for the -; next available block. Start searching at block number (BC-1). -; The search procedure is to look for an empty block that is -; before the starting block. If not empty, look at a later -; block number. In this way, we return the closest empty block -; on either side of the 'target' block number. This will speed -; access on random devices. For serial devices, this should be -; changed to look in the forward direction first and then start -; at the front and search some more. -; -; On return, (DE)= block number that is empty and (HL) =0 -; if no empry block was found. -; -FNDSPACE: LD D,B ;set (DE) as the block that is checked. - LD E,C -; -; Look before target block. Registers (BC) are used as the lower -; pointer and (DE) as the upper pointer. -; -FNDSPA1:LD A,C ;is block 0 specified? - OR B - JP Z,FNDSPA2 - DEC BC ;nope, check previous block. - PUSH DE - PUSH BC - CALL CKBITMAP - RRA ;is this block empty? - JP NC,FNDSPA3 ;yes. use this. -; -; Note that the above logic gets the first block that it finds -; that is empty. Thus a file could be written 'backward' making -; it very slow to access. This could be changed to look for the -; first empty block and then continue until the start of this -; empty space is located and then used that starting block. -; This should help speed up access to some files especially on -; a well used disk with lots of fairly small 'holes'. -; - POP BC ;nope, check some more. - POP DE -; -; Now look after target block. -; -FNDSPA2:LD HL,(DSKSIZE) ;is block (DE) within disk limits? - LD A,E - SUB L - LD A,D - SBC A,H - JP NC,FNDSPA4 - INC DE ;yes, move on to next one. - PUSH BC - PUSH DE - LD B,D - LD C,E - CALL CKBITMAP ;check it. - RRA ;empty? - JP NC,FNDSPA3 - POP DE ;nope, continue searching. - POP BC - JP FNDSPA1 -; -; Empty block found. Set it as used and return with (HL) -; pointing to it (true?). -; -FNDSPA3:RLA ;reset byte. - INC A ;and set bit 0. - CALL STBMAP1 ;update bit map. - POP HL ;set return registers. - POP DE - RET -; -; Free block was not found. If (BC) is not zero, then we have -; not checked all of the disk space. -; -FNDSPA4:LD A,C - OR B - JP NZ,FNDSPA1 - LD HL,0 ;set 'not found' status. - RET -; -; Move a complete fcb entry into the directory and write it. -; -FCBSET: LD C,0 - LD E,32 ;length of each entry. -; -; Move (E) bytes from the fcb pointed to by (PARAMS) into -; fcb in directory starting at relative byte (C). This updated -; directory buffer is then written to the disk. -; -UPDATE: PUSH DE - LD B,0 ;set (BC) to relative byte position. - LD HL,(PARAMS) ;get address of fcb. - ADD HL,BC ;compute starting byte. - EX DE,HL - CALL FCB2HL ;get address of fcb to update in directory. - POP BC ;set (C) to number of bytes to change. - CALL DE2HL -UPDATE1:CALL TRKSEC ;determine the track and sector affected. - JP DIRWRITE ;then write this sector out. -; -; Routine to change the name of all files on the disk with a -; specified name. The fcb contains the current name as the -; first 12 characters and the new name 16 bytes into the fcb. -; -CHGNAMES: CALL CHKWPRT ;check for a write protected disk. - LD C,12 ;match first 12 bytes of fcb only. - CALL FINDFST ;get first name. - LD HL,(PARAMS) ;get address of fcb. - LD A,(HL) ;get user number. - LD DE,16 ;move over to desired name. - ADD HL,DE - LD (HL),A ;keep same user number. -CHGNAM1:CALL CKFILPOS ;any matching file found? - RET Z ;no, we must be done. - CALL CHKROFL ;check for read only file. - LD C,16 ;start 16 bytes into fcb. - LD E,12 ;and update the first 12 bytes of directory. - CALL UPDATE - CALL FINDNXT ;get te next file name. - JP CHGNAM1 ;and continue. -; -; Update a files attributes. The procedure is to search for -; every file with the same name as shown in fcb (ignoring bit 7) -; and then to update it (which includes bit 7). No other changes -; are made. -; -SAVEATTR: LD C,12 ;match first 12 bytes. - CALL FINDFST ;look for first filename. -SAVATR1:CALL CKFILPOS ;was one found? - RET Z ;nope, we must be done. - LD C,0 ;yes, update the first 12 bytes now. - LD E,12 - CALL UPDATE ;update filename and write directory. - CALL FINDNXT ;and get the next file. - JP SAVATR1 ;then continue until done. -; -; Open a file (name specified in fcb). -; -OPENIT: LD C,15 ;compare the first 15 bytes. - CALL FINDFST ;get the first one in directory. - CALL CKFILPOS ;any at all? - RET Z -OPENIT1:CALL SETEXT ;point to extent byte within users fcb. - LD A,(HL) ;and get it. - PUSH AF ;save it and address. - PUSH HL - CALL FCB2HL ;point to fcb in directory. - EX DE,HL - LD HL,(PARAMS) ;this is the users copy. - LD C,32 ;move it into users space. - PUSH DE - CALL DE2HL - CALL SETS2B7 ;set bit 7 in 's2' byte (unmodified). - POP DE ;now get the extent byte from this fcb. - LD HL,12 - ADD HL,DE - LD C,(HL) ;into (C). - LD HL,15 ;now get the record count byte into (B). - ADD HL,DE - LD B,(HL) - POP HL ;keep the same extent as the user had originally. - POP AF - LD (HL),A - LD A,C ;is it the same as in the directory fcb? - CP (HL) - LD A,B ;if yes, then use the same record count. - JP Z,OPENIT2 - LD A,0 ;if the user specified an extent greater than - JP C,OPENIT2 ;the one in the directory, then set record count to 0. - LD A,128 ;otherwise set to maximum. -OPENIT2:LD HL,(PARAMS) ;set record count in users fcb to (A). - LD DE,15 - ADD HL,DE ;compute relative position. - LD (HL),A ;and set the record count. - RET -; -; Move two bytes from (DE) to (HL) if (and only if) (HL) -; point to a zero value (16 bit). -; Return with zero flag set it (DE) was moved. Registers (DE) -; and (HL) are not changed. However (A) is. -; -MOVEWORD: LD A,(HL) ;check for a zero word. - INC HL - OR (HL) ;both bytes zero? - DEC HL - RET NZ ;nope, just return. - LD A,(DE) ;yes, move two bytes from (DE) into - LD (HL),A ;this zero space. - INC DE - INC HL - LD A,(DE) - LD (HL),A - DEC DE ;don't disturb these registers. - DEC HL - RET -; -; Get here to close a file specified by (fcb). -; -CLOSEIT:XOR A ;clear status and file position bytes. - LD (STATUS),A - LD (FILEPOS),A - LD (FILEPOS+1),A - CALL GETWPRT ;get write protect bit for this drive. - RET NZ ;just return if it is set. - CALL GETS2 ;else get the 's2' byte. - AND 80H ;and look at bit 7 (file unmodified?). - RET NZ ;just return if set. - LD C,15 ;else look up this file in directory. - CALL FINDFST - CALL CKFILPOS ;was it found? - RET Z ;just return if not. - LD BC,16 ;set (HL) pointing to records used section. - CALL FCB2HL - ADD HL,BC - EX DE,HL - LD HL,(PARAMS) ;do the same for users specified fcb. - ADD HL,BC - LD C,16 ;this many bytes are present in this extent. -CLOSEIT1: LD A,(BIGDISK) ;8 or 16 bit record numbers? - OR A - JP Z,CLOSEIT4 - LD A,(HL) ;just 8 bit. Get one from users fcb. - OR A - LD A,(DE) ;now get one from directory fcb. - JP NZ,CLOSEIT2 - LD (HL),A ;users byte was zero. Update from directory. -CLOSEIT2: OR A - JP NZ,CLOSEIT3 - LD A,(HL) ;directories byte was zero, update from users fcb. - LD (DE),A -CLOSEIT3: CP (HL) ;if neither one of these bytes were zero, - JP NZ,CLOSEIT7 ;then close error if they are not the same. - JP CLOSEIT5 ;ok so far, get to next byte in fcbs. -CLOSEIT4: CALL MOVEWORD ;update users fcb if it is zero. - EX DE,HL - CALL MOVEWORD ;update directories fcb if it is zero. - EX DE,HL - LD A,(DE) ;if these two values are no different, - CP (HL) ;then a close error occured. - JP NZ,CLOSEIT7 - INC DE ;check second byte. - INC HL - LD A,(DE) - CP (HL) - JP NZ,CLOSEIT7 - DEC C ;remember 16 bit values. -CLOSEIT5: INC DE ;bump to next item in table. - INC HL - DEC C ;there are 16 entries only. - JP NZ,CLOSEIT1 ;continue if more to do. - LD BC,0FFECH ;backup 20 places (extent byte). - ADD HL,BC - EX DE,HL - ADD HL,BC - LD A,(DE) - CP (HL) ;directory's extent already greater than the - JP C,CLOSEIT6 ;users extent? - LD (HL),A ;no, update directory extent. - LD BC,3 ;and update the record count byte in - ADD HL,BC ;directories fcb. - EX DE,HL - ADD HL,BC - LD A,(HL) ;get from user. - LD (DE),A ;and put in directory. -CLOSEIT6: LD A,0FFH ;set 'was open and is now closed' byte. - LD (CLOSEFLG),A - JP UPDATE1 ;update the directory now. -CLOSEIT7: LD HL,STATUS ;set return status and then return. - DEC (HL) - RET -; -; Routine to get the next empty space in the directory. It -; will then be cleared for use. -; -GETEMPTY: CALL CHKWPRT ;make sure disk is not write protected. - LD HL,(PARAMS) ;save current parameters (fcb). - PUSH HL - LD HL,EMPTYFCB ;use special one for empty space. - LD (PARAMS),HL - LD C,1 ;search for first empty spot in directory. - CALL FINDFST ;(* only check first byte *) - CALL CKFILPOS ;none? - POP HL - LD (PARAMS),HL ;restore original fcb address. - RET Z ;return if no more space. - EX DE,HL - LD HL,15 ;point to number of records for this file. - ADD HL,DE - LD C,17 ;and clear all of this space. - XOR A -GETMT1: LD (HL),A - INC HL - DEC C - JP NZ,GETMT1 - LD HL,13 ;clear the 's1' byte also. - ADD HL,DE - LD (HL),A - CALL CHKNMBR ;keep (SCRATCH1) within bounds. - CALL FCBSET ;write out this fcb entry to directory. - JP SETS2B7 ;set 's2' byte bit 7 (unmodified at present). -; -; Routine to close the current extent and open the next one -; for reading. -; -GETNEXT:XOR A - LD (CLOSEFLG),A ;clear close flag. - CALL CLOSEIT ;close this extent. - CALL CKFILPOS - RET Z ;not there??? - LD HL,(PARAMS) ;get extent byte. - LD BC,12 - ADD HL,BC - LD A,(HL) ;and increment it. - INC A - AND 1FH ;keep within range 0-31. - LD (HL),A - JP Z,GTNEXT1 ;overflow? - LD B,A ;mask extent byte. - LD A,(EXTMASK) - AND B - LD HL,CLOSEFLG ;check close flag (0ffh is ok). - AND (HL) - JP Z,GTNEXT2 ;if zero, we must read in next extent. - JP GTNEXT3 ;else, it is already in memory. -GTNEXT1:LD BC,2 ;Point to the 's2' byte. - ADD HL,BC - INC (HL) ;and bump it. - LD A,(HL) ;too many extents? - AND 0FH - JP Z,GTNEXT5 ;yes, set error code. -; -; Get here to open the next extent. -; -GTNEXT2:LD C,15 ;set to check first 15 bytes of fcb. - CALL FINDFST ;find the first one. - CALL CKFILPOS ;none available? - JP NZ,GTNEXT3 - LD A,(RDWRTFLG) ;no extent present. Can we open an empty one? - INC A ;0ffh means reading (so not possible). - JP Z,GTNEXT5 ;or an error. - CALL GETEMPTY ;we are writing, get an empty entry. - CALL CKFILPOS ;none? - JP Z,GTNEXT5 ;error if true. - JP GTNEXT4 ;else we are almost done. -GTNEXT3:CALL OPENIT1 ;open this extent. -GTNEXT4:CALL STRDATA ;move in updated data (rec #, extent #, etc.) - XOR A ;clear status and return. - JP SETSTAT -; -; Error in extending the file. Too many extents were needed -; or not enough space on the disk. -; -GTNEXT5:CALL IOERR1 ;set error code, clear bit 7 of 's2' - JP SETS2B7 ;so this is not written on a close. -; -; Read a sequential file. -; -RDSEQ: LD A,1 ;set sequential access mode. - LD (MODE),A -RDSEQ1: LD A,0FFH ;don't allow reading unwritten space. - LD (RDWRTFLG),A - CALL STRDATA ;put rec# and ext# into fcb. - LD A,(SAVNREC) ;get next record to read. - LD HL,SAVNXT ;get number of records in extent. - CP (HL) ;within this extent? - JP C,RDSEQ2 - CP 128 ;no. Is this extent fully used? - JP NZ,RDSEQ3 ;no. End-of-file. - CALL GETNEXT ;yes, open the next one. - XOR A ;reset next record to read. - LD (SAVNREC),A - LD A,(STATUS) ;check on open, successful? - OR A - JP NZ,RDSEQ3 ;no, error. -RDSEQ2: CALL COMBLK ;ok. compute block number to read. - CALL CHKBLK ;check it. Within bounds? - JP Z,RDSEQ3 ;no, error. - CALL LOGICAL ;convert (BLKNMBR) to logical sector (128 byte). - CALL TRKSEC1 ;set the track and sector for this block #. - CALL DOREAD ;and read it. - JP SETNREC ;and set the next record to be accessed. -; -; Read error occured. Set status and return. -; -RDSEQ3: JP IOERR1 -; -; Write the next sequential record. -; -WTSEQ: LD A,1 ;set sequential access mode. - LD (MODE),A -WTSEQ1: LD A,0 ;allow an addition empty extent to be opened. - LD (RDWRTFLG),A - CALL CHKWPRT ;check write protect status. - LD HL,(PARAMS) - CALL CKROF1 ;check for read only file, (HL) already set to fcb. - CALL STRDATA ;put updated data into fcb. - LD A,(SAVNREC) ;get record number to write. - CP 128 ;within range? - JP NC,IOERR1 ;no, error(?). - CALL COMBLK ;compute block number. - CALL CHKBLK ;check number. - LD C,0 ;is there one to write to? - JP NZ,WTSEQ6 ;yes, go do it. - CALL GETBLOCK ;get next block number within fcb to use. - LD (RELBLOCK),A ;and save. - LD BC,0 ;start looking for space from the start - OR A ;if none allocated as yet. - JP Z,WTSEQ2 - LD C,A ;extract previous block number from fcb - DEC BC ;so we can be closest to it. - CALL EXTBLK - LD B,H - LD C,L -WTSEQ2: CALL FNDSPACE ;find the next empty block nearest number (BC). - LD A,L ;check for a zero number. - OR H - JP NZ,WTSEQ3 - LD A,2 ;no more space? - JP SETSTAT -WTSEQ3: LD (BLKNMBR),HL ;save block number to access. - EX DE,HL ;put block number into (DE). - LD HL,(PARAMS) ;now we must update the fcb for this - LD BC,16 ;newly allocated block. - ADD HL,BC - LD A,(BIGDISK) ;8 or 16 bit block numbers? - OR A - LD A,(RELBLOCK) ;(* update this entry *) - JP Z,WTSEQ4 ;zero means 16 bit ones. - CALL ADDA2HL ;(HL)=(HL)+(A) - LD (HL),E ;store new block number. - JP WTSEQ5 -WTSEQ4: LD C,A ;compute spot in this 16 bit table. - LD B,0 - ADD HL,BC - ADD HL,BC - LD (HL),E ;stuff block number (DE) there. - INC HL - LD (HL),D -WTSEQ5: LD C,2 ;set (C) to indicate writing to un-used disk space. -WTSEQ6: LD A,(STATUS) ;are we ok so far? - OR A - RET NZ - PUSH BC ;yes, save write flag for bios (register C). - CALL LOGICAL ;convert (BLKNMBR) over to loical sectors. - LD A,(MODE) ;get access mode flag (1=sequential, - DEC A ;0=random, 2=special?). - DEC A - JP NZ,WTSEQ9 -; -; Special random i/o from function #40. Maybe for M/PM, but the -; current block, if it has not been written to, will be zeroed -; out and then written (reason?). -; - POP BC - PUSH BC - LD A,C ;get write status flag (2=writing unused space). - DEC A - DEC A - JP NZ,WTSEQ9 - PUSH HL - LD HL,(DIRBUF) ;zero out the directory buffer. - LD D,A ;note that (A) is zero here. -WTSEQ7: LD (HL),A - INC HL - INC D ;do 128 bytes. - JP P,WTSEQ7 - CALL DIRDMA ;tell the bios the dma address for directory access. - LD HL,(LOGSECT) ;get sector that starts current block. - LD C,2 ;set 'writing to unused space' flag. -WTSEQ8: LD (BLKNMBR),HL ;save sector to write. - PUSH BC - CALL TRKSEC1 ;determine its track and sector numbers. - POP BC - CALL DOWRITE ;now write out 128 bytes of zeros. - LD HL,(BLKNMBR) ;get sector number. - LD C,0 ;set normal write flag. - LD A,(BLKMASK) ;determine if we have written the entire - LD B,A ;physical block. - AND L - CP B - INC HL ;prepare for the next one. - JP NZ,WTSEQ8 ;continue until (BLKMASK+1) sectors written. - POP HL ;reset next sector number. - LD (BLKNMBR),HL - CALL DEFDMA ;and reset dma address. -; -; Normal disk write. Set the desired track and sector then -; do the actual write. -; -WTSEQ9: CALL TRKSEC1 ;determine track and sector for this write. - POP BC ;get write status flag. - PUSH BC - CALL DOWRITE ;and write this out. - POP BC - LD A,(SAVNREC) ;get number of records in file. - LD HL,SAVNXT ;get last record written. - CP (HL) - JP C,WTSEQ10 - LD (HL),A ;we have to update record count. - INC (HL) - LD C,2 -; -;* This area has been patched to correct disk update problem -;* when using blocking and de-blocking in the BIOS. -; -WTSEQ10:NOP ;was 'dcr c' - NOP ;was 'dcr c' - LD HL,0 ;was 'jnz wtseq99' -; -; * End of patch. -; - PUSH AF - CALL GETS2 ;set 'extent written to' flag. - AND 7FH ;(* clear bit 7 *) - LD (HL),A - POP AF ;get record count for this extent. -WTSEQ99:CP 127 ;is it full? - JP NZ,WTSEQ12 - LD A,(MODE) ;yes, are we in sequential mode? - CP 1 - JP NZ,WTSEQ12 - CALL SETNREC ;yes, set next record number. - CALL GETNEXT ;and get next empty space in directory. - LD HL,STATUS ;ok? - LD A,(HL) - OR A - JP NZ,WTSEQ11 - DEC A ;yes, set record count to -1. - LD (SAVNREC),A -WTSEQ11:LD (HL),0 ;clear status. -WTSEQ12:JP SETNREC ;set next record to access. -; -; For random i/o, set the fcb for the desired record number -; based on the 'r0,r1,r2' bytes. These bytes in the fcb are -; used as follows: -; -; fcb+35 fcb+34 fcb+33 -; | 'r-2' | 'r-1' | 'r-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | overflow | | extra | extent | record # | -; | ______________| |_extent|__number___|_____________| -; also 's2' -; -; On entry, register (C) contains 0ffh if this is a read -; and thus we can not access unwritten disk space. Otherwise, -; another extent will be opened (for writing) if required. -; -POSITION: XOR A ;set random i/o flag. - LD (MODE),A -; -; Special entry (function #40). M/PM ? -; -POSITN1:PUSH BC ;save read/write flag. - LD HL,(PARAMS) ;get address of fcb. - EX DE,HL - LD HL,33 ;now get byte 'r0'. - ADD HL,DE - LD A,(HL) - AND 7FH ;keep bits 0-6 for the record number to access. - PUSH AF - LD A,(HL) ;now get bit 7 of 'r0' and bits 0-3 of 'r1'. - RLA - INC HL - LD A,(HL) - RLA - AND 1FH ;and save this in bits 0-4 of (C). - LD C,A ;this is the extent byte. - LD A,(HL) ;now get the extra extent byte. - RRA - RRA - RRA - RRA - AND 0FH - LD B,A ;and save it in (B). - POP AF ;get record number back to (A). - INC HL ;check overflow byte 'r2'. - LD L,(HL) - INC L - DEC L - LD L,6 ;prepare for error. - JP NZ,POSITN5 ;out of disk space error. - LD HL,32 ;store record number into fcb. - ADD HL,DE - LD (HL),A - LD HL,12 ;and now check the extent byte. - ADD HL,DE - LD A,C - SUB (HL) ;same extent as before? - JP NZ,POSITN2 - LD HL,14 ;yes, check extra extent byte 's2' also. - ADD HL,DE - LD A,B - SUB (HL) - AND 7FH - JP Z,POSITN3 ;same, we are almost done then. -; -; Get here when another extent is required. -; -POSITN2:PUSH BC - PUSH DE - CALL CLOSEIT ;close current extent. - POP DE - POP BC - LD L,3 ;prepare for error. - LD A,(STATUS) - INC A - JP Z,POSITN4 ;close error. - LD HL,12 ;put desired extent into fcb now. - ADD HL,DE - LD (HL),C - LD HL,14 ;and store extra extent byte 's2'. - ADD HL,DE - LD (HL),B - CALL OPENIT ;try and get this extent. - LD A,(STATUS) ;was it there? - INC A - JP NZ,POSITN3 - POP BC ;no. can we create a new one (writing?). - PUSH BC - LD L,4 ;prepare for error. - INC C - JP Z,POSITN4 ;nope, reading unwritten space error. - CALL GETEMPTY ;yes we can, try to find space. - LD L,5 ;prepare for error. - LD A,(STATUS) - INC A - JP Z,POSITN4 ;out of space? -; -; Normal return location. Clear error code and return. -; -POSITN3:POP BC ;restore stack. - XOR A ;and clear error code byte. - JP SETSTAT -; -; Error. Set the 's2' byte to indicate this (why?). -; -POSITN4:PUSH HL - CALL GETS2 - LD (HL),0C0H - POP HL -; -; Return with error code (presently in L). -; -POSITN5:POP BC - LD A,L ;get error code. - LD (STATUS),A - JP SETS2B7 -; -; Read a random record. -; -READRAN:LD C,0FFH ;set 'read' status. - CALL POSITION ;position the file to proper record. - CALL Z,RDSEQ1 ;and read it as usual (if no errors). - RET -; -; Write to a random record. -; -WRITERAN: LD C,0 ;set 'writing' flag. - CALL POSITION ;position the file to proper record. - CALL Z,WTSEQ1 ;and write as usual (if no errors). - RET -; -; Compute the random record number. Enter with (HL) pointing -; to a fcb an (DE) contains a relative location of a record -; number. On exit, (C) contains the 'r0' byte, (B) the 'r1' -; byte, and (A) the 'r2' byte. -; -; On return, the zero flag is set if the record is within -; bounds. Otherwise, an overflow occured. -; -COMPRAND: EX DE,HL ;save fcb pointer in (DE). - ADD HL,DE ;compute relative position of record #. - LD C,(HL) ;get record number into (BC). - LD B,0 - LD HL,12 ;now get extent. - ADD HL,DE - LD A,(HL) ;compute (BC)=(record #)+(extent)*128. - RRCA ;move lower bit into bit 7. - AND 80H ;and ignore all other bits. - ADD A,C ;add to our record number. - LD C,A - LD A,0 ;take care of any carry. - ADC A,B - LD B,A - LD A,(HL) ;now get the upper bits of extent into - RRCA ;bit positions 0-3. - AND 0FH ;and ignore all others. - ADD A,B ;add this in to 'r1' byte. - LD B,A - LD HL,14 ;get the 's2' byte (extra extent). - ADD HL,DE - LD A,(HL) - ADD A,A ;and shift it left 4 bits (bits 4-7). - ADD A,A - ADD A,A - ADD A,A - PUSH AF ;save carry flag (bit 0 of flag byte). - ADD A,B ;now add extra extent into 'r1'. - LD B,A - PUSH AF ;and save carry (overflow byte 'r2'). - POP HL ;bit 0 of (L) is the overflow indicator. - LD A,L - POP HL ;and same for first carry flag. - OR L ;either one of these set? - AND 01H ;only check the carry flags. - RET -; -; Routine to setup the fcb (bytes 'r0', 'r1', 'r2') to -; reflect the last record used for a random (or other) file. -; This reads the directory and looks at all extents computing -; the largerst record number for each and keeping the maximum -; value only. Then 'r0', 'r1', and 'r2' will reflect this -; maximum record number. This is used to compute the space used -; by a random file. -; -RANSIZE:LD C,12 ;look thru directory for first entry with - CALL FINDFST ;this name. - LD HL,(PARAMS) ;zero out the 'r0, r1, r2' bytes. - LD DE,33 - ADD HL,DE - PUSH HL - LD (HL),D ;note that (D)=0. - INC HL - LD (HL),D - INC HL - LD (HL),D -RANSIZ1:CALL CKFILPOS ;is there an extent to process? - JP Z,RANSIZ3 ;no, we are done. - CALL FCB2HL ;set (HL) pointing to proper fcb in dir. - LD DE,15 ;point to last record in extent. - CALL COMPRAND ;and compute random parameters. - POP HL - PUSH HL ;now check these values against those - LD E,A ;already in fcb. - LD A,C ;the carry flag will be set if those - SUB (HL) ;in the fcb represent a larger size than - INC HL ;this extent does. - LD A,B - SBC A,(HL) - INC HL - LD A,E - SBC A,(HL) - JP C,RANSIZ2 - LD (HL),E ;we found a larger (in size) extent. - DEC HL ;stuff these values into fcb. - LD (HL),B - DEC HL - LD (HL),C -RANSIZ2:CALL FINDNXT ;now get the next extent. - JP RANSIZ1 ;continue til all done. -RANSIZ3:POP HL ;we are done, restore the stack and - RET ;return. -; -; Function to return the random record position of a given -; file which has been read in sequential mode up to now. -; -SETRAN: LD HL,(PARAMS) ;point to fcb. - LD DE,32 ;and to last used record. - CALL COMPRAND ;compute random position. - LD HL,33 ;now stuff these values into fcb. - ADD HL,DE - LD (HL),C ;move 'r0'. - INC HL - LD (HL),B ;and 'r1'. - INC HL - LD (HL),A ;and lastly 'r2'. - RET -; -; This routine select the drive specified in (ACTIVE) and -; update the login vector and bitmap table if this drive was -; not already active. -; -LOGINDRV: LD HL,(LOGIN) ;get the login vector. - LD A,(ACTIVE) ;get the default drive. - LD C,A - CALL SHIFTR ;position active bit for this drive - PUSH HL ;into bit 0. - EX DE,HL - CALL SELECT ;select this drive. - POP HL - CALL Z,SLCTERR ;valid drive? - LD A,L ;is this a newly activated drive? - RRA - RET C - LD HL,(LOGIN) ;yes, update the login vector. - LD C,L - LD B,H - CALL SETBIT - LD (LOGIN),HL ;and save. - JP BITMAP ;now update the bitmap. -; -; Function to set the active disk number. -; -SETDSK: LD A,(EPARAM) ;get parameter passed and see if this - LD HL,ACTIVE ;represents a change in drives. - CP (HL) - RET Z - LD (HL),A ;yes it does, log it in. - JP LOGINDRV -; -; This is the 'auto disk select' routine. The firsst byte -; of the fcb is examined for a drive specification. If non -; zero then the drive will be selected and loged in. -; -AUTOSEL:LD A,0FFH ;say 'auto-select activated'. - LD (AUTO),A - LD HL,(PARAMS) ;get drive specified. - LD A,(HL) - AND 1FH ;look at lower 5 bits. - DEC A ;adjust for (1=A, 2=B) etc. - LD (EPARAM),A ;and save for the select routine. - CP 1EH ;check for 'no change' condition. - JP NC,AUTOSL1 ;yes, don't change. - LD A,(ACTIVE) ;we must change, save currently active - LD (OLDDRV),A ;drive. - LD A,(HL) ;and save first byte of fcb also. - LD (AUTOFLAG),A ;this must be non-zero. - AND 0E0H ;whats this for (bits 6,7 are used for - LD (HL),A ;something)? - CALL SETDSK ;select and log in this drive. -AUTOSL1:LD A,(USERNO) ;move user number into fcb. - LD HL,(PARAMS) ;(* upper half of first byte *) - OR (HL) - LD (HL),A - RET ;and return (all done). -; -; Function to return the current cp/m version number. -; -GETVER: LD A,022H ;version 2.2 - JP SETSTAT -; -; Function to reset the disk system. -; -RSTDSK: LD HL,0 ;clear write protect status and log - LD (WRTPRT),HL ;in vector. - LD (LOGIN),HL - XOR A ;select drive 'A'. - LD (ACTIVE),A - LD HL,TBUFF ;setup default dma address. - LD (USERDMA),HL - CALL DEFDMA - JP LOGINDRV ;now log in drive 'A'. -; -; Function to open a specified file. -; -OPENFIL:CALL CLEARS2 ;clear 's2' byte. - CALL AUTOSEL ;select proper disk. - JP OPENIT ;and open the file. -; -; Function to close a specified file. -; -CLOSEFIL: CALL AUTOSEL ;select proper disk. - JP CLOSEIT ;and close the file. -; -; Function to return the first occurence of a specified file -; name. If the first byte of the fcb is '?' then the name will -; not be checked (get the first entry no matter what). -; -GETFST: LD C,0 ;prepare for special search. - EX DE,HL - LD A,(HL) ;is first byte a '?'? - CP '?' - JP Z,GETFST1 ;yes, just get very first entry (zero length match). - CALL SETEXT ;get the extension byte from fcb. - LD A,(HL) ;is it '?'? if yes, then we want - CP '?' ;an entry with a specific 's2' byte. - CALL NZ,CLEARS2 ;otherwise, look for a zero 's2' byte. - CALL AUTOSEL ;select proper drive. - LD C,15 ;compare bytes 0-14 in fcb (12&13 excluded). -GETFST1:CALL FINDFST ;find an entry and then move it into - JP MOVEDIR ;the users dma space. -; -; Function to return the next occurence of a file name. -; -GETNXT: LD HL,(SAVEFCB) ;restore pointers. note that no - LD (PARAMS),HL ;other dbos calls are allowed. - CALL AUTOSEL ;no error will be returned, but the - CALL FINDNXT ;results will be wrong. - JP MOVEDIR -; -; Function to delete a file by name. -; -DELFILE:CALL AUTOSEL ;select proper drive. - CALL ERAFILE ;erase the file. - JP STSTATUS ;set status and return. -; -; Function to execute a sequential read of the specified -; record number. -; -READSEQ:CALL AUTOSEL ;select proper drive then read. - JP RDSEQ -; -; Function to write the net sequential record. -; -WRTSEQ: CALL AUTOSEL ;select proper drive then write. - JP WTSEQ -; -; Create a file function. -; -FCREATE:CALL CLEARS2 ;clear the 's2' byte on all creates. - CALL AUTOSEL ;select proper drive and get the next - JP GETEMPTY ;empty directory space. -; -; Function to rename a file. -; -RENFILE:CALL AUTOSEL ;select proper drive and then switch - CALL CHGNAMES ;file names. - JP STSTATUS -; -; Function to return the login vector. -; -GETLOG: LD HL,(LOGIN) - JP GETPRM1 -; -; Function to return the current disk assignment. -; -GETCRNT:LD A,(ACTIVE) - JP SETSTAT -; -; Function to set the dma address. -; -PUTDMA: EX DE,HL - LD (USERDMA),HL ;save in our space and then get to - JP DEFDMA ;the bios with this also. -; -; Function to return the allocation vector. -; -GETALOC:LD HL,(ALOCVECT) - JP GETPRM1 -; -; Function to return the read-only status vector. -; -GETROV: LD HL,(WRTPRT) - JP GETPRM1 -; -; Function to set the file attributes (read-only, system). -; -SETATTR:CALL AUTOSEL ;select proper drive then save attributes. - CALL SAVEATTR - JP STSTATUS -; -; Function to return the address of the disk parameter block -; for the current drive. -; -GETPARM:LD HL,(DISKPB) -GETPRM1:LD (STATUS),HL - RET -; -; Function to get or set the user number. If (E) was (FF) -; then this is a request to return the current user number. -; Else set the user number from (E). -; -GETUSER:LD A,(EPARAM) ;get parameter. - CP 0FFH ;get user number? - JP NZ,SETUSER - LD A,(USERNO) ;yes, just do it. - JP SETSTAT -SETUSER:AND 1FH ;no, we should set it instead. keep low - LD (USERNO),A ;bits (0-4) only. - RET -; -; Function to read a random record from a file. -; -RDRANDOM: CALL AUTOSEL ;select proper drive and read. - JP READRAN -; -; Function to compute the file size for random files. -; -WTRANDOM: CALL AUTOSEL ;select proper drive and write. - JP WRITERAN -; -; Function to compute the size of a random file. -; -FILESIZE: CALL AUTOSEL ;select proper drive and check file length - JP RANSIZE -; -; Function #37. This allows a program to log off any drives. -; On entry, set (DE) to contain a word with bits set for those -; drives that are to be logged off. The log-in vector and the -; write protect vector will be updated. This must be a M/PM -; special function. -; -LOGOFF: LD HL,(PARAMS) ;get drives to log off. - LD A,L ;for each bit that is set, we want - CPL ;to clear that bit in (LOGIN) - LD E,A ;and (WRTPRT). - LD A,H - CPL - LD HL,(LOGIN) ;reset the login vector. - AND H - LD D,A - LD A,L - AND E - LD E,A - LD HL,(WRTPRT) - EX DE,HL - LD (LOGIN),HL ;and save. - LD A,L ;now do the write protect vector. - AND E - LD L,A - LD A,H - AND D - LD H,A - LD (WRTPRT),HL ;and save. all done. - RET -; -; Get here to return to the user. -; -GOBACK: LD A,(AUTO) ;was auto select activated? - OR A - JP Z,GOBACK1 - LD HL,(PARAMS) ;yes, but was a change made? - LD (HL),0 ;(* reset first byte of fcb *) - LD A,(AUTOFLAG) - OR A - JP Z,GOBACK1 - LD (HL),A ;yes, reset first byte properly. - LD A,(OLDDRV) ;and get the old drive and select it. - LD (EPARAM),A - CALL SETDSK -GOBACK1:LD HL,(USRSTACK) ;reset the users stack pointer. - LD SP,HL - LD HL,(STATUS) ;get return status. - LD A,L ;force version 1.4 compatability. - LD B,H - RET ;and go back to user. -; -; Function #40. This is a special entry to do random i/o. -; For the case where we are writing to unused disk space, this -; space will be zeroed out first. This must be a M/PM special -; purpose function, because why would any normal program even -; care about the previous contents of a sector about to be -; written over. -; -WTSPECL:CALL AUTOSEL ;select proper drive. - LD A,2 ;use special write mode. - LD (MODE),A - LD C,0 ;set write indicator. - CALL POSITN1 ;position the file. - CALL Z,WTSEQ1 ;and write (if no errors). - RET -; -;************************************************************** -;* -;* BDOS data storage pool. -;* -;************************************************************** -; -EMPTYFCB: DEFB 0E5H ;empty directory segment indicator. -WRTPRT: DEFW 0 ;write protect status for all 16 drives. -LOGIN: DEFW 0 ;drive active word (1 bit per drive). -USERDMA:DEFW 080H ;user's dma address (defaults to 80h). -; -; Scratch areas from parameter block. -; -SCRATCH1: DEFW 0 ;relative position within dir segment for file (0-3). -SCRATCH2: DEFW 0 ;last selected track number. -SCRATCH3: DEFW 0 ;last selected sector number. -; -; Disk storage areas from parameter block. -; -DIRBUF: DEFW 0 ;address of directory buffer to use. -DISKPB: DEFW 0 ;contains address of disk parameter block. -CHKVECT:DEFW 0 ;address of check vector. -ALOCVECT: DEFW 0 ;address of allocation vector (bit map). -; -; Parameter block returned from the bios. -; -SECTORS:DEFW 0 ;sectors per track from bios. -BLKSHFT:DEFB 0 ;block shift. -BLKMASK:DEFB 0 ;block mask. -EXTMASK:DEFB 0 ;extent mask. -DSKSIZE:DEFW 0 ;disk size from bios (number of blocks-1). -DIRSIZE:DEFW 0 ;directory size. -ALLOC0: DEFW 0 ;storage for first bytes of bit map (dir space used). -ALLOC1: DEFW 0 -OFFSET: DEFW 0 ;first usable track number. -XLATE: DEFW 0 ;sector translation table address. -; -; -CLOSEFLG: DEFB 0 ;close flag (=0ffh is extent written ok). -RDWRTFLG: DEFB 0 ;read/write flag (0ffh=read, 0=write). -FNDSTAT:DEFB 0 ;filename found status (0=found first entry). -MODE: DEFB 0 ;I/o mode select (0=random, 1=sequential, 2=special random). -EPARAM: DEFB 0 ;storage for register (E) on entry to bdos. -RELBLOCK: DEFB 0 ;relative position within fcb of block number written. -COUNTER:DEFB 0 ;byte counter for directory name searches. -SAVEFCB:DEFW 0,0 ;save space for address of fcb (for directory searches). -BIGDISK:DEFB 0 ;if =0 then disk is > 256 blocks long. -AUTO: DEFB 0 ;if non-zero, then auto select activated. -OLDDRV: DEFB 0 ;on auto select, storage for previous drive. -AUTOFLAG: DEFB 0 ;if non-zero, then auto select changed drives. -SAVNXT: DEFB 0 ;storage for next record number to access. -SAVEXT: DEFB 0 ;storage for extent number of file. -SAVNREC:DEFW 0 ;storage for number of records in file. -BLKNMBR:DEFW 0 ;block number (physical sector) used within a file or logical sect -LOGSECT:DEFW 0 ;starting logical (128 byte) sector of block (physical sector). -FCBPOS: DEFB 0 ;relative position within buffer for fcb of file of interest. -FILEPOS:DEFW 0 ;files position within directory (0 to max entries -1). -; -; Disk directory buffer checksum bytes. One for each of the -; 16 possible drives. -; -CKSUMTBL: DEFB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; Extra space ? -; - DEFB 0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; -BOOT: JP 0 ;NOTE WE USE FAKE DESTINATIONS -WBOOT: JP 0 -CONST: JP 0 -CONIN: JP 0 -CONOUT: JP 0 -LIST: JP 0 -PUNCH: JP 0 -READER: JP 0 -HOME: JP 0 -SELDSK: JP 0 -SETTRK: JP 0 -SETSEC: JP 0 -SETDMA: JP 0 -READ: JP 0 -WRITE: JP 0 -PRSTAT: JP 0 -SECTRN: JP 0 -; -;* -;****************** E N D O F C P / M ***************** -;* - END - diff --git a/branches/s100/Applegate/cpm22.inc b/branches/s100/Applegate/cpm22.inc deleted file mode 100644 index 60405ae8..00000000 --- a/branches/s100/Applegate/cpm22.inc +++ /dev/null @@ -1,39 +0,0 @@ -;******************************************************** -; This file contains bits of information that are common -; between the CCP, BDOS and BIOS. Since the CCP and -; BDOS are built as one unit and the BIOS as another, it -; is handy to have common things in a common file rather -; that constantly needing to keep things in sync between -; two different files. -; -; 02/16/2013 - Bob Applegate - - -; -; This is the TOTAL RAM in the system. Ie, starts at 64 -; but then gets decreased due to ROM monitors at top of -; memory. This can be set artificially low to allow -; more room for BIOS debugging code. -; -; This is the amount of contiguous RAM from 0000. -; -RAMSIZE EQU 48 ;expressed in K - -; -; Low memory locations -; -IOBYTE EQU 3 ;i/o definition byte. -TDRIVE EQU 4 ;current drive name and user number. -ENTRY EQU 5 ;entry point for the cp/m bdos. - - - -CCPSIZE EQU 0800H ;I hate hard-coding things! -BDOSSIZE EQU 0E00H - -; -; Where CP/M things are located -; -CCPBASE equ (RAMSIZE-7)*1024 -BDOSBASE equ (CCPBASE+CCPSIZE) -BIOSBASE equ (BDOSBASE+BDOSSIZE) diff --git a/branches/s100/Applegate/loadcpm.py b/branches/s100/Applegate/loadcpm.py deleted file mode 100755 index 2fc1b81b..00000000 --- a/branches/s100/Applegate/loadcpm.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/python -# Written by Douglas Goodall 17:25 Wed, Jan 30, 2013 -# load cpm.bin and bios.bin then jump - -import sys -import os -import serial - -# passing in a string either "12" or "0x12" -# return value is string of hex digits only (no 0x) -def safebyte(parm): - xyz = parm - myord = ord(xyz) - hexdata = hex(myord) - newstr = hexdata - if (hexdata[0] == '0'): - if(hexdata[1] == 'x'): - newstr = hexdata[2] - if(len(hexdata)>3): - newstr = newstr + hexdata[3] - return newstr - -# passing in a string either "1234" of "0x1234" -# return value is string of hex digits only (1234) (no 0x) -def safeword(parm): - xyz = parm - myint = int(xyz) - hexdata = hex(myint) - newstr = hexdata - if (hexdata[0] == '0'): - if(hexdata[1] == 'x'): - newstr = hexdata[2] - if(len(hexdata)>3): - newstr = newstr + hexdata[3] - if(len(hexdata)>4): - newstr = newstr + hexdata[4] - if(len(hexdata)>5): - newstr = newstr + hexdata[5] - return newstr - -def loadngo(filename): - statinfo = os.stat(filename) - filelen = statinfo.st_size - infile = open(filename,'rb') - filedata = infile.read() - infile.close() - ser = serial.Serial('/dev/cu.PL2303-0000201D', 19200, timeout=10) - ser.write("\n\n") - ser.write("sa400\n") - print ser.read(12); - for x in range(1,filelen): - ser.write(safebyte(filedata[x-1])) - ser.write(" ") - print ser.read(12) - ser.write("\n") - print ser.read(12) - ser.close() - -print "*******************************************************************" -print "loadcpm.py 1/30/2013 dwg - load&go S-100 CP/M using master-yoda ROM" -print "*******************************************************************" -#loadngo("cpm.bin") -ser = serial.Serial('/dev/cu.PL2303-0000201D', 19200, timeout=1) -ser.read(128) -ser.read(128) -ser.write("\n") -ser.close() -loadngo("cpm.bin") - diff --git a/branches/s100/Applegate/s100iobd.inc b/branches/s100/Applegate/s100iobd.inc deleted file mode 100644 index 553ee3cb..00000000 --- a/branches/s100/Applegate/s100iobd.inc +++ /dev/null @@ -1,77 +0,0 @@ - .page -;******************************************************** -; These are I/O functions for the CCS 2710 four-port -; serial I/O board. -; -; Bob Applegate, 02/16/2008 -; -SIObase .equ 0E0H -; -SIODATA .equ SIObase -SIOBAUDL .equ SIObase ;also used for baud rate -SIOINTEN .equ SIObase+1 -SIOBAUDH .equ SIObase+1 ;ditto -SIOIDENT .equ SIObase+2 -SIOLCTRL .equ SIObase+3 -SIOMDMCT .equ SIObase+4 -SIOLSTAT .equ SIObase+5 -SIOMDMST .equ SIObase+6 -BAUD03 .equ 0180H ;divisor for 300 baud -BAUD12 .equ 060H ;1200 baud -BAUD_2400 .equ 030h ;2400 baud -BAUD96 .equ 00CH ;9600 baud -DATRDY .equ 01H ;rec'd data ready -TXMTY .equ 20H ;transmitter holding reg empty -HSMSK .equ 20H - -BAUD_RATE .equ BAUD_2400 - -; -; This function initializes the main console port for the -; default baud rate. -; -initser: ld a,0fH - out (SIOMDMCT),a - ld a,083H ;enable divisor latch access - out (SIOLCTRL),a - ld a,BAUD_RATE / 256 ;get hi byte - out (SIOBAUDH),a - ld a,BAUD_RATE % 256 ;get low byte - out (SIOBAUDL),a - ld a,03H ;8 data bits, one stop bit, no parity - out (SIOLCTRL),a - xor a ;clear acc - out (SIOINTEN),a ;disable ints - out (SIOLSTAT),a ;clear status - in a,(SIODATA) ;clear out any garbage in rec'd data reg - ret -; -; TTY output of character in C. Modifies A. -; -ttyout: IN A,(SIOLSTAT) ;was A,TTS, read status port - AND TXMTY ;check buffer empty bit - JR Z,ttyout ;branch if not empty - LD A,C - OUT (SIODATA),A ;was TTO,A, send out character - RET ;thassit -; -; Check to see if a character is ready to be read from the TTY. -; Returns TRUE (0ffh) in A is there is a character waiting, or -; FALSE (0) if there is nothing. -; -ttystat: IN A,(SIOLSTAT) ;was A,TTS - AND DATRDY - LD A,TRUE ;was FALSE - RET NZ - CPL - RET -; -; This gets the next character from the TTY and returns it in A. -; This will block if there is nothing waiting. -; -ttyin: IN A,(SIOLSTAT) ;read status reg - AND DATRDY ;look for data ready - JR Z,ttyin ;wait for char - IN a,(SIODATA) ;read character - RET - .page diff --git a/branches/s100/Applegate/tasm.inc b/branches/s100/Applegate/tasm.inc deleted file mode 100644 index e61cd62d..00000000 --- a/branches/s100/Applegate/tasm.inc +++ /dev/null @@ -1,19 +0,0 @@ -; -; To make it easier to port code from other assemblers, -; this maps some common psuedo-ops into TASM versions. -; -#define EQU .equ -#define equ .equ -#define END .end -#define end .end -#define DEFB .db -#define DB .db -#define db .db -#define DEFW .dw -#define DW .dw -#define dw .dw -#define DS .ds -#define ds .ds -#define ORG .org -#define org .org -#define TEXT .text diff --git a/branches/s100/Applegate/tasm.tab b/branches/s100/Applegate/tasm.tab deleted file mode 100644 index f644ccd4..00000000 --- a/branches/s100/Applegate/tasm.tab +++ /dev/null @@ -1,594 +0,0 @@ -"TASM Z80 Assembler. " -/**************************************************************************** -/* $Id: tasm80.tab 1.2 1998/02/28 14:31:22 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the Z80 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Carl A. Wall, VE3APY. -/* -/* Class bits assigned as follows: -/* Bit-0 = Z80 (base instruction set) -/* Bit-1 = HD64180 (extended instructions) -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OP BYTES RULE CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC A,(HL) 8E 1 NOP 1 -ADC A,(IX*) 8EDD 3 ZIX 1 -ADC A,(IY*) 8EFD 3 ZIX 1 -ADC A,A 8F 1 NOP 1 -ADC A,B 88 1 NOP 1 -ADC A,C 89 1 NOP 1 -ADC A,D 8A 1 NOP 1 -ADC A,E 8B 1 NOP 1 -ADC A,H 8C 1 NOP 1 -ADC A,L 8D 1 NOP 1 -ADC A,* CE 2 NOP 1 -ADC HL,BC 4AED 2 NOP 1 -ADC HL,DE 5AED 2 NOP 1 -ADC HL,HL 6AED 2 NOP 1 -ADC HL,SP 7AED 2 NOP 1 - -ADD A,(HL) 86 1 NOP 1 -ADD A,(IX*) 86DD 3 ZIX 1 -ADD A,(IY*) 86FD 3 ZIX 1 -ADD A,A 87 1 NOP 1 -ADD A,B 80 1 NOP 1 -ADD A,C 81 1 NOP 1 -ADD A,D 82 1 NOP 1 -ADD A,E 83 1 NOP 1 -ADD A,H 84 1 NOP 1 -ADD A,L 85 1 NOP 1 -ADD A,* C6 2 NOP 1 -ADD HL,BC 09 1 NOP 1 -ADD HL,DE 19 1 NOP 1 -ADD HL,HL 29 1 NOP 1 -ADD HL,SP 39 1 NOP 1 -ADD IX,BC 09DD 2 NOP 1 -ADD IX,DE 19DD 2 NOP 1 -ADD IX,IX 29DD 2 NOP 1 -ADD IX,SP 39DD 2 NOP 1 -ADD IY,BC 09FD 2 NOP 1 -ADD IY,DE 19FD 2 NOP 1 -ADD IY,IY 29FD 2 NOP 1 -ADD IY,SP 39FD 2 NOP 1 - -AND (HL) A6 1 NOP 1 -AND (IX*) A6DD 3 ZIX 1 -AND (IY*) A6FD 3 ZIX 1 -AND A A7 1 NOP 1 -AND B A0 1 NOP 1 -AND C A1 1 NOP 1 -AND D A2 1 NOP 1 -AND E A3 1 NOP 1 -AND H A4 1 NOP 1 -AND L A5 1 NOP 1 -AND * E6 2 NOP 1 - -BIT *,(HL) 46CB 2 ZBIT 1 -BIT *,(IX*) CBDD 4 ZBIT 1 0 4600 -BIT *,(IY*) CBFD 4 ZBIT 1 0 4600 -BIT *,A 47CB 2 ZBIT 1 -BIT *,B 40CB 2 ZBIT 1 -BIT *,C 41CB 2 ZBIT 1 -BIT *,D 42CB 2 ZBIT 1 -BIT *,E 43CB 2 ZBIT 1 -BIT *,H 44CB 2 ZBIT 1 -BIT *,L 45CB 2 ZBIT 1 - -CALL C,* DC 3 NOP 1 -CALL M,* FC 3 NOP 1 -CALL NC,* D4 3 NOP 1 -CALL NZ,* C4 3 NOP 1 -CALL P,* F4 3 NOP 1 -CALL PE,* EC 3 NOP 1 -CALL PO,* E4 3 NOP 1 -CALL Z,* CC 3 NOP 1 -CALL * CD 3 NOP 1 - -CCF "" 3F 1 NOP 1 - -CP (HL) BE 1 NOP 1 -CP (IX*) BEDD 3 ZIX 1 -CP (IY*) BEFD 3 ZIX 1 -CP A BF 1 NOP 1 -CP B B8 1 NOP 1 -CP C B9 1 NOP 1 -CP D BA 1 NOP 1 -CP E BB 1 NOP 1 -CP H BC 1 NOP 1 -CP L BD 1 NOP 1 -CP * FE 2 NOP 1 -CPD "" A9ED 2 NOP 1 -CPDR "" B9ED 2 NOP 1 -CPIR "" B1ED 2 NOP 1 -CPI "" A1ED 2 NOP 1 -CPL "" 2F 1 NOP 1 - -DAA "" 27 1 NOP 1 - -DEC (HL) 35 1 NOP 1 -DEC (IX*) 35DD 3 ZIX 1 -DEC (IY*) 35FD 3 ZIX 1 -DEC A 3D 1 NOP 1 -DEC B 05 1 NOP 1 -DEC BC 0B 1 NOP 1 -DEC C 0D 1 NOP 1 -DEC D 15 1 NOP 1 -DEC DE 1B 1 NOP 1 -DEC E 1D 1 NOP 1 -DEC H 25 1 NOP 1 -DEC HL 2B 1 NOP 1 -DEC IX 2BDD 2 NOP 1 -DEC IY 2BFD 2 NOP 1 -DEC L 2D 1 NOP 1 -DEC SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -DJNZ * 10 2 R1 1 - -EI "" FB 1 NOP 1 -EX (SP),HL E3 1 NOP 1 -EX (SP),IX E3DD 2 NOP 1 -EX (SP),IY E3FD 2 NOP 1 -EX AF,AF' 08 1 NOP 1 -EX DE,HL EB 1 NOP 1 -EXX "" D9 1 NOP 1 -HALT "" 76 1 NOP 1 - -IM 0 46ED 2 NOP 1 -IM 1 56ED 2 NOP 1 -IM 2 5EED 2 NOP 1 - -/* Alternate form of above -IM0 46ED 2 NOP 1 -IM1 56ED 2 NOP 1 -IM2 5EED 2 NOP 1 - -IN A,(C) 78ED 2 NOP 1 -IN B,(C) 40ED 2 NOP 1 -IN C,(C) 48ED 2 NOP 1 -IN D,(C) 50ED 2 NOP 1 -IN E,(C) 58ED 2 NOP 1 -IN H,(C) 60ED 2 NOP 1 -IN L,(C) 68ED 2 NOP 1 - -IN A,(*) DB 2 NOP 1 - -IN0 A,(*) 38ED 3 NOP 2 -IN0 B,(*) 00ED 3 NOP 2 -IN0 C,(*) 08ED 3 NOP 2 -IN0 D,(*) 10ED 3 NOP 2 -IN0 E,(*) 18ED 3 NOP 2 -IN0 H,(*) 20ED 3 NOP 2 -IN0 L,(*) 28ED 3 NOP 2 - -INC (HL) 34 1 NOP 1 -INC (IX*) 34DD 3 ZIX 1 -INC (IY*) 34FD 3 ZIX 1 -INC A 3C 1 NOP 1 -INC B 04 1 NOP 1 -INC BC 03 1 NOP 1 -INC C 0C 1 NOP 1 -INC D 14 1 NOP 1 -INC DE 13 1 NOP 1 -INC E 1C 1 NOP 1 -INC H 24 1 NOP 1 -INC HL 23 1 NOP 1 -INC IX 23DD 2 NOP 1 -INC IY 23FD 2 NOP 1 -INC L 2C 1 NOP 1 -INC SP 33 1 NOP 1 - - -IND "" AAED 2 NOP 1 -INDR "" BAED 2 NOP 1 -INI "" A2ED 2 NOP 1 -INIR "" B2ED 2 NOP 1 - -JP (HL) E9 1 NOP 1 -JP (IX) E9DD 2 NOP 1 -JP (IY) E9FD 2 NOP 1 -JP C,* DA 3 NOP 1 -JP M,* FA 3 NOP 1 -JP NC,* D2 3 NOP 1 -JP NZ,* C2 3 NOP 1 -JP P,* F2 3 NOP 1 -JP PE,* EA 3 NOP 1 -JP PO,* E2 3 NOP 1 -JP Z,* CA 3 NOP 1 -JP * C3 3 NOP 1 - -JR C,* 38 2 R1 1 -JR NC,* 30 2 R1 1 -JR NZ,* 20 2 R1 1 -JR Z,* 28 2 R1 1 -JR * 18 2 R1 1 - -LD (BC),A 02 1 NOP 1 -LD (DE),A 12 1 NOP 1 -LD (HL),A 77 1 NOP 1 -LD (HL),B 70 1 NOP 1 -LD (HL),C 71 1 NOP 1 -LD (HL),D 72 1 NOP 1 -LD (HL),E 73 1 NOP 1 -LD (HL),H 74 1 NOP 1 -LD (HL),L 75 1 NOP 1 -LD (HL),* 36 2 NOP 1 -LD (IX*),A 77DD 3 ZIX 1 -LD (IX*),B 70DD 3 ZIX 1 -LD (IX*),C 71DD 3 ZIX 1 -LD (IX*),D 72DD 3 ZIX 1 -LD (IX*),E 73DD 3 ZIX 1 -LD (IX*),H 74DD 3 ZIX 1 -LD (IX*),L 75DD 3 ZIX 1 -LD (IX*),* 36DD 4 ZIX 1 -LD (IY*),A 77FD 3 ZIX 1 -LD (IY*),B 70FD 3 ZIX 1 -LD (IY*),C 71FD 3 ZIX 1 -LD (IY*),D 72FD 3 ZIX 1 -LD (IY*),E 73FD 3 ZIX 1 -LD (IY*),H 74FD 3 ZIX 1 -LD (IY*),L 75FD 3 ZIX 1 -LD (IY*),* 36FD 4 ZIX 1 -LD (*),A 32 3 NOP 1 -LD (*),BC 43ED 4 NOP 1 -LD (*),DE 53ED 4 NOP 1 -LD (*),HL 22 3 NOP 1 -LD (*),IX 22DD 4 NOP 1 -LD (*),IY 22FD 4 NOP 1 -LD (*),SP 73ED 4 NOP 1 -LD A,(BC) 0A 1 NOP 1 -LD A,(DE) 1A 1 NOP 1 -LD A,(HL) 7E 1 NOP 1 -LD A,(IX*) 7EDD 3 ZIX 1 -LD A,(IY*) 7EFD 3 ZIX 1 -LD A,A 7F 1 NOP 1 -LD A,B 78 1 NOP 1 -LD A,C 79 1 NOP 1 -LD A,D 7A 1 NOP 1 -LD A,E 7B 1 NOP 1 -LD A,H 7C 1 NOP 1 -LD A,I 57ED 2 NOP 1 -LD A,L 7D 1 NOP 1 -LD A,R 5FED 2 NOP 1 -LD A,(*) 3A 3 NOP 1 -LD A,* 3E 2 NOP 1 -LD B,(HL) 46 1 NOP 1 -LD B,(IX*) 46DD 3 ZIX 1 -LD B,(IY*) 46FD 3 ZIX 1 -LD B,A 47 1 NOP 1 -LD B,B 40 1 NOP 1 -LD B,C 41 1 NOP 1 -LD B,D 42 1 NOP 1 -LD B,E 43 1 NOP 1 -LD B,H 44 1 NOP 1 -LD B,L 45 1 NOP 1 -LD B,* 06 2 NOP 1 -LD BC,(*) 4BED 4 NOP 1 -LD BC,* 01 3 NOP 1 -LD C,(HL) 4E 1 NOP 1 -LD C,(IX*) 4EDD 3 ZIX 1 -LD C,(IY*) 4EFD 3 ZIX 1 -LD C,A 4F 1 NOP 1 -LD C,B 48 1 NOP 1 -LD C,C 49 1 NOP 1 -LD C,D 4A 1 NOP 1 -LD C,E 4B 1 NOP 1 -LD C,H 4C 1 NOP 1 -LD C,L 4D 1 NOP 1 -LD C,* 0E 2 NOP 1 -LD D,(HL) 56 1 NOP 1 -LD D,(IX*) 56DD 3 ZIX 1 -LD D,(IY*) 56FD 3 ZIX 1 -LD D,A 57 1 NOP 1 -LD D,B 50 1 NOP 1 -LD D,C 51 1 NOP 1 -LD D,D 52 1 NOP 1 -LD D,E 53 1 NOP 1 -LD D,H 54 1 NOP 1 -LD D,L 55 1 NOP 1 -LD D,* 16 2 NOP 1 -LD DE,(*) 5BED 4 NOP 1 -LD DE,* 11 3 NOP 1 -LD E,(HL) 5E 1 NOP 1 -LD E,(IX*) 5EDD 3 ZIX 1 -LD E,(IY*) 5EFD 3 ZIX 1 -LD E,A 5F 1 NOP 1 -LD E,B 58 1 NOP 1 -LD E,C 59 1 NOP 1 -LD E,D 5A 1 NOP 1 -LD E,E 5B 1 NOP 1 -LD E,H 5C 1 NOP 1 -LD E,L 5D 1 NOP 1 -LD E,* 1E 2 NOP 1 -LD H,(HL) 66 1 NOP 1 -LD H,(IX*) 66DD 3 ZIX 1 -LD H,(IY*) 66FD 3 ZIX 1 -LD H,A 67 1 NOP 1 -LD H,B 60 1 NOP 1 -LD H,C 61 1 NOP 1 -LD H,D 62 1 NOP 1 -LD H,E 63 1 NOP 1 -LD H,H 64 1 NOP 1 -LD H,L 65 1 NOP 1 -LD H,* 26 2 NOP 1 -LD HL,(*) 2A 3 NOP 1 -LD HL,* 21 3 NOP 1 -LD I,A 47ED 2 NOP 1 -LD IX,(*) 2ADD 4 NOP 1 -LD IX,* 21DD 4 NOP 1 -LD IY,(*) 2AFD 4 NOP 1 -LD IY,* 21FD 4 NOP 1 -LD L,(HL) 6E 1 NOP 1 -LD L,(IX*) 6EDD 3 ZIX 1 -LD L,(IY*) 6EFD 3 ZIX 1 -LD L,A 6F 1 NOP 1 -LD L,B 68 1 NOP 1 -LD L,C 69 1 NOP 1 -LD L,D 6A 1 NOP 1 -LD L,E 6B 1 NOP 1 -LD L,H 6C 1 NOP 1 -LD L,L 6D 1 NOP 1 -LD L,* 2E 2 NOP 1 -LD R,A 4FED 2 NOP 1 -LD SP,(*) 7BED 4 NOP 1 -LD SP,HL F9 1 NOP 1 -LD SP,IX F9DD 2 NOP 1 -LD SP,IY F9FD 2 NOP 1 -LD SP,* 31 3 NOP 1 -LDD "" A8ED 2 NOP 1 -LDDR "" B8ED 2 NOP 1 -LDI "" A0ED 2 NOP 1 -LDIR "" B0ED 2 NOP 1 -NEG "" 44ED 2 NOP 1 -NOP "" 00 1 NOP 1 - -MLT BC 4CED 2 NOP 2 -MLT DE 5CED 2 NOP 2 -MLT HL 6CED 2 NOP 2 -MLT SP 7CED 2 NOP 2 - -OR (HL) B6 1 NOP 1 -OR (IX*) B6DD 3 ZIX 1 -OR (IY*) B6FD 3 ZIX 1 -OR A B7 1 NOP 1 -OR B B0 1 NOP 1 -OR C B1 1 NOP 1 -OR D B2 1 NOP 1 -OR E B3 1 NOP 1 -OR H B4 1 NOP 1 -OR L B5 1 NOP 1 -OR * F6 2 NOP 1 - -OTDM "" 8BED 2 NOP 2 -OTDMR "" 9BED 2 NOP 2 -OTDR "" BBED 2 NOP 1 -OTIM "" 83ED 2 NOP 2 -OTIMR "" 93ED 2 NOP 2 -OTIR "" B3ED 2 NOP 1 - -OUT (C),A 79ED 2 NOP 1 -OUT (C),B 41ED 2 NOP 1 -OUT (C),C 49ED 2 NOP 1 -OUT (C),D 51ED 2 NOP 1 -OUT (C),E 59ED 2 NOP 1 -OUT (C),H 61ED 2 NOP 1 -OUT (C),L 69ED 2 NOP 1 -OUT (*),A D3 2 NOP 1 - -OUT0 (*),A 39ED 3 NOP 2 -OUT0 (*),B 01ED 3 NOP 2 -OUT0 (*),C 09ED 3 NOP 2 -OUT0 (*),D 11ED 3 NOP 2 -OUT0 (*),E 19ED 3 NOP 2 -OUT0 (*),H 21ED 3 NOP 2 -OUT0 (*),L 29ED 3 NOP 2 - -OUTD "" ABED 2 NOP 1 -OUTI "" A3ED 2 NOP 1 - -POP AF F1 1 NOP 1 -POP BC C1 1 NOP 1 -POP DE D1 1 NOP 1 -POP HL E1 1 NOP 1 -POP IX E1DD 2 NOP 1 -POP IY E1FD 2 NOP 1 - -PUSH AF F5 1 NOP 1 -PUSH BC C5 1 NOP 1 -PUSH DE D5 1 NOP 1 -PUSH HL E5 1 NOP 1 -PUSH IX E5DD 2 NOP 1 -PUSH IY E5FD 2 NOP 1 - -RES *,(HL) 86CB 2 ZBIT 1 -RES *,(IX*) CBDD 4 ZBIT 1 0 8600 -RES *,(IY*) CBFD 4 ZBIT 1 0 8600 -RES *,A 87CB 2 ZBIT 1 -RES *,B 80CB 2 ZBIT 1 -RES *,C 81CB 2 ZBIT 1 -RES *,D 82CB 2 ZBIT 1 -RES *,E 83CB 2 ZBIT 1 -RES *,H 84CB 2 ZBIT 1 -RES *,L 85CB 2 ZBIT 1 - -RET "" C9 1 NOP 1 -RET C D8 1 NOP 1 -RET M F8 1 NOP 1 -RET NC D0 1 NOP 1 -RET NZ C0 1 NOP 1 -RET P F0 1 NOP 1 -RET PE E8 1 NOP 1 -RET PO E0 1 NOP 1 -RET Z C8 1 NOP 1 -RETI "" 4DED 2 NOP 1 -RETN "" 45ED 2 NOP 1 - -RL (HL) 16CB 2 NOP 1 -RL (IX*) CBDD 4 ZIX 1 0 1600 -RL (IY*) CBFD 4 ZIX 1 0 1600 -RL A 17CB 2 NOP 1 -RL B 10CB 2 NOP 1 -RL C 11CB 2 NOP 1 -RL D 12CB 2 NOP 1 -RL E 13CB 2 NOP 1 -RL H 14CB 2 NOP 1 -RL L 15CB 2 NOP 1 -RLA "" 17 1 NOP 1 - -RLC (HL) 06CB 2 NOP 1 -RLC (IX*) CBDD 4 ZIX 1 0 0600 -RLC (IY*) CBFD 4 ZIX 1 0 0600 -RLC A 07CB 2 NOP 1 -RLC B 00CB 2 NOP 1 -RLC C 01CB 2 NOP 1 -RLC D 02CB 2 NOP 1 -RLC E 03CB 2 NOP 1 -RLC H 04CB 2 NOP 1 -RLC L 05CB 2 NOP 1 -RLCA "" 07 1 NOP 1 -RLD "" 6FED 2 NOP 1 - -RR (HL) 1ECB 2 NOP 1 -RR (IX*) CBDD 4 ZIX 1 0 1E00 -RR (IY*) CBFD 4 ZIX 1 0 1E00 -RR A 1FCB 2 NOP 1 -RR B 18CB 2 NOP 1 -RR C 19CB 2 NOP 1 -RR D 1ACB 2 NOP 1 -RR E 1BCB 2 NOP 1 -RR H 1CCB 2 NOP 1 -RR L 1DCB 2 NOP 1 -RRA "" 1F 1 NOP 1 -RRC (HL) 0ECB 2 NOP 1 -RRC (IX*) CBDD 4 ZIX 1 0 0E00 -RRC (IY*) CBFD 4 ZIX 1 0 0E00 -RRC A 0FCB 2 NOP 1 -RRC B 08CB 2 NOP 1 -RRC C 09CB 2 NOP 1 -RRC D 0ACB 2 NOP 1 -RRC E 0BCB 2 NOP 1 -RRC H 0CCB 2 NOP 1 -RRC L 0DCB 2 NOP 1 -RRCA "" 0F 1 NOP 1 -RRD "" 67ED 2 NOP 1 - -RST 00H C7 1 NOP 1 -RST 08H CF 1 NOP 1 -RST 10H D7 1 NOP 1 -RST 18H DF 1 NOP 1 -RST 20H E7 1 NOP 1 -RST 28H EF 1 NOP 1 -RST 30H F7 1 NOP 1 -RST 38H FF 1 NOP 1 - -/* Alternate form of above -RST 00 C7 1 NOP 1 -RST 08 CF 1 NOP 1 -RST 10 D7 1 NOP 1 -RST 18 DF 1 NOP 1 -RST 20 E7 1 NOP 1 -RST 28 EF 1 NOP 1 -RST 30 F7 1 NOP 1 -RST 38 FF 1 NOP 1 - -SBC A,(HL) 9E 1 NOP 1 -SBC A,(IX*) 9EDD 3 ZIX 1 -SBC A,(IY*) 9EFD 3 ZIX 1 -SBC A,A 9F 1 NOP 1 -SBC A,B 98 1 NOP 1 -SBC A,C 99 1 NOP 1 -SBC A,D 9A 1 NOP 1 -SBC A,E 9B 1 NOP 1 -SBC A,H 9C 1 NOP 1 -SBC A,L 9D 1 NOP 1 -SBC HL,BC 42ED 2 NOP 1 -SBC HL,DE 52ED 2 NOP 1 -SBC HL,HL 62ED 2 NOP 1 -SBC HL,SP 72ED 2 NOP 1 -SBC A,* DE 2 NOP 1 -SCF "" 37 1 NOP 1 - -SET *,(HL) C6CB 2 ZBIT 1 -SET *,(IX*) CBDD 4 ZBIT 1 0 C600 -SET *,(IY*) CBFD 4 ZBIT 1 0 C600 -SET *,A C7CB 2 ZBIT 1 -SET *,B C0CB 2 ZBIT 1 -SET *,C C1CB 2 ZBIT 1 -SET *,D C2CB 2 ZBIT 1 -SET *,E C3CB 2 ZBIT 1 -SET *,H C4CB 2 ZBIT 1 -SET *,L C5CB 2 ZBIT 1 - -SLA (HL) 26CB 2 NOP 1 -SLA (IX*) CBDD 4 ZIX 1 0 2600 -SLA (IY*) CBFD 4 ZIX 1 0 2600 -SLA A 27CB 2 NOP 1 -SLA B 20CB 2 NOP 1 -SLA C 21CB 2 NOP 1 -SLA D 22CB 2 NOP 1 -SLA E 23CB 2 NOP 1 -SLA H 24CB 2 NOP 1 -SLA L 25CB 2 NOP 1 - -SLP "" 76ED 2 NOP 2 - -SRA (HL) 2ECB 2 NOP 1 -SRA (IX*) CBDD 4 ZIX 1 0 2E00 -SRA (IY*) CBFD 4 ZIX 1 0 2E00 -SRA A 2FCB 2 NOP 1 -SRA B 28CB 2 NOP 1 -SRA C 29CB 2 NOP 1 -SRA D 2ACB 2 NOP 1 -SRA E 2BCB 2 NOP 1 -SRA H 2CCB 2 NOP 1 -SRA L 2DCB 2 NOP 1 - -SRL (HL) 3ECB 2 NOP 1 -SRL (IX*) CBDD 4 ZIX 1 0 3E00 -SRL (IY*) CBFD 4 ZIX 1 0 3E00 -SRL A 3FCB 2 NOP 1 -SRL B 38CB 2 NOP 1 -SRL C 39CB 2 NOP 1 -SRL D 3ACB 2 NOP 1 -SRL E 3BCB 2 NOP 1 -SRL H 3CCB 2 NOP 1 -SRL L 3DCB 2 NOP 1 - -SUB (HL) 96 1 NOP 1 -SUB (IX*) 96DD 3 ZIX 1 -SUB (IY*) 96FD 3 ZIX 1 -SUB A 97 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB * D6 2 NOP 1 - -TST A 3CED 2 NOP 2 -TST B 04ED 2 NOP 2 -TST C 0CED 2 NOP 2 -TST D 14ED 2 NOP 2 -TST E 1CED 2 NOP 2 -TST H 24ED 2 NOP 2 -TST L 2CED 2 NOP 2 -TST (HL) 34ED 2 NOP 2 -TST * 64ED 3 NOP 2 - -TSTIO * 74ED 3 NOP 2 - -XOR (HL) AE 1 NOP 1 -XOR (IX*) AEDD 3 ZIX 1 -XOR (IY*) AEFD 3 ZIX 1 -XOR A AF 1 NOP 1 -XOR B A8 1 NOP 1 -XOR C A9 1 NOP 1 -XOR D AA 1 NOP 1 -XOR E AB 1 NOP 1 -XOR H AC 1 NOP 1 -XOR L AD 1 NOP 1 -XOR * EE 2 NOP 1 diff --git a/branches/s100/Applegate/zapple.asm b/branches/s100/Applegate/zapple.asm deleted file mode 100644 index 3b522a72..00000000 --- a/branches/s100/Applegate/zapple.asm +++ /dev/null @@ -1,80 +0,0 @@ -; -;================================================================================================== -; WRAPPER FOR ZAPPLE MONITOR FOR N8VEM PROJECT -; WAYNE WARTHEN - 2012-11-26 -;================================================================================================== -; -; THE FOLLOWING MACROS DO THE HEAVY LIFTING TO MAKE THE ZAPPLE SOURCE -; COMPATIBLE WITH TASM -; -#DEFINE EQU .EQU -#DEFINE NAME \; -#DEFINE PAGE .PAGE -#DEFINE CSEG .CSEG -#DEFINE DSEG .DSEG -#DEFINE ORG .ORG -#DEFINE END .END -#DEFINE IF .IF -#DEFINE ELSE .ELSE -#DEFINE ENDIF .ENDIF -#DEFINE DEFB .DB -#DEFINE DB .DB -#DEFINE DEFW .DW -#DEFINE DW .DW -#DEFINE . _ -#DEFINE TITLE .TITLE -#DEFINE EXT \; -#DEFINE NOT ~ -; -#ADDINSTR IN A,* DB 2 NOP 1 -#ADDINSTR OUT *,A D3 2 NOP 1 -#ADDINSTR ADD A 87 1 NOP 1 -#ADDINSTR ADD D 82 1 NOP 1 -#ADDINSTR ADD * C6 2 NOP 1 -#ADDINSTR ADC A 8F 1 NOP 1 -#ADDINSTR ADC * CE 2 NOP 1 -#ADDINSTR SBC H 9C 1 NOP 1 -; -; -; -COLOC .EQU 0 -LNLOC .EQU 0 -LULOC .EQU 0 -PTPL .EQU 0 -PULOC .EQU 0 -CSLOC .EQU 0 -CILOC .EQU 0 -RPTPL .EQU 0 -RULOC .EQU 0 -; -; 16C550 SERIAL LINE UART -; -SIO_BASE .EQU 90H -SIO_RBR .EQU SIO_BASE + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY) -SIO_THR .EQU SIO_BASE + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY) -SIO_IER .EQU SIO_BASE + 1 ; DLAB=0: INT ENABLE REG -SIO_IIR .EQU SIO_BASE + 2 ; INT IDENT REGISTER (READ ONLY) -SIO_FCR .EQU SIO_BASE + 2 ; FIFO CONTROL REG (WRITE ONLY) -SIO_LCR .EQU SIO_BASE + 3 ; LINE CONTROL REG -SIO_MCR .EQU SIO_BASE + 4 ; MODEM CONTROL REG -SIO_LSR .EQU SIO_BASE + 5 ; LINE STATUS REG -SIO_MSR .EQU SIO_BASE + 6 ; MODEM STATUS REG -SIO_SCR .EQU SIO_BASE + 7 ; SCRATCH REGISTER -SIO_DLL .EQU SIO_BASE + 0 ; DLAB=1: DIVISOR LATCH (LS) -SIO_DLM .EQU SIO_BASE + 1 ; DLAB=1: DIVISOR LATCH (MS) -; -BAUDRATE .EQU 38400 -UART_DIV .EQU (1843200 / (16 * BAUDRATE)) -; -; -; -BASE .EQU $6000 - -; -; NOW INCLUDE THE MAIN SOURCE -; -#INCLUDE "zapple.z80" -; - .FILL $7000 - $ -; - .END diff --git a/branches/s100/Applegate/zapple.z80 b/branches/s100/Applegate/zapple.z80 deleted file mode 100644 index 2505962c..00000000 --- a/branches/s100/Applegate/zapple.z80 +++ /dev/null @@ -1,1940 +0,0 @@ -; << ZAPPLE 2-K MONITOR SYSTEM >> -; by -; -; TECHNICAL DESIGN LABS, INC. -; RESEARCH PARK -; PRINCETON, NEW JERSEY 08540 -; -; COPYRIGHT JULY 1976 BY TDL INC. -; -; ASSEMBLED BY ROGER AMIDON -; -; -;BASE: EQU 0F000H ; WW: NOW DEFINED IN WRAPPER -USER: EQU BASE+800H -; - TITLE -; -RST7: EQU 38H ;RST 7 (LOCATION FOR TRAP) -;WW IOBYT: EQU 76H ;R/W PORT FOR TEMP. STORAGE -IOBYT: EQU SIO_SCR ; WW - USING UART SPR FOR TEMP. STORAGE -;WW SENSE: EQU 7AH ;PORT FOR INITIAL I/O CMNFIGURATIOL (IN) -;WW SWITCH: EQU 0FFH ;FRONT PANEL SENSE SWITCHES -;WW RCP: EQU 7AH ;READER CONTROL PORT (OUT) -;WW NN: EQU 0F8H ;"I" REGISTER INITIAL VALUE -; -; EXTERNAL EQUATES -; - NAME ZAPPLE - EXT COLOC - EXT LNLOC - EXT LULOC - EXT PTPL - EXT PULOC - EXT CSLOC - EXT CILOC - EXT RPTPL - EXT RULOC -; -; -; -; -;-TELEPRINTER -; -; WW: VALUES BELOW MODIFIED FOR N8VEM STD UART PORTS -TTI: EQU SIO_RBR ;DATA IN PORT -TTO: EQU SIO_THR ;DATA OUT PORT -TTS: EQU SIO_LSR ;STATUS PORT (IN) -TTYDA: EQU $01 ;DATA AVAILABLE MASK BIT -TTYBE: EQU $20 ;XMTR BUFFER EMPTY MASK -; -;-C.R.T. SYSTEM -; -CRTI: EQU 51H ;DATA PORT (IN) -CRTS: EQU 50H ;STATUS PORT (IN) -CRTO: EQU 51H ;DATA PORT (OUT) -CRTDA: EQU 40H ;DATA AVAILABLE MASK -CRTBE: EQU 80H ;XMTR BUFFER EMPTY MASK -; -;-CASSETTE SYSTEM -; -RCSD: EQU 61H ;DATA IN PORT -RCSS: EQU 60H ;STATUS PORT (IN) -RCSDA: EQU 40H ;DATA AVAILABLE MASK -PCASO: EQU 61H ;DATA PORT (OUT) -PCASS: EQU 60H ;CONTROL PORT (OUT) -PCSBE: EQU 80H ;XMTR BUFFER EMPTY MASK -; -; -; -FALSE: EQU 0 ;ISN'T SO -TRUE: EQU NOT FALSE ;IT IS SO -CR: EQU 0DH ;ASCII CARRIAGE RETURN -LF: EQU 0AH ;ASCII LINE FEED -BELL: EQU 7 ;DING -RUB: EQU 0FFH ;RUB OUT -FIL: EQU 00 ;FILL CHARACTER AFTER CRLF -MAX: EQU 7 ;NUMBER OF QUES IN EOF -; -; -; -CMSK: EQU 11111100B ;CONSOLE DEVICE -RMSK: EQU 11110011B ;STORAGE DEVICE (IN) -PMSK: EQU 11001111B ;STORAGE DEVICE (OUT) -LMSK: EQU 00111111B ;LIST DEVICE -; -; -;-CONSOLE CONFIGURATION -CTTY: EQU 0 ;TELEPRINTER -CCRT: EQU 1 ;C.R.T. -BATCH: EQU 2 ;READER FOR INPUT, LIST FOR OUTPUT -CUSE: EQU 3 ;USER DEFINED -; -;-STORAGE INPUT CONFIGURATION -RTTY: EQU 0 ;TELEPRINTER READER -RPTR: EQU 4 ;HIGH-SPEED RDR (EXTERNAL ROUTINE) -RCAS: EQU 8 ;CASSETTE -RUSER: EQU 0CH ;USER DEFINED -; -;-STORAGE OUTPUT CONFIGURATION -PTTY: EQU 0 ;TELEPRINTER PUNCH -PPTP: EQU 10H ;HIGH-SPEED PUNCH (EXTERNAL ROUTINE) -PCAS: EQU 20H ;CASSETTE -PUSER: EQU 30H ;USER DEFINED -; -;-LIST DEVICE CONFIGURATION -LTTY: EQU 0 ;TELEPRINTER PRINTER -LCRT: EQU 40H ;C.R.T. SCREEN -LINE: EQU 80H ;LINE PRINTER (EXTERNAL ROUTINE) -LUSER: EQU 0C0H ;USER DEFINED -; -; -; VECTOR FOR USER DEFINED ROUTINES -; -;.LOC: USER -;CILOC: .BLKB 3 ;CONSOLE INPUT -;COLOC: .BLKB 3 ;CONSOLE OUTPUT -;RPTPL: .BLKB 3 ;HIGH-SPEED READER -;RULOC: .BLKB 3 ;USER DEFINED STORAGE (INPUT) -;PTPL: .BLKB 3 ;HIGH-SPEED PUNCH -;PULOC: .BLKB 3 ;USER DEFINED STORAGE (OUTPUT) -;LNLOC: .BLKB 3 ;LINE PRINTER -;LULOC: .BLKB 3 ;USER DEFINED PRINTER -;CSLOC: .BLKB 3 ;CONSOLE INPUT STATUS ROUTINE -;J: =. -; -; PROGRAM CODE BEGINS HERE -; -; - .ORG BASE ; WW: MODIFIED FOR TASM SYNTAX - JP BEGIN ;GO AROUND VECTORS -; -; -; -; THESE VECTORS MAY BE USED BY USER WRITTEN -; PROGRAMS TO SIMPLIFY THE HANDLING OF I/O -; FROM SYSTEM TO SYSTEM. WHATEVER THE CURRENT -; ASSIGNED DEVICE, THESE VECTORS WILL PERFORM -; THE REQUIRED I/O OPERATION, AND RETURN TO -; THE CALLING PROGRAM. (RET) -; -; THE REGISTER CONVENTION USED FOLLOWS- -; -; ANY INPUT OR OUTPUT DEVICE -; CHARACTER TO BE OUTPUT IN 'C' REGISTER. -; CHARACTER WILL BE IN 'A' REGISTER UPON -; RETURNING FROM AN INPUT OR OUTPUT. -; 'CSTS'- -; RETURN TRUE (0FFH IN 'A' REG.) IF THERE IS -; SOMETHING WAITING, AND ZERO (00) IF NOT. -; 'IOCHK'- -; RETURN WITH THE CURRENT I/O CONFIGURATION -; BYTE IN 'A' REGISTER. -; 'IOSET'- -; ALLOWS A PROGRAM TO DYNAMICALLY ALTER THE -; CURRENT I/O CONFIGURATION, AND REQUIRES -; THE NEW BYTE IN 'C' REGISTER. -; 'MEMCK'- -; RETURNS WITH THE HIGHEST ALLOWED USER -; MEMORY LOCATION. 'B'=HIGH BYTE, 'A'=LOW. -; 'TRAP'- -; THIS IS THE 'BREAKPOINT' ENTRY POINT, -; BUT MAY BE 'CALLED'. IT WILL SAVE -; THE MACHINE STATE. RETURN CAN BE MADE WITH -; A SIMPLE 'G[CR]' ON THE CONSOLE. -; - JP CI ;CONSOLE INPUT - JP RI ;READER INPUT - JP CO ;CONSOLE OUTPUT - JP PUO ;PUNCH OUTPUT - JP LO ;LIST OUTPUT - JP CSTS ;CONSOLE STATUS - JP IOCHK ;I/O CHECK - JP IOSET ;I/O SET - JP MEMCK ;MEMORY LIMIT CHECK -TRAP: JP RESTART ;BREAKPOINT -; -; ANNOUNCEMENT OF MONITOR NAME & VERSION -MSG: DB CR,LF,FIL,FIL,FIL - DB "Zapple V" ; WW: CHANGED TO DQUOTES - DB "1.1" ; WW: CHANGED TO DQUOTES -MSGL: EQU $-MSG -; -; LET US BEGIN -; -; -; *NOTE- THE CODE UP TO THE 'IN SENSE' MAY -; BE REPLACED BY ENOUGH CODE TO INITIALIZE -; AN ACIA OR SIO DEVICE. ADDITIONAL DEVICES -; MAY BE INITIALIZED USING THE 'Q' COMMAND. -; (OR STANDARD ROUTINES FOR INITILIZATION -; MAY BE LOADED & EXECUTED IN THE USER AREA). -; -BEGIN: ;WW LD A,NN ;FOR 'I' REG. IF NEEDED. - ;WW LD I,A - ;WW NOP ;SPARE BYTE - ;WW XOR A ;CLEAR READER CONTROL PORT - ;WW OUT RCP,A -; - ;WW IN A,SENSE ;INITIALIZE I/O CONFIGURARTION - LD A,$FF ; WW - INIT IOBYT TO $FF (NOTE IT IS INVERTED WHEN USED) - OUT IOBYT,A - LD SP,AHEAD-4 ;SET UP A FAKE STACK - JP MEMSIZ+1 ;GET MEMORY SIZE - DEFW AHEAD -AHEAD: LD SP,HL ;SET TRUE STACK - EX DE,HL - LD BC,ENDX-EXIT - LD HL,EXIT - LDIR ;MOVE TO RAM - EX DE,HL - LD BC,-5FH ;SET UP A USER'S STACK VALUE - ADD HL,BC - PUSH HL ;PRE-LOAD USER'S STACK VALUE - LD HL,0 ;INITIALIZE OTHER REGISTERS - LD B,10 ; (16 OF THEM) -STKIT: PUSH HL ; TO ZERO - DJNZ STKIT -HELLO: LD B,MSGL ;SAY HELLO TO THE FOLKS - CALL TOM ;OUTPUT SIGN-ON MSG -START: LD DE,START ;MAIN 'WORK' LOOP - PUSH DE ;SET UP A RETURN TO HERE - CALL CRLF - LD C,'>' - CALL CO -STARO: CALL TI ;GET A CONSOLE CHARACTER - AND 7FH ;IGNORE NULLS - JR Z,STARO ;GET ANOTHER - SUB 'A' ;QUALIFY THE CHARACTER - RET M ;Z - ADD A ;A*2 - LD B,0 - LD C,A ;POINT TO PLACE ON TABLE - LD HL,TBL ;POINT TO COMMAND TABLE - ADD HL,BC ;ADD IN DISPLACEMENT - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ;D&E=ROUTINE ADDRESS - LD C,2 ;SET C UP - JP (HL) ;GO EXECUTE COMMAND -; -; -; -TBL: - DEFW ASSIGN ;A - ASSIGN I/O - DEFW BYE ;B - SYSTEM SHUT-DOWN - DEFW COMP ;C - COMPARE MEMORY VS. READER INPUT - DEFW DISP ;D - DISPLAY MEMORY ON CONS. IN HEX - DEFW EOF ;E - END OF FILE TAG FOR HEX DUMPS - DEFW FILL ;F - FILL MEMORY WITH A CONSTANT - DEFW GOTO ;G - GOTO [ADDR] <,>BREAKPOINTS (2) - DEFW HEXN ;H - HEX MATH. , - DEFW ERROR ;I * USER DEFINED, INSERT VECTOR -; J=J ;VECTOR ADDR - DEFW TEST ;J - NON-DESTRUCTIVE MEMORY TEST - DEFW ERROR ;K * USER DEFINED, INSERT VECTOR -; J=J+3 ;VECTOR ADDR - DEFW LOAD ;L - MOVE A BINARY FORMAT FILE - DEFW MOVE ;M - MOVE BLOCKS OF MEMORY - DEFW NULL ;N - PUNCH NULLS ON PUNCH DEVICE - DEFW ERROR ;O * USER DEFINED, INSERT VECTOR -; J=J+3 ;VECTOR ADDR - DEFW PUTA ;P - 'PUT' ASCII INTO MEMORY. - DEFW QUERY ;Q - QI(N)=DISP. N; QO(N,V)=OUT N,V - DEFW READ ;R - READ A HEX FILE (W/CHECKSUMS) - DEFW SUBS ;S - SUBSTITUTE &/OR EXAMINE MEMORY - DEFW TYPE ;T - TYPE MEMORY IN ASCII - DEFW UNLD ;U - MEMORY TO PUNCH (BINARY FORMAT) - DEFW VERIFY ;V - COMPARE MEMORY AGAINST MEMORY - DEFW WRITE ;W - MEMORY TO PUNCH (HEX FORMAT) - DEFW XAM ;X - EXAMINE & MODIFY CUP REGISTERS - DEFW WHERE ;Y - FIND SEQUENCE OF BYTES IN RAM - DEFW SIZE ;Z - ADDRESS OF LAST R/W LOCATION -; -; -; -; THIS ROUTINE CONTROLS THE CONFIGURATION -; OF THE VARIOUS I/O DRIVERS & DEVICES. THIS IS -; ACCOMPLISHED VIA A HARDWARE READ/WRITE PORT. -; THIS PORT IS INITIALIZED UPON SIGN-ON -; BY THE VALUE READ ON PORT 'SENSE'. IF MAY BE -; DYNAMICALLY MODIFIED THROUGH CONSOLE COMMANDS. -; -; THE VALUE ON THE 'IOBYT' PORT REPRESENTS THE -; CURRENT CONFIGURATION. IT IS STURCTURED THUSLY: -; -; 000000XX - WHERE XX REPRESENTS THE CURRENT CONSOLE -; 0000XX00 - WHERE XX REPRESENTS THE CURRENT READER -; 00XX0000 - WHERE XX REPRESENTS THE CURRENT PUNCH -; XX000000 - WHERE XX REPRESENTS THE CURRENT LISTER -; -; WHEN USING A MEMORY LOCATION FOR IOBYT, THE -; POLARITY IS REVERSED. FOR AN I/O PORT, -; WHEN XX = 11, THE DEVICE IS ALWAYS THE -; TELEPRINTER. WHEN XX = 00, THE DEVICE IS ALWAYS -; USER DEFINED. SEE OPERATOR'S MANUAL FOR FURTHER -; DETAILS. -; -ASSIGN: CALL TI ;GET DEVICE NAME - LD HL,LTBL ;POINT TO DEVICE TABLE - LD BC,400H ;4 DEVICES TO LOOK FOR - LD DE,5 ;4 DEV. + IDENT. -..A0: CP (HL) ;LOOK FOR MATCH - JR Z,..A1 - ADD HL,DE ;GO THRU TABLE - INC C ;KEEP TRACK OF DEVICE - DJNZ ..A0 - JR ..ERR ;WRONG IDENTIFIER -..A1: LD E,C ;SAVE DEVICE NUMBER -..A2: CALL TI ;SCAN PAST '=' - CP '=' - JR NZ,..A2 - CALL TI ;GET NEW ASSIGNMENT - LD BC,400H ;4 POSSIBLE ASSIGNMENTS -..A3: INC HL ;POINT TO ASSIGNMENT NAME - CP (HL) ;LOOK FOR PROPER MATCH - JR Z,..A4 ;MATCH FOUND - INC C ;KEEP TRACK OF ASSIGNMENT NMBR - DJNZ ..A3 -..ERR: JP ERROR ;NO MATCH, ERROR -..A4: LD A,3 ;SET UP A MASK - INC E -..A5: DEC E ;DEVICE IN E - JR Z,..A6 ;GOT IT - SLA C ;ELSE MOVE MASKS - SLA C - RLA - RLA ;A=DEVICE MASK - JR ..A5 -..A6: CPL ;INVERT FOR AND'ING - LD D,A ;SAVE IN D -..A7: CALL PCHK ;WAIT FOR [CR] - JR NC,..A7 - CALL IOCHK ;GET PRESENT CONFIGURATION - AND D ;MODIFY ONLY SELECTED DEVICE - OR C ;'OR' NEW BIT PATTERN - LD C,A ;NEW CONFIGURATION -; -; THIS ALLOWS USER PROGRAMS TO MODIFY -; THE I/O CONDIGURATIMN DYNAMICALLY -; DURING EXECUTION. -; -IOSET: LD A,C ;NEW I/O BYTE PASSED IN C REE - CPL ;WE SAVE THE INVERTED BYTE - OUT IOBYT,A ;IN AN I/O PORT LATCH - RET -; -; THIS RETURNS THE CURRENT I/O -; CONFIGURATION IN THEE A REG. -; -IOCHK: IN A,IOBYT ;GET SAVED VALUE - CPL ;AND INVERT IT AGAIN - XOR A ; WW - RET -; -; -; THIS ROUTINE IS USED AS A SIMPLE MEANS TO PREVENT -; UNAUTHORIZED SYSTEM OPERATION. THE SYSTEM LOCKS UP, -; MONITORING FOR A 'CONT.-SHIFT-N', AT WHICH TIME IT -; WILL SIGN-ON AGAIN. NO REGISTER ASSIGHNMENTS OR I/O -; CONFIGURATIONS WILL BE ALTERED. -; -BYE: CALL CRLF -..BY: CALL KI - CP 1EH ;CONTROL-SHIFT-N - JR NZ,..BY - POP DE ;REMOVE THE RETURN - JP HELLO ;AND SIGN-ON AGAIN -; -; THIS ALLOW ENTERING OF ASCII TEXT INTO MEMORY -; FROM THE CONSOLE DEVICE. THE PARITY BIT IS CLEARED, -; AND ALL WILL BE STORED EXCEPT THE BACK-ARROR [ ] -; WHICH DELETES THE PREVIOUS CHARACTER, AND -; CONTROL-D, WHICH RETURNS CONTROL TO THE MONITOR. -; THIS COMMAND, COMBINED WITH THE 'Y' COMMAND, -; PROVIDES A RUDIMENTARY TEXT PROCESSING ABILITY. -; -PUTA: CALL EXPR1 ;GET THE STARTING ADDR. - CALL CRLF - POP HL -...A1: CALL KI ;GET A CHARACTER - CP 4 ;CONTROL-D? (EOT) - JP Z,LFADR ;YES, STOP & PRINT - CP 5FH ;ERASE MISTAKE? - JR Z,...A3 ; YES. - LD (HL),A ;ELSE STORE IT IN MEMORY - LD C,A - INC HL -...A2: CALL CO ;ECHO ON CONSOLE - JR ...A1 -...A3: DEC HL - LD C,(HL) - JR ...A2 ;ECHO & CONTINUE -; -; THIS ROUTINE COMPARES THE READER INPUT -; DEVICE WITH THE MEMORY BLOCK SPECIFIED. -; IT TESTS ALL EIGHT BITS, AND ANY DISCREPENCIES -; WILL BE OUTPUT TO THE CONSOLE. THIS IS USEFUL -; WHEN USED WITH THE BINARY DUMP DORMAT TO BOTH -; VERIFY PROPER READING & STORAGE, OR TO DETECT -; PROGRAM CHANGES SINCE IT WAS LAST LOADED. -; -COMP: CALL EXLF ;GET START ' STOP ADDR. -..C: CALL RIFF ;GET A FULL READER BYTE - CP (HL) ;8 BIT COMPARE - CALL NZ,CERR ;CALL IF INVALID COMPARE - CALL HILOX ;SEE IF RANGE SATISFIED - JR ..C -; -; THIS SUBROUTINE IS USED TO DISPLAY THE -; CURRENT LOCATION OF THE 'M' REGISTER POINTER (HL) , -; AND THE VALUE AT THE LOCATION, AND THE CONTENTS -; OF THE ACCUMULATOR. USED BY TWO ROUTINES. -; -CERR: LD B,A ;SAVE ACC. - CALL HLSP ;DISPLAY H&L - LD A,(HL) - CALL LBYTE ;PRINT 'M' - CALL BLK ;SPACE OVER - LD A,B - CALL LBYTE ;PRINT ACC. - JP CRLF ;CRLF & RETURN -; -; THIS DISPLAYS THE CONTENTS OF MEMORY IN BASE HEX -; WITH THE STARTING LOCATION ON EACH LINE. (BETWEEN -; THE TWO PARAMEETERS GIVEN). 16 BYTES PER LINE MAX. -; -DISP: CALL EXLF ;GET DISPLAY RANGE -..D0: CALL LFADR ;CRLF & PRINT ADDR. -..D1: CALL BLK ;SPACE OVER - LD A,(HL) - CALL LBYTE - CALL HILOX ;RANGE CHECK - LD A,L - AND 0FH ;SEE IF TIME TO CRLF - JR NZ,..D1 - JR ..D0 -; -; THIS OUTPUTS THE END OF FILE (EOF) PATTERN -; FOR THE CHECKSUM LOADER. IT IS USED AFTER -; PUNCHING A BLOCK OF MEMORY WITH THE 'W' -; COMMAND. AN ADDRESS PARAMETER MAY BE GIVEN, -; AND UPON READING, THIS ADDRESS WILL BE -; AUTOMATICALLY PLACED INT THE 'P' COUNTER. THE -; PROGRAM CAN THEN BE RUN WITH A SIMPLE 'G[CR]' -; COMMAND. -; -EOF: CALL EXPR1 ;GET OPTIONAL ADDR. - CALL PEOL ;CRLF TO PUNCH - LD C,':' ;FILE MARKER CUE - CALL PUO - XOR A ;ZERO LENGTH - CALL PBYTE - POP HL - CALL PADR ;PUNCH OPTIONAL ADDR. - LD HL,0 ;FILE TYPE=0 - CALL PADR ;PUNCH IT - JP NULL ;TRAILER & RETURN -; -; THIS COMMAND WILL FILL A BLOCK OF MEMORY -; WITH A VALUE. IE; FO,1FFF,0 FILLS FROM -; <1> TO <2> WITH THE BYTE <3>. HANDY FOR -; INITIALIZING A BLOCK TO A SPECIFIC VALUE, OR -; MEMORY TO A CONSTANT VALUE BEFOR LOADING -; A PROGRAM. (ZERO IS ESPECIALLY USEFUL.) -; -FILL: CALL EXPR3 ;GET 3 PARAMEETERS -..F: LD (HL),C ;STORE THE BYTE - CALL HILO - JR NC,..F - POP DE ;RESTORE STACK - JP START ; IN CASE OF ACCIDENTS -; -; THIS COMMAND ALLOWS EXECUTION OF ANOTHER -; PROGRAM WHILE RETAINING SOME MONITOR -; CONTROL BY SETTING BREAKPOINTS. -; -; TO SIMPLY EXECUTE, TYPE 'G[CR]'. TO SET -; A BREAKPOINT TRAP, ADD THE ADDRESS (ES) TO THE -; COMMAND. IE; G,[CR]. TWO BREAKPOINTS -; ARE ALLOWED, ENOUGH TO SATISFY MOST REQUIREMENTS. -; ONCE A BREAKPOINT HAS BEEN REACHED, THE -; REGISTERS MAY BE EXAMINED OR MODIFIED. THE -; PROGRAM CAN THEN BE CONTINUED BY TYPING ONLY -; A 'G[CR]'. OR ANOTHER BREAKPOINT COULD BE -; IMPLEMENTED AT THAT TIME BY TYPING 'G,[CR]'. -; -; *NOTE: THIS IS SOFTWARE CONTROLLED, AND THE -; BREAKPOINT MUST OCCUR ON AN INSTRUCTION -; BYTE. -; -GOTO: CALL PCHK ;GET A POSSIBLE ADDRESS - JR C,..G3 ;CR ENTERED - JR Z,..G0 ;DELIMETER ENTERED - CALL EXF ;GET ONE EXPRESSION - POP DE - LD HL,PLOC ;PLACE ADDRESS IN 'P' LOCATION - ADD HL,SP - LD (HL),D ;HIGH BYTE - DEC HL - LD (HL),E ;LOW BYTE - LD A,B - CP CR ;SEE IF LAST CHARACTER WAS A CR - JR Z,..G3 ;YES, LEAVE -..G0: LD D,2 ;TWO BREAKPOINTS MAX - LD HL,TLOC ;POINT TO TRAP STORAGE - ADD HL,SP -..G1: PUSH HL ;SAVE STORAGE POINTER - CALL EXPR1 ;GET A TRAP ADDRESS - LD E,B ;SAVE DELIMITER - POP BC ;TRAP ADDR. - POP HL ;STORAGE - LD A,B ;LOOK AT TRAP ADDR - OR C - JR Z,..G2 ;DON'T SET A TRAP AT 0 - LD (HL),C ;SAVE BKPT ADDR - INC HL - LD (HL),B - INC HL - LD A,(BC) ;PICK UP INST. BYTE - LD (HL),A ;SAVE THAT TOO - INC HL - LD A,0FFH ;RST 7 - LD (BC),A ;SOFTWARE INTERUPT -..G2: LD A,E ;LOOK AT DEELIMITER - CP CR - JR Z,..G2A - DEC D ;COUNT BKPTS - JR NZ,..G1 ;GET ONE MORE -..G2A: LD A,0C3H ;SET UP JUMP INSTRUCTION - LD (RST7),A ; AT RESTART TRAP LOC. - LD HL,TRAP ; TO MONITOR VECTOR - LD (RST7+1),HL -..G3: CALL CRLF - POP DE ;CLEAR SYSTEM RETURN - LD HL,22 ;FIND 'EXIT' ROUTINE - ADD HL,SP ;UP IN STACK - JP (HL) ;GO SOMPLACE -; -; THIS IS A 'QUICKIE' MEMORY TEST TO SPOT -; HARD MEMORY FAILURES, OR ACCIDENTLY -; PROTECTED MEEMORY LOCATIONS. IT IS NOT -; MEANT TO BE THE DEFINITIVE MEMORY DIAGNOSTIC. -; IT IS, HOWEVER, NON-DESTRUCTIVEE. ERRORS ARE -; PRINTED ON THE CONSOLE AS FOLLOWS- -; 00000100 WHERE <1> IS THE BAD BIT. -; BIT LOCATION OF THE FAILURE IS EASILY -; DETERMINED. NON-R/W MEMORY WILL RETURN -; WITH- 11111111 -; -TEST: CALL EXLF ;GET TWO PARAMS -...T1: LD A,(HL) ;READ A BYTE - LD B,A ;SAVE IN B REG. - CPL - LD (HL),A ;READ/COMPLIMENT/WRITE - XOR (HL) ; & COMPARE - JR Z,...T2 ;SKIP IF ZERO (OK) - PUSH DE ;SAVE END POINTER - LD D,B ;SAVE BYTE - LD E,A ;SET-UP TO DISPLAY - CALL HLSP ;PRINT BAD ADDR - CALL BITS ;PRINT BAD BIT LOC. - CALL CRLF - LD B,D ;RESTORE BYTE - POP DE ;RESTORE DE -...T2: LD (HL),B ;REPLACE BYTE - CALL HILOX ;RANGE TEST - JR ...T1 -; -; THIS COMMAND MOVES MASS AMOUNTS OF MEMORY -; FROM <1> THRU <2> TO THE ADDRESS STARTING -; AT <3>. THIS ROUTINE SHOULD BE USED WITH -; SOME CAUTION, AS IT COULD SMASH MEMORY IF -; CARLESSLY IMPLEMENTED. -; -; M<1>,<2>,<3> -; -MOVE: CALL EXPR3 ;GET 3 PARAMTERS -..M: LD A,(HL) ;PICK UP - LD (BC),A ;PUT DOWN - INC BC ;MOVE UP - CALL HILOX ;CHECK IF DONE - JR ..M -; -; THIS COMMAND READS THE CHECK-SUMMED HEX FILES -; FOR BOTH THE NORMAL INTEL FORMAT AND THE TDL -; RELOCATING FORMAT. ON BOTH FILES, A 'BIAS' MAY -; BE ADDED, WHICH WILL CAUSE THE OBJECT CODE TO -; BE PLACED IN A LOCATION OTHER THAN ITS -; INTENDED EXECUTION LOCATION. THE BIAS IS ADDED -; TO WHAT WOULD HAVE BEEN THE NORMAL LOADING -; LOCATION, AND WILL WRAP AROUND TO ENABLE -; LOADING ANY PROGRAM ANYWHERE IN MEMORY. -; -; WHEN LOADING A RELOCATABLE FILE, AN ADDITIONAL -; PARAMETER MAY BE ADDED, WHICH REPRESENTS THE -; ACTUAL EXECUTION ADDRESS DESIRED. THIS ALSO MAY -; BE ANY LOCATION IN MEMORY. -; -; EXAMPLES: -; -; R[CR] =0 BIAS, 0 EXECUTION ADDR. -; R[CR] =<1>BIAS, 0 EXECUTION ADDR. -; R,[CR] =0 BIAS, <1> EXECUTION ADDR. -; R,[CR] =<1>BIAS, <2>EXECUTION ADDR. -; -READ: CALL EXPR1 ;GET BIAS, IF ANY - LD A,B ;LOOK AT DELIMITER - SUB CR ;ALL DONE? - LD B,A ;SET UP RELOCATION OF 0 - LD C,A ; IF CR ENTERED - POP DE ;BIAS AMOUNT - JR Z,..R0 ;CR ENTERED - CALL EXPR1 ;GET RELOCATION - POP BC ;ACTUAL RELOCATION VALUE -..R0: EX DE,HL - EXX ;HL'=BIAS, BC'=RELOCATION - CALL CRLF -LOD0: CALL RIX ;GET A CHARACTER - SUB ':' ;ABSOLUTE FILE CUE? - LD B,A ;SAVE CUE CLUE - AND 0FEH ;KILL BIT 0 - JR NZ,LOD0 ; NO, KEEP LOOKING - LD D,A ;ZERO CHECKSUM - CALL SBYTE ;GET FILE LENGTH - LD E,A ;SAVE IN E REG. - CALL SBYTE ;GET LOAD MSB - PUSH AF ;SAVE IT - CALL SBYTE ;GET LOAD LSB - EXX ;CHANGE GEARS - POP DE ;RECOVER MSB - LD E,A ;FULL LOAD ADDR - PUSH BC ;BC'=RELOCATION - PUSH DE ;DE'=LOAD ADDR - PUSH HL ;HL'=BIAS - ADD HL,DE ; BIAS+LOAD - EX (SP),HL ;RESTORE HL' - POP IX ; X=BIAS+LOAD - EXX ;DOWNSHIFT - POP HL ;HL=LOAD ADDR - CALL SBYTE ;GET FILE TYPE - DEC A ;1=REL. FILE, 0=ABS. - LD A,B ;SAVE CUE BIT - POP BC ;BC=RELOCATION - JR NZ,..A ;ABSOLUTE FILE - ADD HL,BC ;ELSE RELMCATE - ADD IX,BC ;BOTH X & HL -..A: INC E ;TEST LENGHT - DEC E ;0=DONE - JR Z,DONE - DEC A ;TEST CUE - JR Z,LODR ;RELATIVE -..LI: CALL SBYTE ;NEXT - CALL STORE ;STORE IT - JR NZ,..L1 ;MORE COMING -LOD4: CALL SBYTE ;GET CHECKSUM - JR Z,LOD0 ;GOOD CHECKSUM -ERR3: PUSH IX - POP HL ;TRANSFER - CALL LADR ;PRINT CURRENT LOAD ADDR -ERR2: JP ERROR ;ABORT -DONE: LD A,H ;DON'T MODIFY IF ZERO - OR L - RET Z - EX DE,HL ;ELSE STORE IN PC - LD HL,PLOC - ADD HL,SP - LD (HL),D ;IN STACK AREA - DEC HL - LD (HL),E - RET -LODR: LD L,1 ;SET-UP BIT COUNTER -..L1: CALL LODCB ;GET THE BIT - JR C,..L3 ;DOUBLE BIT -..L5: CALL STORE ;WRITE IT - JR NZ,..L1 - JR LOD4 ;TEST CHECKSUM -..L3: LD C,A ;SAVE LOW BYTE - CALL LODCB ;NEXT CONTROL BIT - LD B,A ;SAVE HIGH BYTE - EXX - PUSH BC ;GET RELOCATION - EXX - EX (SP),HL ;INTO HL - ADD HL,BC ;RELOCATE - LD A,L ;LOW BYTE - CALL STORE ;STORE IT - LD A,H ;HIGH BYTE - POP HL ;RESTORE HL - JR ..L5 ;DO THIS AGAIN -LODCB: DEC L ;COUNT BITS - JR NZ,..LC1 ;MORE LEFT - CALL SBYTE ;GET NEXT - DEC E ;COUNT BYTES - LD H,A ;SAVE THE BITS - LD L,8 ;8 BITS/BYTE -..LC1: CALL SBYTE ;GET A DATA BYTE - SLA H ;TEST NEXT BIT - RET -SBYTE: PUSH BC ;PRESERVE BC - CALL RIBBLE ;GET A CONVERTED ASCII CHAR. - RLCA - RLCA - RLCA - RLCA ;MOV IT TO HIGH NIBBLE - LD C,A ;SAVE IT - CALL RIBBLE ;GET OTHER HALF - OR C ;MAKE WHOLE - LD C,A ;SAVE AGAIN IN C - ADD D ;UPDATE CHECKSUM - LD D,A ;NEW CHECKKSUM - LD A,C ;CONVERTED BYTE - POP BC - RET -STORE: LD (IX),A ;WRITE TO MEMORY - CP (IX) ;VALID WRITE? - JR NZ,ERR3 ; NO. - INC IX ;ADVANCE POINTER - DEC E ;COUNT DOWN - RET -; -; THIS ROUTINE ALLOWS BOTH INSPECTION OF & -; MODIFICATION OF MEMORY ON A BYTE BY BYTE -; BASIS. IT TAKES ONE ADDRESS PARAMETER, -; FOLLOWED BY A SPACE. THE DATA AT THAT -; LOCATION WILL BE DISPLAYED. IF IT IS -; DESIRED TO CHANGE IT, THE VALUE IS THEN -; ENTERED. A FOLLOWING SPACE WILL DISPLAY -; THE NEXT BYTE. A CARRIAGE RETURN [CR] -; WILL TERMINATE THE COMMAND. THE SYSTEM -; ADDS A CRLF AT LOCATIONS ENDING WITH EITHER -; XXX0 OR XXX8 TO AID IN DTERMINING THE -; PRESENT ADDRESS, IT IS PRINTED AFTER -; EACH CRLF. A BACKARROW [ ] WILL BACK -; UP THE POINTER AND DISPLAY THE -; PREVIOUS LOCATION. -; -SUBS: CALL EXPR1 ;GET STARTING ADDR - POP HL -..S0: LD A,(HL) - CALL LBYTE ;DISPLAY THE BYTE - CALL COPCK ;MODIFY? - RET C ; NO, ALL DONE - JR Z,..S1 ;DON'T MODIFY - CP 05FH ;BACKUP? - JR Z,..S2 - PUSH HL ;SAVE POINTER - CALL EXF ;GET NEW VALUE - POP DE ;VALUE IN EE - POP HL - LD (HL),E ;MODIFY - LD A,B ;TEST DELIMITER - CP CR - RET Z ;DONE -..S1: INC HL -..S3: LD A,L ;SEE IF TIME TO CRLF - AND 7 - CALL Z,LFADR ;TIME TO CRLF - JR ..S0 -..S2: DEC HL ;DECREMENT POINTER - JR ..S3 ;AND PRINT DATA THERE. -; -; THIS ROUTINE TRANSLATES THE DATA IN -; MEMORY TO AN ASCII FORMAT. ALL NON- -; PRINTING CHARACTERS AREE CONVERTED TO -; PERIODS. [.] -; THERE ARE 64 CHARACTERS PER LINE. -; -TYPE: CALL EXLF ;DISPLAY RANGE -..T0: CALL LFADR ;DISPLAY ADDRESS - LD B,64 ;CHARACTERS PER LINE -..T1: LD A,(HL) - AND 7FH ;KILL PARITY BIT - CP ' ' ;RANGE TEST - JR NC,..T3 ;=>SPACEE -..T2: LD A,'.' ;REPLACE NON-PRINTING -..T3: CP 07CH ;ABOVE LOWER CASE z - JR NC,..T2 - LD C,A ;SEND IT - CALL CO - CALL HILOX ;MORE TO GO? - DJNZ ..T1 ;SEE FI TIME TO CRLF - JR ..T0 ;YES -; -; THIS IS A HEXADECIMAL SEARCH ROUTINE. IT -; TAKES NO ADDRESS PARAMETERS. AS MANY -; BYTES MAY BE ENTERED, SEPERATED BY A COMMA, -; AS DESIRED. THE MAXIMUM IS 255, BUT 3-4 IS -; TYPICAL, AND MORE THAN 12 WOULD BE UNUSUAL. -; THE ENTIRE MEMORY IS SEARCHED STARTING -; FROM ZERO, AND ALL STARTING ADDRESSES OF EACH -; OCCURANCE OF THE SEARCH STRING ARE PRINTED -; ON THE CONSOLE DEVICE. -; -WHERE: LD D,0 ;COUNT SEARCH STRING -...W0: CALL EXPR1 ;GET ONE BYTE - POP HL ;PICK IT UP - LD H,L ;STICK IN HIGH BYTE - PUSH HL ;PUT IT IN STACK - INC SP ;ADJUST STACK - INC D ;COUNT UP - LD A,B ;TEST DELIMITER - SUB CR - JR NZ,...W0 ;MORE TO GO - LD B,A ;CHEAP ZEROS - LD C,A - LD H,A - LD L,D ;GET BYTE COUNT IN L - DEC L ;-1 - ADD HL,SP ;BYTES STORED IN STACKK - PUSH HL - PUSH BC -FINDC: PUSH BC ;SAVE THAT POINTER - CALL CRLF - POP BC ;RESTORE -FIND: POP HL ;HL=SEARCH ADDR - POP IX ;X=SEARCH BYTE POINTER - LD E,D ;RESET COUNTER - LD A,(IX) ;GET THE FIRST SEARCH BYTE - CPIR ;COMPARE, INCR., & REPEAT - JP PO,DONE ;ODD PARITY=DONE - PUSH IX ;SAVE POINTERS - PUSH HL -FOUND: DEC E - JR Z,TELL ;FOUND ALL - LD A,(IX-1) ;LOOK AT NEXT MATCH - CP (HL) ;TEST NEXT - JR NZ,FIND ;NO MATCH - INC HL ;BUMP POINTER - DEC IX - JR FOUND ;TEST NEXT MATCH -TELL: POP HL - PUSH HL - DEC HL - PUSH BC ;SAVE SEARCH COUNT LIMIT - CALL LADR ;TELL CONSOLE - POP BC ;RESTORE - JR FINDC -DONE2: INC SP - DEC E ;RESET STACK - JR NZ,DONE2 - RET -; -; THIS ROUTINE DUMPS MEMORY IN THE STANDARD -; INTEL HEX-FILE FORMAT. A START & END -; PARAMETER IS REQUIRED. AT THE CONCLUSION -; OF THE DUMP, AND "END OF FILE" SHOULD BE -; GENERATED WITH THE "E" COMMAND. -; -WRITE: CALL EXLF ;GET TWO PARAMETERS - CALL WAIT ;PAUSE IF TTY CONFIGURATION -..W0: CALL PEOL ;CRLF TO PUNCH - LD BC,':' ;START OF FILE - CALL PUO ;PUNCH IT - PUSH DE ;SAVE - PUSH HL ;POINTERS -..W1: INC B ;CALCULATE FILE LENGTH - CALL HILO - JR C,..W4 ;SHORT FILE - LD A,24 ;24 BYTES PER FILE - SUB B ;ENOUGH YET? - JR NZ,..W1 ; NO. - POP HL ;GET START ADDR BACK. - CALL ..W2 ;SEND THE BLOCK - POP DE ;RESTORE END OF FILE POINTER - JR ..W0 ;KEEP GOING -..W2: LD D,A ;INITIALIZE CHECKSUM - LD A,B ;FILE LENGTH - CALL PBYTE ;PUNCH IT - CALL PADR ;PUNCH ADDRESS - XOR A ;FILE TYPE=0 - CALL PBYTE ;PUNCH IT -..W3: LD A,(HL) ;GET A DATA BYTE - CALL PBYTE ;PUNCH IT - INC HL ;POINT TO NEXT BYTE - DJNZ ..W3 ;DECREMENT FILE COUNT - XOR A - SUB D ;CALCULATE CHECKSUM - JP PBYTE ;PUNCH IT, RETURN -..W4: POP HL ;CLEAR STACK - POP DE ; OF POINTERS - XOR A ;SET UP A - JR ..W2 ;FINISH UP & RETURN -; -; -; THIS ROUTINE ALLOWS DISPLAYING THE -; USER'S CPU REGISTERS. THEY ALSO MAY BE -; USING THE REGISTER NAME AFTER TYPEINT THE "X". -; I.E. XA 00- -; THE REGISTER MAY BE SKIPPED OVER, OR MODIFIED, -; SIMILARLY TO THE "S" COMMAND. -; -; TO DISPLAY THE "NORMAL" SYSTEM STATUS, -; SIMPLY TYPE "X[CR]". TO DISPLAY THE -; ADDISTIONAL Z-80 REGISTERS, FOLLOW -; THE "X" WITH AN APOSTROPHE. I.E. "X'[CR]", -; OR TO EXAMINE A SINGLE "PRIME" REGISTER, -; TYPE THE REGISTER IDENTIFIER AFTER THE -; APOSTROPHE. I.E. X'X 0000- -; -; THESE REGISTER VALUES ARE PLACED INTO THE CPU -; UPON EXECUTING ANY "GO" COMMAND. [G] -; -XAM: CALL TI - LD HL,ACTBL - CP CR ;FULL REG. DISPLAY - JR Z,..X6 - CP 2CH ;SEE IF PRIMES WANTED - JR NZ,..X0 - LD HL,PRMTB - CALL TI - CP CR ;FULL REG. DISPLAY - JR Z,..X6 -..X0: CP (HL) ;TEST FOR REGISTER NAME - JR Z,..X1 - BIT 7,(HL) ;SEE IF END OF TABLE - JP NZ,ERROR - INC HL - INC HL - JR ..X0 -..X1: CALL BLK -..X2: INC HL - LD A,(HL) - LD B,A ;SAVE FOR FLAGS - AND 3FH ;CLEAR FLAGS FOR BIAS - EX DE,HL - LD L,A ;DISPLACEMENT FROM STACK - LD H,0 - ADD HL,SP - EX DE,HL - INC HL - LD A,(DE) ;PICK UP REG. VALUE - CALL LBYTE ;PRINT IT - BIT 7,B - JR Z,..X3 - DEC DE - LD A,(DE) - CALL LBYTE -..X3: CALL COPCK ;MODIFY - RET C ;CR ENTERED, ALL DONE - JR Z,..X5 ;SKIP TO NEXT REG. - PUSH HL - PUSH BC - CALL EXF ;GET NEW VALUE - POP HL - POP AF - PUSH BC - PUSH AF - LD A,L - LD (DE),A - POP BC - BIT 7,B ;SEE IF 8 BIT OR 16 BIT REG. - JR Z,..X4 ;8 BIT - INC DE - LD A,H ;HIGH BYTE OF 16 BIT REG. - LD (DE),A -..X4: POP BC - POP HL - LD A,B ;TEST DELIMITER - CP CR - RET Z ;CR ENTRED, ALL DONE -..X5: BIT 7,(HL) ;SEE IF END OF TABLE - RET NZ ;RETURN IF SO - JR ..X2 -..X6: CALL CRLF -..X7: CALL BLK - LD A,(HL) - INC HL - OR A - RET M - LD C,A - CALL CO - LD C,'=' - CALL CO - LD A,(HL) - LD B,A ;SAVE FLAGS - AND 3FH ;CLEAR UP FOR OFFSET - INC HL - EX DE,HL - LD L,A - LD H,0 - ADD HL,SP - EX DE,HL - BIT 6,B ;TEST FOR SPECIAL "M" - JR NZ,..X9 ;PRINT OUT ACTUAL "M" - LD A,(DE) - CALL LBYTE ;PRINT REG. VALUE - BIT 7,B ;SINGLE OR DOUBLE? - JR Z,..X7 ;SINGLE. - DEC DE - LD A,(DE) -..X8: CALL LBYTE - JR ..X7 -..X9: PUSH HL ;SAVE HL - LD A,(DE) ;GET REG. POINTER - LD H,A ;HIGH BYTE - DEC DE - LD A,(DE) - LD L,A ;LOW BYTE - LD A,(HL) ;GET VALUE - POP HL ;RESTORE HL - JR ..X8 ;PRINT VALUE & CONTINUE -; -; THIS IS A MESSAGE OUTPUT ROUTINE. -; IT IS USED BY THE SIGN-ON AND THE CRLF. -; POINTER IS IN HL (WHEN ENTERED AT -; TOM1) AND LENGTH IN B REG. -; -TOM: LD HL,MSG -TOM1 LD C,(HL) ;GET A CHARACTER - INC HL ;MOVE POINTER - CALL CO ;OUTPUT IT - DJNZ TOM1 ;KEEP GOILG TILL B=0 - CALL CSTS ;SEE IF AN ABORT REQUEST - OR A ; WAITING - RET Z ;NO. -; -; SEE IF CONTROL-C IS WAITING -; ABMRT IF SO. -CCHK: CALL KI - CP 3 ;CONTROL-C? - RET NZ -; -; SYSTEM ERROR ROUTINE. THIS -; WILL RESTORE THE SYTEM AFTER -; A SYSTEM ERROR HAS BEEN TAKEN. -; THE I/O CONFIGURATION IS NOT -; AFFECTED. -; -ERROR: CALL MEMSIZ - LD DE,-22 ;STACK POINTER OFFSET - ADD HL,DE - LD SP,HL - LD C,'*' ;ANNOUNCE ERROR - CALL CO - JP START ;BACK TO WORK -; -; THIS GETS A READER CHARACTER, -; AND COMPARES IT WITH THE 'D' REG. -; IT ABORTS ON AND 'OUT-OF-DATA' -; CONDITION. -; -RIFF: CALL RI ;GET READER CHARACTER - JR C,ERROR ;ABORT ON CARRY - CP D ;TEST D - RET -; -; THIS ROUTINE WILL RETURN THE -; CURRENT VALUE OF THE HIGHEST -; READ/WRITE MEMORY LOCATION THAT -; IS AVAILABLE ON THE SYSTEM. -; IT WILL "SEARCH" FOR MEMORY -; STARTING AT THE BOTTOM OF MEMORY -; AND GO UPWARDS UNTIL NON-R/W MEMORY -; IS FOUND. -; -SIZE: CALL MEMSIZ ;GET THE VALUE - LD BC,ENDX-EXIT - ADD HL,BC ;ADJUST IT -; -; -; CRLF BEFORE HLSP ROUTINE -; -LFADR: CALL CRLF -; -; PRINT THE CURRENT VALUE OF H&L, -; AND A SPACE. -; -HLSP: CALL LADR -; -; PRINT A SPACE ON THE CONSOLE -; -BLK: LD C,' ' -; -; THIS IS THE MAIN CONSOLE -; OUTPUT ROUTINE -; -CO: CALL IOCHK - AND NOT CMSK - JR NZ,CO0 -; -; TELEPRINTER CONFIGURATION -; I/O DRIVER. -; -TTYOUT: IN A,TTS - AND TTYBE - JR Z,TTYOUT ; WW: NZ -> Z - LD A,C - OUT TTO,A - RET -CO0: DEC A ;CCRT? - JR NZ,CO1 ; NO. -; -; C.R.T. CONFIGURATION DRIVER. -; -CRTOUT: IN A,CRTS - AND CRTBE - JR NZ,CRTOUT - LD A,C - OUT CRTO,A - RET -; -CO1: DEC A ;BATCH - JP NZ,COLOC ; NO, MUST BE USER -; -; LIST OUTPUT DRIVER ROUTINE -; -A USER VECTORED ROUTINE, USED -; BYT THE ASSEMBLER, ETC. ALSO, -; WHEN THE ASSIGNED MODE IS "BATCH", -; THIS IS THE ROUTINE USED FOR THE -; MONITOR OUTPUT THAT WOULD NORMALLY -; GO TO THE "CONSOLE". -; -LO: CALL IOCHK - AND NOT LMSK - JR Z,TTYOUT - CP LCRT - JR Z,CRTOUT - CP LINE - JP Z,LNLOC ;EXTERNAL VECTOR - JP LULOC ;USER DEFINED VECTOR -; -; SEND CRLF TO PUNCH DEVICE -; -PEOL: LD C,CR - CALL PUO - LD C,LF -; -; PUNCH OUTPUT DRIVER ROUTINE -; -PUO: CALL IOCHK - AND NOT PMSK - JR Z,TTYOUT ;PUNCH=TELEPRINTER - CP PCAS ;CASSETTE? - JR NZ,PO1 ; NO. -; -PO0: IN A,PCASS - AND PCSBE - JR NZ,PO0 - LD A,C - OUT PCASO,A - RET -; -PO1: CP PPTP - JP Z,PTPL ;EXTERNAL VECTOR - JP PULOC ;USER VECTOR -; -; -; THIS IS A BINARY DUMP ROUTINE THAT MAY BE -; USED WITH BOTH PAPER-TAPE AND/OR CASSETTE -; SYSTEMS. IT PUNCHES A START-OF-FILE MARK -; AND THEN PUNCHES IN FULL 8-BITS DIRECTLY -; FROM MEMORY. IT IS FOLLOWED BY AN END-OF- -; FILE MARKER. THESE DUMPS MAY BE LOADED -; USING THE "L" COMMAND. THEY ARE USEFUL -; FOR FAST LOADING, AND MAY BE VERIFIED -; USING THE "C" (COMPARE) COMMAND. -; -; U,[CR] -; PUNCHES FROM THRU -; -UNLD: CALL EXLF ;GET TWO PARAMETERS - CALL WAIT ;PAUSE FOR PUNCH-ON (TTY) - CALL LEAD ;PUNCH LEADER - CALL MARK ;PUNCH FILE MARKER -..U: LD C,(HL) ;GET MEMORY BYTE - CALL PUO ;PUNCH IT - CALL HILO ;SEE IF DONE - JR NC,..U - CALL MARK ;PUNCH END OF FILE MARKER -; -; THIS PUNCHES NULLS (LEADER/TRAILER). -; IT RETURNS "QUIET" IN CASE THE PUNCH -; AND CONSOLE ARE THE SAME. -; -NULL: CALL LEAD ;PUNCH NULLS -; -; THIS ROUTINE WILL PAUSE FOR -; A KEYBOARD CHARACTER. IT IS -; USED AS A DELAY TO GIVE THE -; OPERATOR TIME TO TURN ON THE -; TELEPRINTER PUNCH BEFORE SENDING -; A HEX FILE OR BINARY FILE TO -; THE PUNCH. IT WIL SIMPLY -; RETURN IF THE PUNCH & CONSOLE -; ARE NO BOTH ASSIGNED TO THE -; DEFAULT. (TELEPRINTER) -; -WAIT: CALL IOCHK - AND ~CMSK | ~PMSK ; WW: WAS "AND NOT CMSK OR NOT PMSK" - RET NZ - JP STARO ;RETURN "QUIET" -; -; CONVERT HEX TO ASCII -; -CONV: AND 0FH ;LOW NIBBLE ONLY - ADD 90H - DAA - ADC 40H - DAA - LD C,A - RET -; -; GET TWO PARAMETERS, PLACE -; THEM IN DE & HL, AND THEN -; CRLF. -; -EXLF: CALL EXPR - POP DE - POP HL -; -; CONSOLE CARRIAGE RETURN & -; LINE FEED ROUTINE. -; -; THE NUMBER OF FILL CHARACTERS -; MAY BE ADJUSTED TO 0-3 BY THE -; VALUE PLACED IN THE B REG. MINIMUM -; VALUE FOR "B" IS TWO (2). MAXIMUM -; IS FIVE (5). -; -CRLF: PUSH HL ;SAVE HL - ;WW LD B,4 ;CRLF LENGTH (SET FOR 2 FILLS) - LD B,2 ; WW - CHANGE TO ZERO FILLS - CALL TOM ;SEND CRLF - POP HL - RET -; -; I -; TEST THE CURRENT CONSOLES -; KEYBOARD FOR A KEY-PRESS -; RETURN TRUE (0FFH IN A REG) -; IF THERE IS A CHARACTER -; WAITING IN THE UART. -; -CSTS: CALL IOCHK - AND NOT CMSK - JR NZ,CS0 - IN A,TTS - JR CS1 -CS0: DEC A ;CCRT - JR NZ,CS3 - IN A,CRTS -CS1: AND TTYDA - LD A,FALSE -CS2: RET Z ; WW: NZ -> Z - CPL - RET -CS3: DEC A ;BATCH - RET Z - JP CSLOC ;USED DEFINED FUNCTION -; -; GET THREE PARAMETERS AND -; CRLF. -; -EXPR3: INC C - CALL EXPR - CALL CRLF - POP BC - POP DE - POP HL - RET -; -; GET ONE PARAMETER. -; NO CRLF. -; -EXPR1: LD C,1 -; -; THIS IS THE MAIN "PARAMETER-GETTING" ROUTINE. -; THIS ROUTINE WILL ABORT ON A NON-HEX CHARACTER. -; IT TAKES THE MOST RECENTELY TYPED FOUR VALID -; HEX CHARACTERS, AND PLACES THEM UP ON THE STACK. -; (AS ONE 16 BIT VALUE, CONTAINED IN TWO -; 8-BIT BYTES.) IF A CARRIAGE RETURN IS ENTERED, -; IT WILL PLACE THE VALUE OF "0000" IN THE STACK. -; -EXPR: LD HL,0 ;INITIALIZE HL TO ZERO -EX0: CALL TI ;GET SOMETHING FROM CONSOLE -EX1: LD B,A ;SAVE IT - CALL NIBBLE ;CONVERT ASCII TO HEX - JR C,..EX2 ;ILLEGAL CHARACTER DECTECTED - ADD HL,HL ;MULTIPLY BY 16 - ADD HL,HL - ADD HL,HL - ADD HL,HL - OR L ;OR IN THE SINGLE NIBBLE - LD L,A - JR EX0 ;GET SOME MORE -..EX2: EX (SP),HL ;SAVE UP IN STACK - PUSH HL ;REPLACE THE RETURN - LD A,B ;TEST THE DELIMITER - CALL QCHK - JR NC,..EX3 ;CR ENTERED - DEC C ;SHOULD GO TO ZERO - RET Z ; RETURN IF IT DOES -..EX3: JP NZ,ERROR ;SOMETHING WRONG - DEC C ;DO THIS AGAIN? - JR NZ,EXPR ; YES. - RET ;ELSE RETURN -EXF: LD C,1 - LD HL,0 - JR EX1 -; -; RANGE TESTING ROUTINES. -; CARRY SET INDICATES RANGE EXCEEDED. -; -HILOX: CALL HILO - RET NC ;OK - POP DE ;RETURN ONE LEVEL BACKK - RET -; -HILO: INC HL ;INCREMENT HL - LD A,H ;TEST FOR CROSSING 64K BORDER - OR L - SCF ;CARRY SET=STOP - RET Z ;YES, BORDER CROSSED - LD A,E ;NOW, TEST HL VS. DE - SUB L - LD A,D - SBC H - RET ;IF CARRY WAS SET, THEN STOP -; -; HEXADECIMAL MATH ROUTINE -; -; THIS ROUTINE IS USEFUL FOR -; DETERMINING RELATIVE JUMP -; OFFSETS. IT RETURNS THE SUM -; & DIFFERENCE OF TWO PARAMETERS. -; -; H, -; -; X+Y X-Y -; -HEXN: CALL EXLF - PUSH HL ;SAVE HL FOR LATER - ADD HL,DE ;GET SUM - CALL HLSP ;PRINT IT - POP HL ;THIS IS LATER - OR A ;CLEAR CARRY - SBC HL,DE ;GET DIFFERENCE & PRINT IT -; -; PRINT H&L ON CONSOLE -; -LADR: LD A,H - CALL LBYTE - LD A,L -LBYTE: PUSH AF - RRCA - RRCA - RRCA - RRCA - CALL ..2 - POP AF -..2: CALL CONV - JP CO -; THIS ROUTINE SENDS EIGHT RUBOUTS -; TO THE PUNCH DEVICE. -; -MARK: LD BC,08FFH ;SET-UP B&C - JR LE0 -; -; THIS ROUTINE SENDS BLANKDS TO THE -; PUNCH DEVICE. -; -LEAD: LD BC,4800H ;PRESET SOME NULLS -LE0: CALL PUO - DJNZ LE0 - RET -; -; THIS ROUTINE RETURNS TO A USER -; PROGRAM THE CURRENT TOP OF -; MEMORY VALUE MINUS WORKSPACE -; AREA USED BY THE MONITOR. -; -MEMCK: PUSH HL - CALL MEMSIZ - LD A,L - SUB 2CH - JR NC,...B - DEC H -...B: LD B,H - POP HL - RET -; -; THIS IS A CALLED ROUTINE USED -; TO CALCULATE THE TOP OF MEMORY -; STARTING FROM THE BOTTOM OF -; MEMORY, AND SEARCHING UPWARD UNTIL -; FIRST R/W MEMORY IS FOUND, AND THEN -; CONTINUING UNTIL THE END OF THE R/W -; MEMORY. THIS ALLOWS R.O.M. AT ZERO, -; AND INSURES A CONTINUOUS MEMORY BLOCK -; HAS BEEN FOUND. -; IT IS USED BY THE ERROR ROUTINE TO -; RESET THE STACK POINTER AS WELL. -; -MEMSIZ: PUSH BC -;WW LD BC,BASE ;POINT TO START OF MONITOR -;WW LD HL,-1 ;RAM SEARCH STARTINT PT. -;WW..M0: INC H ;FIRST FIND R/W MEMORY -;WW LD A,(HL) -;WW CPL -;WW LD (HL),A -;WW CP (HL) -;WW CPL -;WW LD (HL),A -;WW JR NZ,..M0 -;WW..M1: INC H ;R/W FOUND, NOW FIND END -;WW LD A,(HL) -;WW CPL -;WW LD (HL),A -;WW CP (HL) -;WW CPL -;WW LD (HL),A -;WW JR NZ,..M2 -;WW LD A,H ;TEST FOR MONITOR BORDER -;WW CP B -;WW JR NZ,..M1 ;NOT THERE YET -;WW..M2: DEC H ;BACK UP, SUBTRACT WORKSPACE - LD HL,$EFFF ; WW - FIXED TOP OF MEMORY AT $F000 - LD BC,EXIT-ENDX - ADD HL,BC - POP BC ;RESTORE BC - RET ;VALUE IN HL -; -; -RIBBLE: CALL RIX -NIBBLE: SUB '0' ;QUALIFY & CONVERT - RET C ;<0 - CP 'G'-'0' ;>F? - CCF ;PERVERT CARRY - RET C - CP 10 ;NMBR? - CCF ;PERVERT AGAIN - RET NC ;RETURN CLEAN - SUB 'A'-'9'-1 ;ADJUST - CP 0AH ;FILTER ":" THRU "@" - RET -; -; SEND H&L VALUE TO PUNCH DEVICE -; -PADR: LD A,H - CALL PBYTE - LD A,L -; -; PUNCH A SINGLE BYTE -; -PBYTE: PUSH AF ;NIBBLE AT A TIME - RRCA - RRCA - RRCA - RRCA - CALL CONV - CALL PUO - POP AF ;NEXT NIBBLE - PUSH AF ;SAVE FOR CHECKSUM - CALL CONV - CALL PUO - POP AF ;ORIGINAL BYTE HERE - ADD D ;ADDED TO CHECKQUM - LD D,A ;UPDATE CHECKSUM - RET -; -; -COPCK: LD C,'-' - CALL CO -; -PCHK: CALL TI -; -; TEST FOR DELIMITERS -; -QCHK: CP ' ' ;RETURN ZERO IF DELIMITER - RET Z - CP ',' - RET Z - CP CR ;RETURN W/CARRY SET IF CR - SCF - RET Z - CCF ;ELSE NON-ZERO, NO CARRY - RET -; -; MAIN CONSOLE INPUT ROUTINE -; -CI: CALL IOCHK - AND ~CMSK ; WW: WAS "NOT CMSK" - JR NZ,CI1 -; -; TELEPRINTER ROUTINE -; -TTYIN: IN A,TTS - AND TTYDA - JR Z,TTYIN - IN A,TTI - RET -; -CI1: DEC A ;CONSOLE=CRT? - JR NZ,CI2 -; -; C.R.T. INPUT ROUTINE -; -CRTIN: IN A,CRTS - AND CRTDA - JR Z,CRTIN - IN A,CRTI - RET -; -CI2: DEC A ;BATCH? - JP NZ,CILOC ;NO, MUST BE USER DEFINED -; -; -; READER INPUT ROUTINE, WITH -; TIME-OUT DELAY. INCLUDES -; PULSING OF HARDWARE PORT -; TO INDICATE REQUEST FOR -; READER DATA. -; -RI: PUSH HL - CALL IOCHK - AND NOT RMSK - ;WW CPL - ;WW OUT RCP,A ;PULSE READER CONTROL PORT - ;WW CPL ;CLEEAR IT - ;WW OUT RCP,A - JR NZ,RI3 ;NOT TTY - LD H,A ;CLEAR FOR-TIME OUT TEST -RI0: IN A,TTS - AND TTYDA - JR NZ,RI2 ; WW: Z -> NZ - PUSH BC - LD B,0 -DL0: EX (SP),HL ;WASTE TIME - EX (SP),HL ;FOR DELAY - DJNZ DL0 - POP BC - DEC H -; JR NZ,RI0 ; WW - JR RI0 ; WW - ELIMINATE TIMEOUT -RI1: XOR A - SCF - POP HL - RET -RI2: IN A,TTI -RID: OR A - POP HL - RET -RI3: CP RCAS - JR NZ,RI6 - ;WW IN A,SWITCH ;READ INITIAL SENSE CONDX. - ;WW LD L,A -RI4: ;WW IN A,SWITCH ;SEE IF SW. ALTERED - ;WW CP L - ;WW JR NZ,RI1 ;ABORT IF SO - IN A,RCSS - AND RCSDA ;DATA YET? - JR NZ,RI4 ;KEEP LOOKING -RI5: IN A,RCSD - JR RID -RI6: POP HL - CP RPTR - JP Z,RPTPL ;EXTERNAL ROUTINE - JP RULOC ;USER VECTOR -; -; THIS ROUTINE GETS READER INPUT -; AND KILLS THE PARITY BIT. -; -RIX: CALL RIFF - AND 7FH - RET -; -; THIS ROUTINE READS A BINARY FILE -; IMAGE, IN THE FORM AS PUNCHED IN -; THE "U" (UNLOAD) COMMAND. IT TAKES -; ONE PARAMETER, WHICH IS THE STARTING -; ADDRESS OF THE LOAD, AND WILL PRINT -; THE LAST ADDRESS (+1) LOADED ON THE -; CONSOLE DEVICE. -; -LOAD: CALL EXPR1 ;INITIAL LOAD ADDRESS - POP HL - CALL CRLF - LD D,0FFH ;START-OF-FILE TAB -...L0: LD B,4 ;FIND AT LEAST FOUR 0FFH'S -...L1: CALL RIFF - JR NZ,...L0 - DJNZ ...L1 -...L2: CALL RIFF ;4 FOUND, NOW WAIT FOR NON-0FFH - JR Z,...L2 - LD (HL),A ;FIRST REAL DATA BYTE - LD A,BELL ;TELL TTY - OUT TTO,A -...L3: INC HL - CALL RIFF - JR Z,..EL ;POSSIBLE END OF FILE - LD (HL),A - JR ...L3 -..EL: LD E,1 ;INITIALIZE -..EL0: CALL RIFF - JR NZ,..EL1 - INC E ;COUNT QUES - LD A,MAX ;LOOK FOR EOF - CP E ;FOUND MAX? - JR NZ,..EL0 ;NOPE - JP LADR ;YEP, PRINT END ADDR -..EL1: LD (HL),D - INC HL - DEC E ;RESTORE - JR NZ,..EL1 - LD (HL),A ;REAL BYTE - JR ...L3 -; -; THIS IS THE BREAKPOINT "TRAP" HANDLING -; ROUTINE. ALL USER REGISTERS ARE SAVED -; FOR DISPLAY PURPOSES, AND THE CONTENTS -; ARE RESTORED WHEN EXECUTING A "GO" (G) -; COMMAND. -; -RESTART: - PUSH HL ;PUSH ALL REGISTERS - PUSH DE - PUSH BC - PUSH AF - CALL MEMSIZ ;GET MONITOR'S STACK VALUE - EX DE,HL - LD HL,10 ;GO UP 10 BYTES IN STACK - ADD HL,SP - LD B,4 ;PICK OFF REG. - EX DE,HL -...R0: DEC HL - LD (HL),D ;SAVE IN WORKAREA - DEC HL - LD (HL),E - POP DE - DJNZ ...R0 - POP BC - DEC BC ;ADJUST P.C. VALUE - LD SP,HL ;SET MONITOR STACK - LD HL,TLOCX - ADD HL,SP - LD A,(HL) - SUB C ;LOOK FOR A TRAP/MATCH - INC HL - JR NZ,..R1 - LD A,(HL) - SUB B - JR Z,..R3 ;NO TRAP HERE -..R1: INC HL - INC HL - LD A,(HL) - SUB C ;TEST FOR SECOND TRAP - JR NZ,..R2 - INC HL - LD A,(HL) - SUB B - JR Z,..R3 -..R2: INC BC ;NO TRAPS SET, RE-ADJUST P.C. -..R3: LD HL,LLOCX - ADD HL,SP - LD (HL),E ;STORE USER H&L - INC HL - LD (HL),D - INC HL - INC HL - LD (HL),C ;AND USER P.C. - INC HL - LD (HL),B - PUSH BC - LD C,'@' ;DISPLAY BREAK ADDRESS. - CALL CO - POP HL - CALL LADR - LD HL,TLOCX - ADD HL,SP - LD BC,200H -..R4: LD E,(HL) ;REPLACE BYTES TAKEN FOR TRAP - LD (HL),C ;ZERO OUT STORAGE AREA - INC HL - LD D,(HL) - LD (HL),C - INC HL - LD A,E - OR D ;DO NOTHING IF ZERO - JR Z,..R5 - LD A,(HL) - LD (DE),A ;STORE BYTE -..R5: INC HL ;SAME THING - DJNZ ..R4 ;FOR OTHER BREAKPOINT - EX AF,AF' ;GET ALTERNATE SET OF REG.'S - EXX - PUSH HL ;AND STORE IN WORKSPACE - PUSH DE - PUSH BC - PUSH AF - PUSH IX - PUSH IY - LD A,I ;GET INTERUPT VECTOR BYTE - LD B,A - LD A,R ;GET REFRESH BYTE - LD C,A - PUSH BC ;SAVE - JP START ;BACK TO START -; -; THIS IS THE INTERNAL KEYBOARD -; HANDLING ROUTINE. IT WILL IGNORE -; RUBOUTS (0FFH) AND BLANKS (00), -; AND IT WILL NOT ECHO CR'S & N'S. -; (NO N'S FOR THE "NULL" COMMAND). -; IT CONVERTS LOWER CASE TO UPPER -; CASE FOR THE LOOK-UP OF COMMANDS. -; -; OTHER CHARACTERS ARE ECHOED AS THEY -; ARE RECEIVED. -; -KI: CALL CI ;GET CHARACTER FROM CONSOLE - AND 7FH ;CLEAR PARITY BIT - RET -; -TI: CALL KI - INC A ;IGNORE RUBOUTS - RET M - DEC A ;IGNORE NULLS - RET Z - CP 'N' ;IGNORE N'S FOR NULL CMND - RET Z - CP 'n' - JR Z,..T - CP CR ;IGNORE CR'S - RET Z - PUSH BC - LD C,A - CALL CO - LD A,C - POP BC - CP 'A'-1 ;CONVERT TO UPPER CASE - RET C - CP 'z'+1 - RET NC -..T: AND 05FH - RET -; -; THIS ROUTINE ALLOWS EXAMINATION OF -; ANY INPUT PORT, OR THE SEENDING OF -; ANY VALUE TO ANY PORT. -; -; QO,[CR] -; OUTPUT TO PORT , THE VALUE -; -; QI[CR] -; DISPLAY THE PORT -; -QUERY: CALL TI - CP 'O' - JR Z,QUO - CP 'I' - JP NZ,ERROR - CALL EXPR1 - POP BC - IN E,(C) -BITS: LD B,8 ;DISPLAY 8 BITS - CALL BLK -..Q2: SLA E - LD A,'0'>>1 ; WW: WAS "LD A,'0' >1" - ADC A ;MAKE "0" OR "1" - LD C,A - CALL CO - DJNZ ..Q2 - RET -QUO: CALL EXPR - POP DE - POP BC - OUT (C),E - RET -; -; THIS ROUTINE VERIFIES THE CONTENTS -; OF ONE MEMORY BLOCK WITH ANOTHER. -; -; V,, -; VERIFY FROM <1> THRU <2> WITH -; THE CONTENTS OF MEMORY BEGINNING AT <3> -; -VERIFY: CALL EXPR3 ;GET 3 PARAMENTERS -VERI0: LD A,(BC) - CP (HL) - JR Z,..B - PUSH BC - CALL CERR ;DISPLAY ERRORS - POP BC -..B: INC BC - CALL HILOX - JR VERI0 -; -; -; -; THE FIRST CHARACTER IS THE DEVICE NAME -; (ONE LETTER) AND THE NEXT FOUR ARE THE -; NAMES OF THE FOUR POSSIBLE DRIVERS TO BE -; ASSIGNED. -; -LTBL: - DB 'C' ;CONSOLE ASSIGNMENTS - DB 'T' ;CTTY T=TELEPRINTER - DB 'C' ;CCRT C=CRT (VIDEO MONITOR) - DB 'B' ;BATCH= COMMANDS FROM READER - DB 'U' ;CUSE USER -; - DB 'R' ;READER ASSIGNMENTS - DB 'T' ;RTTY - DB 'P' ;RPTR P=PAPER TAPE - DB 'C' ;RCAS C=CASSETTE - DB 'U' ;RUSER USER -; - DB 'P' ;PUNCH ASSIGNMENTS - DB 'T' ;PTTY - DB 'P' ;PPTP - DB 'C' ;PCAS C=CASSETTE - DB 'U' ;PUSER USER -; - DB 'L' ;LIST ASSIGNMENTS - DB 'T' ;LTTY LIST=TELEPRINTER - DB 'C' ;LCRT LIST=CRT - DB 'L' ;LINE PRINTER - DB 'U' ;LUSER USER -; -; -; THIS IS A SHORT PROGRAM, EXECUTED -; UPON EXECUTING A "GO" COMMAND. IT -; IS PLACED IN THE WORK AREA WHEN -; THE MONITOR IS INITIALIZED, AS IT -; :REQUIRES RAM FOR PROPER OPERATION. -; -EXIT: ;EXIT ROUTINE (LOADS ALL REGISTERS) - POP BC - LD A,C - LD R,A - LD A,B - LD I,A - POP IY - POP IX - POP AF - POP BC - POP DE - POP HL - EX AF,AF' - EXX - POP DE - POP BC - POP AF - POP HL - LD SP,HL - NOP ;RESERVED FOR ENABLE INTERUPTS - LD HL,0 - JP 0 -; - DW 0 ;STORAGE AREA FOR TRAP DATA - DB 0 - DW 0 - DB 0 -; -; DISPLACEMENTS OF REGISTER -; STORAGE FROM NORMAL STACK -; LOCATION. -; -ENDX: -; -ALOC: EQU 15H -BLOC: EQU 13H -CLOC: EQU 12H -DLOC: EQU 11H -ELOC: EQU 10H -FLOC: EQU 14H -HLOC: EQU 31H -LLOC: EQU 30H -PLOC: EQU 34H -SLOC: EQU 17H -TLOC: EQU 35H -TLOCX: EQU 25H -LLOCX: EQU 20H -; -APLOC: EQU 09H -BPLOC: EQU 0BH -CPLOC: EQU 0AH -DPLOC: EQU 0DH -EPLOC: EQU 0CH -FPLOC: EQU 08H -HPLOC: EQU 0FH -LPLOC: EQU 0EH -XLOC: EQU 07 -YLOC: EQU 05 -RLOC: EQU 02 -ILOC: EQU 03 -; -; -; THIS IS THE TABLE USED TO DETERMINE -; A VALID REGISTER IDENTIFIER, AND IT'S -; DISPLACEMENT FROM THE STACK POINTER. -; -; POSITION ONE= REGISTER NAME, WITH BIT 7 INDICATING -; END OF TABLE. -; -; POSITION TWO= BIAS FROM CURRENT STACK LEVEL OR'ED -; WITH A TWO-BIT FLAG. 00XXXXXX=BYTE -; 10XXXXXX=WORD -; 11XXXXXX=SPECIAL FOR "M" REG. -; -ACTBL: ;NORMAL SET OF REGISTERS (8080) -; ;PLUS THE INTERUPT REGISTER ("I") -; - DB 'A',ALOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'B',BLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'C',CLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'D',DLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'E',ELOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'F',FLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'H',HLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'L',LLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'M',HLOC | 0C0H ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'P',PLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'S',SLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'I',ILOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM -; -; DB " RWA" -; -PRMTB: ;ADDITIONAL SET OF REGISTERS (Z-80) -; - DB 'A',APLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'B',BPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'C',CPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'D',DPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'E',EPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'F',FPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'H',HPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'L',LPLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'M',HPLOC | 0C0H ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'X',XLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'Y',YLOC | 080H ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 'R',RLOC | 0 ; WW: REPLACED "OR" WITH "|" FOR TASM - DB 0C1H -; -Z: -;WW END diff --git a/branches/s100/Apps/apps-bins/comfiles.lbr b/branches/s100/Apps/apps-bins/comfiles.lbr deleted file mode 100644 index f5ab52bf..00000000 Binary files a/branches/s100/Apps/apps-bins/comfiles.lbr and /dev/null differ diff --git a/branches/s100/Apps/apps-srcs/sources.lbr b/branches/s100/Apps/apps-srcs/sources.lbr deleted file mode 100644 index b6d3fc6d..00000000 Binary files a/branches/s100/Apps/apps-srcs/sources.lbr and /dev/null differ diff --git a/branches/s100/Apps/core/access.com b/branches/s100/Apps/core/access.com deleted file mode 100644 index fc71ba44..00000000 Binary files a/branches/s100/Apps/core/access.com and /dev/null differ diff --git a/branches/s100/Apps/core/cpmname.com b/branches/s100/Apps/core/cpmname.com deleted file mode 100644 index 665804f6..00000000 Binary files a/branches/s100/Apps/core/cpmname.com and /dev/null differ diff --git a/branches/s100/Apps/core/findfile.com b/branches/s100/Apps/core/findfile.com deleted file mode 100644 index 1e0416ab..00000000 Binary files a/branches/s100/Apps/core/findfile.com and /dev/null differ diff --git a/branches/s100/Apps/core/map.com b/branches/s100/Apps/core/map.com deleted file mode 100644 index 4efc2a81..00000000 Binary files a/branches/s100/Apps/core/map.com and /dev/null differ diff --git a/branches/s100/Apps/core/meta.com b/branches/s100/Apps/core/meta.com deleted file mode 100644 index 17690542..00000000 Binary files a/branches/s100/Apps/core/meta.com and /dev/null differ diff --git a/branches/s100/Apps/core/multifmt.com b/branches/s100/Apps/core/multifmt.com deleted file mode 100644 index 8102760a..00000000 Binary files a/branches/s100/Apps/core/multifmt.com and /dev/null differ diff --git a/branches/s100/Apps/core/rem.com b/branches/s100/Apps/core/rem.com deleted file mode 100644 index a0546cb9..00000000 Binary files a/branches/s100/Apps/core/rem.com and /dev/null differ diff --git a/branches/s100/Apps/core/setlabel.com b/branches/s100/Apps/core/setlabel.com deleted file mode 100644 index 7b53f016..00000000 Binary files a/branches/s100/Apps/core/setlabel.com and /dev/null differ diff --git a/branches/s100/Apps/core/sysgen.com b/branches/s100/Apps/core/sysgen.com deleted file mode 100644 index 11536f4b..00000000 Binary files a/branches/s100/Apps/core/sysgen.com and /dev/null differ diff --git a/branches/s100/Apps/core/termtype.com b/branches/s100/Apps/core/termtype.com deleted file mode 100644 index c01dcdb8..00000000 Binary files a/branches/s100/Apps/core/termtype.com and /dev/null differ diff --git a/branches/s100/Apps/core/view.com b/branches/s100/Apps/core/view.com deleted file mode 100644 index 11ff9af7..00000000 Binary files a/branches/s100/Apps/core/view.com and /dev/null differ diff --git a/branches/s100/Apps/crossdev/2DRIVE.C b/branches/s100/Apps/crossdev/2DRIVE.C deleted file mode 100644 index 3e7e8b91..00000000 --- a/branches/s100/Apps/crossdev/2DRIVE.C +++ /dev/null @@ -1,106 +0,0 @@ -/* twodrive.c 7/11/2012 dwg - */ - -/* This program is experimental and is not for release because - it contains techniques which are not recommended because - there are better API functions to do these operations. */ - -/* - This code is in the crossdev folder because it is part of - my development environment, and I said I would make everything - available. - - The purpose of this code is to dynamically alter the BIOS - data associated with PPIDE (or PPISD) drives. The default - configuration is that mass storage devices get four drives. - - Each of the four drives can be remapped using the logical - unit utility MAP. - - The purpose of this code is to alter the runtime data so that - instead of the PPIDE having four drives for the primary IDE - device, it then has two for the primary and two for the secondary. - - The MAP command will properly display the status after this is - run, but you must keep in mind that having two sets of logical - units at the same time is twice as complicated to keep straight - in your mind, and you have to be more careful you know exactly - how the drives are mapped so you don't accidentally destroy your - data. - - This utility is unsupported, and not recommended for general use. - The reason this utility wasn't generally published is that it - is very difficult to give support about this remotely. - - If you are brave, and talented, and you can figure out what I did - with pointers in this program, then you get the prize, which is - to be able to copy from one CF chip to another in a dual adapter. - - It has only been tested on my PPIDE, and I don't know what will - happen if you try it. You could wipe out your CF chip, so make - sure you are backed up if you try this. -*/ - - -#include "cpmbios.h" -#include "bioscall.h" - -#include "cpmbdos.h" -#include "bdoscall.h" - -#define u8 unsigned char -#define u16 unsigned int - -struct DPH * pDPH_C; -struct DPB * pDPB_C; -u8 * pDU_C; -u16 * pCUR_C; -u16 * pNUM_C; - -struct DPH * pDPH_D; -struct DPB * pDPB_D; -u8 * pDU_D; -u16 * pCUR_D; -u16 * pNUM_D; - -main(argc,argv) - int argc; - char *argv[]; -{ - - ireghl = pSELDSK; - iregbc = DRIVEC; - iregde = 0; - bioscall(); - pDPH_C = ireghl; - pDPB_C = pDPH_C->dpb; - pDU_C = ireghl -1; - *pDU_C = 0X41; - printf("Current C: DevUnit is %02x\n",*pDU_C); - pCUR_C = ireghl + 18; - *pCUR_C = 0; - printf("Current C: Logical Unit is %d\n",* pCUR_C); - pNUM_C = ireghl + 20; - *pNUM_C = 64/9; - printf("Current C: Number of LU's is %d\n",* pNUM_C); - - ireghl = pSELDSK; - iregbc = DRIVED; - iregde = 0; - bioscall(); - - pDPH_D = ireghl; - pDPB_D = pDPH_D->dpb; - pDU_D = ireghl -1; - *pDU_D = 0x41; - printf("Current D: DevUnit is %02x\n",*pDU_D); - - pCUR_D = ireghl + 18; - *pCUR_D = 1; - printf("Current D: Logical Unit is %d\n",* pCUR_D); - - pNUM_D = ireghl + 20; - *pNUM_D = 64/9; - printf("Current D: Number of LU's is %d\n",* pNUM_D); - - -} diff --git a/branches/s100/Apps/crossdev/2MAP.C b/branches/s100/Apps/crossdev/2MAP.C deleted file mode 100644 index 48dfb65b..00000000 --- a/branches/s100/Apps/crossdev/2MAP.C +++ /dev/null @@ -1,322 +0,0 @@ -/* map.c 6/7/2012 dwg - */ - -#include "portab.h" -#include "globals.h" -#include "stdio.h" -#include "stdlib.h" -#include "memory.h" - -#include "cpmbind.h" - -#include "infolist.h" -#include "dphdpb.h" -#include "dphmap.h" -#include "metadata.h" -#include "clogical.h" -#include "applvers.h" - -#define MAXDRIVE 8 - -/* Drive List Geometry */ -#define COL1 0 -#define COL2 (80/4) -#define COL3 (80/2) -#define COL4 (COL2+COL3) -#define LINE 3 - -/* Logical Unit List Geometry */ -#define LGUT 5 -#define COL1A 0 -#define COL2A (80/3) -#define COL3A (2*COL2A) - -/* Nomenclature Geometry */ -#define LINE2 8 - -/* Misc Info Geometry */ -#define CDLINE 6 - -/* BDOS Function number */ -#define RETCURR 25 - -/* function defined in bdoscall.asm */ -extern lurst(); - -struct BIOS * pBIOS; - -struct DPH * pDPH; - -int devunit; -int dev; -int unit; -int currlu; -int numlu; -int drivenum; -int drive; -int deflu; - -char szTemp[128]; - -int readsec(drive,track,sector,buffer) - int drive; - int track; - int sector; - unsigned int buffer; -{ - ireghl = pSELDSK; - iregbc = drive; - iregde = 0; - bioscall(); - - ireghl = pSETTRK; - iregbc = track; - bioscall(); - - ireghl = pSETSEC; - iregbc = sector; - bioscall(); - - ireghl = pSETDMA; - iregbc = buffer; - bioscall(); - - ireghl = pREAD; - bioscall(); - return irega; -} - - - - -int haslu(dr) - int dr; -{ - if(0 < lugnum(dr)) { - return TRUE; - } else { - return FALSE; - } -} - - - -void dispdph(l,c,drive,ptr) - int l; - int c; - char drive; - struct DPH *ptr; -{ - -/* - unsigned int xlt; - unsigned int rv1; - unsigned int rv2; - unsigned int rv3; - unsigned int dbf; - unsigned int dpb; - unsigned int csv; - unsigned int alv; - unsigned char sigl; - unsigned char sigu; - unsigned int current; - unsigned int number; -*/ - crtlc(l,c); - printf("%c: ",drive); - - devunit = lugdu(drive-'A'); - dev = devunit & 0xf0; - unit = devunit & 0x0f; - - currlu = lugcur(drive-'A'); - switch(dev) { - case DEV_MD: - if(0 == unit) printf("ROM"); - if(1 == unit) printf("RAM"); - break; - case DEV_FD: - printf("FD%d",unit); - break; - case DEV_IDE: - printf("IDE%d",unit); - break; - case DEV_ATAPI: - printf("ATAPI%d",unit); - break; - case DEV_PPIDE: - printf("PPIDE%d",unit); - break; - case DEV_SD: - printf("SD%d",unit); - break; - case DEV_PRPSD: - printf("PRPSD%d",unit); - break; - default: - printf("UNK"); - break; - }; - - if('L' == (unsigned char)ptr->sigl) { - if('U' == (unsigned char)ptr->sigu) { -/* printf("-LU%d",(int)ptr->current); */ - printf("-LU%d",currlu); - } - } - -/* printf("dpb=0x%04x, ",(unsigned int)ptr->dpb); - printf("sigl=0x%02x, ",(unsigned char)ptr->sigl); - printf("sigu=0x%02x, ",(unsigned char)ptr->sigu); - printf("curr=0x%04x, ",(unsigned int)ptr->current); - printf("numb=0x%04x", (unsigned int)ptr->number); -*/ - -} - -int main(argc,argv) - int argc; - char *argv[]; -{ - int i; - int mylu; - int drivenum; - int column; - int line; - char szDrive[32]; - char szLuNum[32]; - - if(argc == 3) { - - strcpy(szDrive,argv[1]); - strcpy(szLuNum,argv[2]); - - mylu = atoi(szLuNum); - - if(strlen(szDrive) == 2) { - if(':' == szDrive[1]) { - switch(szDrive[0]) { - case 'a': - case 'A': - luscur(0,mylu); - break; - case 'b': - case 'B': - luscur(1,mylu); - break; - case 'c': - case 'C': - luscur(2,mylu); - break; - case 'd': - case 'D': - luscur(3,mylu); - break; - case 'e': - case 'E': - luscur(4,mylu); - break; - case 'f': - case 'F': - luscur(5,mylu); - break; - case 'g': - case 'G': - luscur(6,mylu); - break; - case 'h': - case 'H': - luscur(7,mylu); - break; - default: - break; - } - - } - } - exit(1); - } - - - pBIOS = BIOSAD; - - crtinit(); - crtclr(); - crtlc(0,0); - - printf("MAP.COM %d/%d/%d v%d.%d.%d.%d", - A_MONTH,A_DAY,A_YEAR,A_RMJ,A_RMN,A_RUP,A_RTP); - printf(" dwg - System Storage Drives and Logical Units"); - - ireghl = pGETINFO; - bioscall(); - pINFOLIST = ireghl; - - crtlc(CDLINE,COL3A+LGUT); - printf("infolist.version %d\n",pINFOLIST->version); - - pDPHMAP = (struct DPHMAPA *)pINFOLIST->dphmap; - - dispdph(LINE, COL1+LGUT-1,'A',(struct DPH *)pDPHMAP->drivea); - dispdph(LINE+1,COL1+LGUT-1,'B',(struct DPH *)pDPHMAP->driveb); - dispdph(LINE, COL2+LGUT-1,'C',(struct DPH *)pDPHMAP->drivec); - dispdph(LINE+1,COL2+LGUT-1,'D',(struct DPH *)pDPHMAP->drived); - dispdph(LINE, COL3+LGUT-1,'E',(struct DPH *)pDPHMAP->drivee); - dispdph(LINE+1,COL3+LGUT-1,'F',(struct DPH *)pDPHMAP->drivef); - dispdph(LINE, COL4+LGUT-1,'G',(struct DPH *)pDPHMAP->driveg); - dispdph(LINE+1,COL4+LGUT-1,'H',(struct DPH *)pDPHMAP->driveh); - - dregbc = RETCURR; - bdoscall(); - drive = drega; - - crtlc(CDLINE,5); - printf("Current drive is %c:",'A'+drive); - - devunit = lugdu(drive); - dev = devunit & 0xf0; - unit = devunit & 0x0f; - currlu = lugcur(drive); - deflu = currlu; - numlu = lugnum(drive); - - crtlc(CDLINE,COL2A+LGUT); - printf("Number of LUs is %d\n",lugnum(drive)); - - if(0. - -;---------------------------------------------------------------------- - maclib portab - maclib globals - maclib cpmbdos - maclib printers - maclib banner - maclib applvers - maclib z80 - maclib memory - maclib version - maclib cpmappl - maclib banner -;----------------------- - - do$start - - jmp around$bandata -argv dw prog,dat,prod,orig,ser,myname,0 -prog db 'ACCESS.COM $' - date - serial - product - originator - oriname -uuid db '08D4953E-B6F4-4673-990C-7E17A0A299BD$' -around$bandata: - - sbanner argv - - lda 80h ; pick up the command tail length provided by CCP - cpi 0 ; were there any parameters given? - jnz no$usage ; If not, go around - printf 'usage - access ' - jmp do$exit -no$usage: - - memcpy work$fcb,PRIFCB,32 ; Save initial default FCB from CCP - - printf 'Checking: ' - - mvi a,'$' ; place a terminating dollar sign - sta PRIFCB+9 ; at the end of the filname field - print PRIFCB+1 ; and print the filename portion - - conout '.' ; print the seperating dot - - memcpy PRIFCB,work$fcb,16 ; get a fresh copy of the initial FCB - mvi a,'$' ; place a terminating dollar sign - sta PRIFCB+12 ; at the end of the filetype field - print PRIFCB+9 ; and print the filetype - print crlf ; followed by a CR and LF - - memcpy PRIFCB,work$fcb,32 ; restore the initial FCB - - mvi c,FOPEN ; Try to open the given filename - lxi d,PRIFCB ; using the primary default FCB - call BDOS ; with a BDOS call - cpi 255 ; Test for Open Failure (255) - jnz done ; jump if file existed - - mvi c,FDELETE ; Delete the A:$$$.SUB file - lxi d,del$fcb ; using an alternative FCB - call BDOS - - printf 'Submit file terminated due to missing file$' - - jmp do$exit ; Go to the one true exit point - -done: - printf 'File found, Submit may proceed' -do$exit: - do$end - - newfcb del$fcb,1,'$$$ SUB' - -work$fcb ds 36 ; A place to save a copy of the default FCB on entry - -crlf db CR,LF ; a dollar sign terminated CR and LF -term db '$' ; a general purpose terminating character - - end start - -; eof - access.asm - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/ACCESS.BAT b/branches/s100/Apps/crossdev/ACCESS.BAT deleted file mode 100644 index c233bcdb..00000000 --- a/branches/s100/Apps/crossdev/ACCESS.BAT +++ /dev/null @@ -1,18 +0,0 @@ -rem access.sub 9/5/2012 dwg - build access from sources - -if not exist access.rel erase access.cpm -if not exist access.rel z80mu rmac access - -if not exist printers.rel erase access.cpm -if not exist printers.rel z80mu rmac printers - -if not exist memory.rel erase access.cpm -if not exist memory.rel z80mu rmac memory - -if not exist banner.rel erase access.cpm -if not exist banner.rel z80mu rmac banner - -if not exist access.cpm z80mu link access,memory,banner,printers -if not exist access.cpm rename access.com access.cpm - -dir access.cpm diff --git a/branches/s100/Apps/crossdev/ACCESS.SUB b/branches/s100/Apps/crossdev/ACCESS.SUB deleted file mode 100644 index 66ec69d7..00000000 --- a/branches/s100/Apps/crossdev/ACCESS.SUB +++ /dev/null @@ -1,7 +0,0 @@ -e:rem access.sub 9/5/2012 dwg - build access from sources -rasm80 access -rasm80 printers -rasm80 memory -rasm80 banner -link80 access,memory,banner,printers - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/ACCESS.SYM b/branches/s100/Apps/crossdev/ACCESS.SYM deleted file mode 100644 index a05bf1be..00000000 --- a/branches/s100/Apps/crossdev/ACCESS.SYM +++ /dev/null @@ -1,8 +0,0 @@ -0103 HEXREF 0113 IDSIG 0115 IDRMJ 0116 IDRMN -0117 IDRUP 0118 IDRTP 0119 IDMON 011A IDDAY -011B IDYR 0120 PRESTK 0122 BEGIN 09C1 PRDWOR -0999 PRHBYT 09AE PRHWOR 0554 XBANNE 07FF XSBANN -0546 XMEMCP 0547 XMEMSE 0983 PRHNYB 09CD PDEC -09EF PDEC1 09F1 PDEC2 0A0D PDEC3 0A24 PDEC4 -0A25 PDEC5 - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/ANSI.H b/branches/s100/Apps/crossdev/ANSI.H deleted file mode 100644 index a6e6f32f..00000000 Binary files a/branches/s100/Apps/crossdev/ANSI.H and /dev/null differ diff --git a/branches/s100/Apps/crossdev/APPLVERS.H b/branches/s100/Apps/crossdev/APPLVERS.H deleted file mode 100644 index 5eaa18ac..00000000 --- a/branches/s100/Apps/crossdev/APPLVERS.H +++ /dev/null @@ -1,20 +0,0 @@ -/************************************/ -/* applvers.h dwg - 2.2.0.3 Beta */ -/************************************/ - -#define A_RMJ 2 -#define A_RMN 3 -#define A_RUP 0 -#define A_RTP 0 - -#define A_MONTH 1 -#define A_DAY 16 -#define A_YEAR 2013 -#define A_YR 13 - -/********************/ -/* eof - applvers.h */ -/********************/ - - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/APPLVERS.LIB b/branches/s100/Apps/crossdev/APPLVERS.LIB deleted file mode 100644 index f20a6db1..00000000 --- a/branches/s100/Apps/crossdev/APPLVERS.LIB +++ /dev/null @@ -1,34 +0,0 @@ -; applvers.lib 2/29/2012 dwg - For RomWBW 2.1.1 Release - -A$RMJ equ 2 -A$RMN equ 2 -A$RUP equ 0 -A$RTP equ 0 - -A$MONTH equ 2 -A$DAY equ 15 -A$YEAR equ 2013 - -date macro -dat db ' 2/15/2013$' - endm - -serial macro -ser db '654321$' - endm - -product macro -prod db 'CPM80$' - endm - -originator macro -orig db 'DWG$' - endm - -oriname macro -myname db ' Douglas W Goodall $' - endm - -; eof - applvers.lib - - diff --git a/branches/s100/Apps/crossdev/AS.COM b/branches/s100/Apps/crossdev/AS.COM deleted file mode 100644 index c8c41b79..00000000 Binary files a/branches/s100/Apps/crossdev/AS.COM and /dev/null differ diff --git a/branches/s100/Apps/crossdev/ASCII.H b/branches/s100/Apps/crossdev/ASCII.H deleted file mode 100644 index 8e1b7765..00000000 --- a/branches/s100/Apps/crossdev/ASCII.H +++ /dev/null @@ -1,13 +0,0 @@ -/* ascii.h 11/25/2012 dwg - */ - -#define ASCII_BS 8 -#define ASCII_TAB 9 -#define ASCII_LF 10 -#define ASCII_VT 11 -#define ASCII_FF 12 -#define ASCII_CR 13 -#define ASCII_ESC 27 - -/* eof - ascii.h */ - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/ASMIFACE.ASM b/branches/s100/Apps/crossdev/ASMIFACE.ASM deleted file mode 100644 index fd84186c..00000000 --- a/branches/s100/Apps/crossdev/ASMIFACE.ASM +++ /dev/null @@ -1,67 +0,0 @@ -; asmiface.asm 6/4/2012 dwg - - - extrn .begin,.chl,.swt - extrn csave,cret,.move - - global xrega_,1 - global xregbc_,2 - global xregde_,2 - global xreghl_,2 - - PUBLIC asmif_ -asmif_: lxi d,.2 - call csave - - LXI H,8-.2 ; pick up 1st parm "function address" - DAD SP - MOV E,M - INX H - MOV D,M - xchg - shld callad+1 - - LXI H,10-.2 - DAD SP - MOV E,M - INX H - MOV D,M ; DE = parm - xchg - shld xregbc_ - - LXI H,12-.2 - DAD SP - MOV E,M - INX H - MOV D,M - xchg - shld xregde_ - - LXI H,14-.2 - DAD SP - MOV E,M - INX H - MOV D,M - xchg - shld xreghl_ - - lhld xregbc_ - mov b,h - mov c,l ; setup B&C - lhld xregde_ - xchg ; setup D&E - lhld xreghl_ ; setup H&L - -callad: call 0e639h ; setlu - - sta xrega_ - shld xreghl_ - xchg - shld xregde_ - mov l,c - mov h,b - shld xregbc_ - RET ; HL has return value - -.2 EQU 0 - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/ASMIFACE.H b/branches/s100/Apps/crossdev/ASMIFACE.H deleted file mode 100644 index 5b39e406..00000000 --- a/branches/s100/Apps/crossdev/ASMIFACE.H +++ /dev/null @@ -1,14 +0,0 @@ -/*****************************/ -/* asmiface.H 6/4/2012 dwg - */ -/*****************************/ - - extern char xrega; - extern unsigned int xregbc; - extern unsigned int xregde; - extern unsigned int xreghl; - extern asmif(); /* asmif(0xe60,bc,de,hl); */ - -/********************/ -/* eof - asmiface.h */ -/********************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/AUTOEXEC.Z80 b/branches/s100/Apps/crossdev/AUTOEXEC.Z80 deleted file mode 100644 index f60431fa..00000000 --- a/branches/s100/Apps/crossdev/AUTOEXEC.Z80 +++ /dev/null @@ -1,18 +0,0 @@ -; -; This is a sample AUTOEXEC.Z80 file. Tailor it to your own preferences, -; or delete it entirely. -; -set_bdos min -set_cpmecho off -set_cpmlist lpt1 -set_cpmpun com1 -set_cpmrdr com1 -set_cpu z80 -set_fake on -set_illop fault -set_iobase 400 -set_mask on -set_source z80 -set_term h19 -set_vars on -coldboot diff --git a/branches/s100/Apps/crossdev/BANKER.ASM b/branches/s100/Apps/crossdev/BANKER.ASM deleted file mode 100644 index 4dbf960e..00000000 --- a/branches/s100/Apps/crossdev/BANKER.ASM +++ /dev/null @@ -1,656 +0,0 @@ - extrn .begin,.chl,.swt - extrn csave,cret,.move - global pINFOLIS_,2 - global metadata_,128 - global pSYSCFG_,2 - global pCBIOS_,2 - PUBLIC main_ -main_: lxi d,.2 - call csave - LXI H,0 - XCHG - LXI H,-132-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-6596 - SHLD ireghl_ - CALL bioscall_ - LHLD ireghl_ - SHLD pINFOLIS_ - LHLD pINFOLIS_ - PUSH H - LXI H,.1+0 - PUSH H - CALL printf_ - POP D - POP D - LXI H,-6656 - SHLD pCBIOS_ - LXI H,-4096 - SHLD hregbc_ - LXI H,-16384 - SHLD hregde_ - CALL diagnose_ - LXI H,-16384 - SHLD pSYSCFG_ - LHLD pSYSCFG_ - LXI D,68 - DAD D - MOV E,M - MVI D,0 - PUSH D - CALL crtinit_ - POP D - CALL crtclr_ - LXI H,0 - PUSH H - LXI H,0 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,0 - PUSH H - LXI H,1 - PUSH H - LXI H,1 - PUSH H - LXI H,2 - PUSH H - LXI H,2012 - PUSH H - LXI H,29 - PUSH H - LXI H,8 - PUSH H - LXI H,.1+31 - PUSH H - CALL printf_ - XCHG - LXI H,16 - DAD SP - SPHL - LXI H,.1+64 - PUSH H - CALL printf_ - POP D - LXI H,-4096 - SHLD hregbc_ - LXI H,-16384 - SHLD hregde_ - CALL diagnose_ - LXI H,-16384 - SHLD pSYSCFG_ - LXI H,0 - PUSH H - LXI H,2 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,0 - PUSH H - LXI H,3 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,.1+107 - PUSH H - CALL printf_ - POP D - LXI H,0 - PUSH H - LXI H,4 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pSYSCFG_ - LXI D,9 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+117 - PUSH H - CALL printf_ - POP D - POP D - LXI H,0 - PUSH H - LXI H,5 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pSYSCFG_ - LXI D,10 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+126 - PUSH H - CALL printf_ - POP D - POP D - LXI H,0 - PUSH H - LXI H,6 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pSYSCFG_ - LXI D,11 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+135 - PUSH H - CALL printf_ - POP D - POP D - LXI H,0 - PUSH H - LXI H,7 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pSYSCFG_ - LXI D,12 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+144 - PUSH H - CALL printf_ - POP D - POP D - LXI H,0 - PUSH H - LXI H,9 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pSYSCFG_ - LXI D,7 - DAD D - MOV E,M - INX H - MOV D,M - LXI H,2-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-16384 - DAD D - SHLD dregde_ - LXI H,9 - SHLD dregbc_ - CALL bdoscall_ - LXI H,0 - PUSH H - LXI H,10 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pSYSCFG_ - LXI D,5 - DAD D - MOV E,M - INX H - MOV D,M - LXI H,-16384 - DAD D - XCHG - LXI H,0-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,128 - PUSH H - LXI H,0 - PUSH H - LXI H,-124-.2 - DAD SP - PUSH H - CALL memset_ - POP D - POP D - POP D - LXI H,11 - PUSH H - LXI H,2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,-124-.2 - DAD SP - PUSH H - CALL memcpy_ - POP D - POP D - POP D - LXI H,-128-.2 - DAD SP - PUSH H - LXI H,.1+153 - PUSH H - CALL printf_ - POP D - POP D - LXI H,26 - PUSH H - LXI H,3 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,.1+156 - PUSH H - CALL printf_ - POP D - LXI H,26 - PUSH H - LXI H,4 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pCBIOS_ - LXI D,75 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+166 - PUSH H - CALL printf_ - POP D - POP D - LXI H,26 - PUSH H - LXI H,5 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pCBIOS_ - LXI D,76 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+175 - PUSH H - CALL printf_ - POP D - POP D - LXI H,26 - PUSH H - LXI H,6 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pCBIOS_ - LXI D,77 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+184 - PUSH H - CALL printf_ - POP D - POP D - LXI H,26 - PUSH H - LXI H,7 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pCBIOS_ - LXI D,78 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+193 - PUSH H - CALL printf_ - POP D - POP D - LXI H,26 - PUSH H - LXI H,9 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pINFOLIS_ - LXI D,4 - DAD D - MOV E,M - INX H - MOV D,M - LXI H,2-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,128 - PUSH H - LXI H,0 - PUSH H - LXI H,-124-.2 - DAD SP - PUSH H - CALL memset_ - POP D - POP D - POP D - LXI H,127 - PUSH H - LXI H,4-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,-124-.2 - DAD SP - PUSH H - CALL memcpy_ - POP D - POP D - POP D - LXI H,0 - XCHG - LXI H,-130-.2 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .4 -.3: - LXI H,-130-.2 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.4: - LXI H,-130-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,128 - CALL .ul - JZ .5 - LXI H,-130-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-128-.2 - DAD SP - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,45 - POP D - CALL .eq - JZ .6 - LXI H,-132-.2 - DAD SP - mov a,m - inx h - ora m - JZ .7 - LXI H,0 - PUSH H - LXI H,-128-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-126-.2 - DAD SP - DAD D - POP D - MOV M,E - JMP .8 -.7: - LXI H,1 - XCHG - LXI H,-132-.2 - DAD SP - MOV M,E - INX H - MOV M,D -.8: -.6: - JMP .3 -.5: - LXI H,-128-.2 - DAD SP - PUSH H - LXI H,.1+202 - PUSH H - CALL printf_ - POP D - POP D - LXI H,26 - PUSH H - LXI H,10 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pINFOLIS_ - LXI D,6 - DAD D - MOV E,M - INX H - MOV D,M - LXI H,0-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,128 - PUSH H - LXI H,0 - PUSH H - LXI H,-124-.2 - DAD SP - PUSH H - CALL memset_ - POP D - POP D - POP D - LXI H,11 - PUSH H - LXI H,2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,-124-.2 - DAD SP - PUSH H - CALL memcpy_ - POP D - POP D - POP D - LXI H,-128-.2 - DAD SP - PUSH H - LXI H,.1+205 - PUSH H - CALL printf_ - POP D - POP D - LXI H,52 - PUSH H - LXI H,3 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,.1+208 - PUSH H - CALL printf_ - POP D - LXI H,52 - PUSH H - LXI H,4 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,2 - PUSH H - LXI H,.1+219 - PUSH H - CALL printf_ - POP D - POP D - LXI H,52 - PUSH H - LXI H,5 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,1 - PUSH H - LXI H,.1+228 - PUSH H - CALL printf_ - POP D - POP D - LXI H,52 - PUSH H - LXI H,6 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,1 - PUSH H - LXI H,.1+237 - PUSH H - CALL printf_ - POP D - POP D - LXI H,52 - PUSH H - LXI H,7 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,0 - PUSH H - LXI H,.1+246 - PUSH H - CALL printf_ - POP D - POP D - LXI H,52 - PUSH H - LXI H,10 - PUSH H - CALL crtlc_ - POP D - POP D - LXI H,29 - PUSH H - LXI H,8 - PUSH H - LXI H,12 - PUSH H - LXI H,.1+255 - PUSH H - CALL printf_ - XCHG - LXI H,8 - DAD SP - SPHL - LXI H,0 - PUSH H - LXI H,23 - PUSH H - CALL crtlc_ - POP D - POP D - RET -.2 EQU -136 -.1: - DB 112,111,115,116,32,71,69,84,73,78,70,79,32,105,114 - DB 101,103,104,108,32,105,115,32,48,120,37,48,52,120,10 - DB 0,66,65,78,75,69,82,46,67,79,77,32,37,100,47 - DB 37,100,47,37,100,32,118,37,100,46,37,100,46,37,100 - DB 46,37,100,0,32,100,119,103,32,45,32,68,105,115,112 - DB 108,97,121,32,77,101,109,111,114,121,32,66,97,110,107 - DB 32,67,104,97,114,97,99,116,101,114,105,115,116,105,99 - DB 115,0,82,79,77,32,66,97,110,107,49,0,82,77,74 - DB 32,61,32,37,100,0,82,77,78,32,61,32,37,100,0 - DB 82,85,80,32,61,32,37,100,0,82,84,80,32,61,32 - DB 37,100,0,37,115,0,67,66,73,79,83,32,72,68,82 - DB 0,82,77,74,32,61,32,37,100,0,82,77,78,32,61 - DB 32,37,100,0,82,85,80,32,61,32,37,100,0,82,84 - DB 80,32,61,32,37,100,0,37,115,0,37,115,0,66,65 - DB 78,75,69,82,46,67,79,77,0,82,77,74,32,61,32 - DB 37,100,0,82,77,78,32,61,32,37,100,0,82,85,80 - DB 32,61,32,37,100,0,82,84,80,32,61,32,37,100,0 - DB 37,48,50,100,37,48,50,100,37,48,50,100,0 - extrn crtlc_ - extrn crtclr_ - extrn crtinit_ - extrn printf_ - extrn diagnose_ - extrn hregde_ - extrn hregbc_ - extrn bioscall_ - extrn ireghl_ - extrn bdoscall_ - extrn dregde_ - extrn dregbc_ - extrn memset_ - extrn memcpy_ - extrn .eq - extrn .ul - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BANKER.C b/branches/s100/Apps/crossdev/BANKER.C deleted file mode 100644 index b6974de6..00000000 --- a/branches/s100/Apps/crossdev/BANKER.C +++ /dev/null @@ -1,153 +0,0 @@ -/* banker.c 6/7/2012 dwg - */ - -#include "stdio.h" -#include "stdlib.h" -#include "memory.h" - -/* #include "cpmbind.h" */ - -#include "std.h" -#include "infolist.h" -#include "metadata.h" - -/* #include "setlunum.h" */ - -#include "applvers.h" -#include "bdoscall.h" -#include "cpmbdos.h" -#include "bioscall.h" -#include "cpmbios.h" -#include "diagnose.h" -#include "cnfgdata.h" -#include "syscfg.h" -#include "applvers.h" - -#define COL1 0 -#define COL2 (80/3) -#define COL3 (2*COL2) -#define LINE 2 - -#define BDOS 5 /* memory address of BDOS invocation */ -#define HIGHSEG 0x0C000 /* memory address of system config */ - -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - -struct SYSCFG * pSYSCFG; -struct BIOS * pCBIOS; - -int main(argc,argv) - int argc; - char *argv[] ; -{ - - char * varloc; - char * tstloc; - char temp[128]; - - int i; - int bFirst; - - bFirst = 0; - - ireghl = pGETINFO; - bioscall(); - pINFOLIST = ireghl; - printf("post GETINFO ireghl is 0x%04x\n",pINFOLIST); - - pCBIOS = 0x0e600; - - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the NBIOS function */ - pSYSCFG = HIGHSEG; - - crtinit(pSYSCFG->cnfgdata.termtype); - crtclr(); - crtlc(0,0); - - printf("BANKER.COM %d/%d/%d v%d.%d.%d.%d", - A_MONTH,A_DAY,A_YEAR,A_RMJ,A_RMN,A_RUP,A_RTP); - printf(" dwg - Display Memory Bank Characteristics"); - - hregbc = 0x0f000; - hregde = 0x0c000; - diagnose(); - pSYSCFG = 0x0C000; - - crtlc(LINE+0,COL1); - crtlc(LINE+1,COL1); - printf("ROM Bank1"); - crtlc(LINE+2,COL1); - printf("RMJ = %d",pSYSCFG->cnfgdata.rmj); - crtlc(LINE+3,COL1); - printf("RMN = %d",pSYSCFG->cnfgdata.rmn); - crtlc(LINE+4,COL1); - printf("RUP = %d",pSYSCFG->cnfgdata.rup); - crtlc(LINE+5,COL1); - printf("RTP = %d",pSYSCFG->cnfgdata.rtp); - crtlc(LINE+7,COL1); - varloc = pSYSCFG->varloc; -/* dregde = (unsigned int)varloc-0x200+0x0c000; */ - dregde = (unsigned int)varloc+0x0c000; - - dregbc = 9; - bdoscall(); - crtlc(LINE+8,COL1); -/* tstloc = 0x0c000-0x0200+(unsigned int)pSYSCFG->tstloc; */ - tstloc = 0x0c000+(unsigned int)pSYSCFG->tstloc; - memset(temp,0,sizeof(temp)); - memcpy(temp,tstloc,11); - printf("%s",temp); - - crtlc(LINE+1,COL2); - printf("CBIOS HDR"); - crtlc(LINE+2,COL2); - printf("RMJ = %d",pCBIOS->rmj); - crtlc(LINE+3,COL2); - printf("RMN = %d",pCBIOS->rmn); - crtlc(LINE+4,COL2); - printf("RUP = %d",pCBIOS->rup); - crtlc(LINE+5,COL2); - printf("RTP = %d",pCBIOS->rtp); - /* */ - crtlc(LINE+7,COL2); - varloc = pINFOLIST->varloc; - memset(temp,0,sizeof(temp)); - memcpy(temp,varloc,sizeof(temp)-1); - for(i=0;itstloc; - memset(temp,0,sizeof(temp)); - memcpy(temp,tstloc,11); - printf("%s",temp); - - crtlc(LINE+1,COL3); - printf("BANKER.COM"); - crtlc(LINE+2,COL3); - printf("RMJ = %d",A_RMJ); - crtlc(LINE+3,COL3); - printf("RMN = %d",A_RMN); - crtlc(LINE+4,COL3); - printf("RUP = %d",A_RUP); - crtlc(LINE+5,COL3); - printf("RTP = %d",A_RTP); - - crtlc(LINE+8,COL3); - printf("%02d%02d%02d",A_YR,A_MONTH,A_DAY); - crtlc(23,0); -} - -/*****************/ -/* eof - cview.c */ -/*****************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BANNER.ASM b/branches/s100/Apps/crossdev/BANNER.ASM deleted file mode 100644 index 935a8671..00000000 --- a/branches/s100/Apps/crossdev/BANNER.ASM +++ /dev/null @@ -1,156 +0,0 @@ -; banner.asm 9/5/2012 dwg - new version semantics - #.#.# (#) - - maclib portab - maclib globals - maclib cpmbios - maclib cpmbdos - maclib bioshdr - maclib printers - maclib cpmappl - maclib applvers - - cseg - - -; entered with argv in hl - public x$banner -x$banner: - shld argv - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xprog ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xvers ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xprod ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xorig ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xser ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xnam ! xchg - - - printf '----------------------------------------' - print crlf - lhld xprog ! xchg ! mvi c,9 ! call BDOS - printf ' ' - IF A$MONTH LT 10 - conout ' ' - ENDIF - IF A$DAY LT 10 - conout ' ' - ENDIF - lxi h,A$MONTH - call pr$d$word - conout '/' - lxi h,A$DAY - call pr$d$word - conout '/' - lxi h,A$YEAR - call pr$d$word - printf ' ' - printf 'Version ' - lxi h,A$RMJ - call pr$d$word - conout '.' - lxi h,A$RMN - call pr$d$word - conout '.' - lxi h,A$RUP - call pr$d$word - printf ' (' - lxi h,A$RTP - call pr$d$word - conout ')' - print crlf - printf 'S/N ' - - lhld xprod ! xchg ! mvi c,9 ! call BDOS - - conout '-' - - lhld xorig ! xchg ! mvi c,9 ! call BDOS - - conout '-' - -; print xser - lhld xser ! xchg ! mvi c,9 ! call BDOS - - printf ' ' -; printf 'All Rights Reserved' - printf 'Licensed under GPL3' - print crlf - printf 'Copyright (C) 2011-12' - - lhld xnam ! xchg ! mvi c,9 ! call BDOS - - print crlf - printf '----------------------------------------' - print crlf - - ret - - -; entered with argv in hl - public x$sbanner -x$sbanner: - shld argv - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xprog ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xvers ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xprod ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xorig ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xser ! xchg - mov e,m ! inx h ! mov d,m ! inx h ! xchg ! shld xnam ! xchg - - -; printf '----------------------------------------' -; print crlf - lhld xprog ! xchg ! mvi c,9 ! call BDOS - printf ' ' - IF A$MONTH LT 10 - conout ' ' - ENDIF - IF A$DAY LT 10 - conout ' ' - ENDIF - lxi h,A$MONTH - call pr$d$word - conout '/' - lxi h,A$DAY - call pr$d$word - conout '/' - lxi h,A$YEAR - call pr$d$word - printf ' ' - printf 'Vers. ' - lxi h,A$RMJ - call pr$d$word - conout '.' - lxi h,A$RMN - call pr$d$word - conout '.' - lxi h,A$RUP - call pr$d$word - printf ' ( ' - lxi h,A$RTP - call pr$d$word - printf ') ' - printf 'COPR Douglas Goodall Licensed w/GPLv3' - - - print crlf - - ret - - -;---------------------------------------------------------------- - -argv ds 2 -;---------------- -xprog ds 2 -xvers ds 2 -xprod ds 2 -xorig ds 2 -xser ds 2 -xnam ds 2 - -crlf db CR,LF,'$' - - end - -; eof - banner.asm - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BANNER.H b/branches/s100/Apps/crossdev/BANNER.H deleted file mode 100644 index 447ec6a3..00000000 --- a/branches/s100/Apps/crossdev/BANNER.H +++ /dev/null @@ -1,4 +0,0 @@ -/* banner.h */ -extern sbanner(); -extern banner(); - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BANNER.LIB b/branches/s100/Apps/crossdev/BANNER.LIB deleted file mode 100644 index fca38939..00000000 --- a/branches/s100/Apps/crossdev/BANNER.LIB +++ /dev/null @@ -1,18 +0,0 @@ -; banner.lib 7/19/2012 dwg - for 2.0.0.0 B22 -; banner.lib 2/17/2012 dwg - review for release 1.5.1.0 -; banner.lib 2/11/2012 dwg - banner library declarations - - extrn x$banner -banner macro argv - lxi h,argv - call x$banner - endm - - extrn x$sbanner -sbanner macro argv - lxi h,argv - call x$sbanner - endm - -; eof - banner.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BANNER.SYM b/branches/s100/Apps/crossdev/BANNER.SYM deleted file mode 100644 index 78bc51c5..00000000 --- a/branches/s100/Apps/crossdev/BANNER.SYM +++ /dev/null @@ -1,29 +0,0 @@ -000F ADAY 0009 AL0OFS 000A AL1OFS 000E ALVOFS 0002 AMONTH -041E ARGV 0002 ARMJ 0002 ARMN 0000 ARTP 0000 ARUP -07DD AYEAR 0005 BDOS E600 BIBOOT E609 BICONIN E60C BICONOUT -E606 BICONST 0000 BIDRVA 0001 BIDRVB 0002 BIDRVC 0003 BIDRVD -0004 BIDRVE 0005 BIDRVF 0006 BIDRVG 0007 BIDRVH E618 BIHOME -E60F BILIST E62D BILISTST E612 BIPUNCH E627 BIREAD E615 BIREADER -E630 BISECTRN E61B BISELDSK E624 BISETDMA E621 BISETSEC E61E BISETTRK -E603 BIWBOOT E62A BIWRITE 0003 BLMOFS 0002 BSHOFS 0001 BYTESIZE -000B CKSOFS 003A COLON 000D CR 0001 CREAD 042C CRLF -0020 CROFS 000C CSVOFS 0012 CUROFS 0002 CWRITE 0010 D0OFS -0008 DBFOFS 0080 DEFBUF 000F DPBLEN 000A DPBOFS 0010 DPHLEN -0001 DRIVEB 0007 DRMOFS 0000 DROFS 000D DSKRESET 0005 DSMOFS -0001 ENGLISH 001B ESC 0004 EXMOFS 000C EXOFS 0001 F1OFS -0002 F2OFS 0003 F3OFS 0004 F4OFS 0005 F5OFS 0006 F6OFS -0007 F7OFS 0008 F8OFS 0000 FALSE 0024 FCBLEN 0010 FCLOSE -0023 FCOMPSIZE 0013 FDELETE 0016 FMAKE 000F FOPEN 0017 FRENAME -0020 LENFCB 000A LF 0010 LU1OFS 0011 LU2OFS 0010 MAXLABEL -0000 NEVER 0014 NLUOFS 00E5 OEMID 000D OFFOFS 0000 PRDWORD -0000 PRHBYTE 0000 PRHWORD 005C PRIFCB 0009 PRINTSTR 0021 R0OFS -0022 R1OFS 0023 R2OFS 000F RCOFS 000A READCONBUF 0014 READSEQ -0025 RESETDRIVE 0019 RETCURR 000C RETVERNO E64B RMJ E64C RMN -E64E RTP E64D RUP 0002 RV1OFS 0004 RV2OFS 0006 RV3OFS -000D S1OFS 000E S2OFS 006C SECFCB 000E SELDSK 001A SETDMA -0024 SETRANDREC 0000 SPANISH 0000 SPTOFS 0200 STACKSIZE 0009 T1OFS -000A T2OFS 000B T3OFS 0000 TERMCPM 0001 TRUE 0002 WORDSIZE -0022 WRITERAND 0028 WRITERANDZF 0015 WRITESEQ 0000 XBANNER -0000 XLTOFS 042A XNAM 0426 XORIG 0424 XPROD 0420 XPROG -02AB XSBANNER 0428 XSER 0422 XVERS - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BDOSCALL.ASM b/branches/s100/Apps/crossdev/BDOSCALL.ASM deleted file mode 100644 index 07850d39..00000000 --- a/branches/s100/Apps/crossdev/BDOSCALL.ASM +++ /dev/null @@ -1,71 +0,0 @@ -; bdoscall.asm 3/10/2012 dwg - bdos binding for Aztec C - - global drega_,1 - global dregbc_,2 - global dregde_,2 - global dreghl_,2 - - PUBLIC lurst_ -lurst_: - - push b - push d - push h - push psw - - mvi c,37 - lxi d,127 - lxi b,127 - call 5 - - pop psw - pop h - pop d - pop b - - RET - - - PUBLIC bdoscall_ -bdoscall_: - - push b - push d - push h - push psw - - lhld dregbc_ - mov b,h - mov c,l - - lhld dregde_ - mov d,h - mov e,l - - lhld dreghl_ - - lda drega_ - - call 5 - - sta drega_ - - shld dreghl_ - - mov l,e - mov h,d - shld dregde_ - - mov l,c - mov h,b - shld dregbc_ - - pop psw - pop h - pop d - pop b - - RET - - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BDOSCALL.H b/branches/s100/Apps/crossdev/BDOSCALL.H deleted file mode 100644 index b816e90a..00000000 --- a/branches/s100/Apps/crossdev/BDOSCALL.H +++ /dev/null @@ -1,8 +0,0 @@ -/* bdoscall.h 3/10/2012 dwg - header file for bdoscall */ - - extern char drega; - extern unsigned int dregbc; - extern unsigned int dregde; - extern unsigned int dreghl; - extern bdoscall(); - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BIN/AS80.EXE b/branches/s100/Apps/crossdev/BIN/AS80.EXE deleted file mode 100644 index 66dd9ba0..00000000 Binary files a/branches/s100/Apps/crossdev/BIN/AS80.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/BIN/CCZ.EXE b/branches/s100/Apps/crossdev/BIN/CCZ.EXE deleted file mode 100644 index 4fdb418e..00000000 Binary files a/branches/s100/Apps/crossdev/BIN/CCZ.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/BIN/HEX80.EXE b/branches/s100/Apps/crossdev/BIN/HEX80.EXE deleted file mode 100644 index f1c2bf1a..00000000 Binary files a/branches/s100/Apps/crossdev/BIN/HEX80.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/BIN/LIBUTIL.EXE b/branches/s100/Apps/crossdev/BIN/LIBUTIL.EXE deleted file mode 100644 index 57db8a9d..00000000 Binary files a/branches/s100/Apps/crossdev/BIN/LIBUTIL.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/BIN/LN80.EXE b/branches/s100/Apps/crossdev/BIN/LN80.EXE deleted file mode 100644 index 2213e719..00000000 Binary files a/branches/s100/Apps/crossdev/BIN/LN80.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/BIN/MAKE.EXE b/branches/s100/Apps/crossdev/BIN/MAKE.EXE deleted file mode 100644 index a541a8b3..00000000 Binary files a/branches/s100/Apps/crossdev/BIN/MAKE.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/BIOSCALL.ASM b/branches/s100/Apps/crossdev/BIOSCALL.ASM deleted file mode 100644 index f3a501de..00000000 --- a/branches/s100/Apps/crossdev/BIOSCALL.ASM +++ /dev/null @@ -1,80 +0,0 @@ -; bioscall.asm 3/10/2012 dwg - bios binding for Aztec C - - global irega_,1 - global iregbc_,2 - global iregde_,2 - global ireghl_,2 - - - public getmeta_ -getmeta_: - push psw - push b - push d - push h - - lxi b,4 - lxi d,0 - call 0e61bh - - lxi d,0 - call 0e61eh - - lxi d,11 - call 0e621h - - lxi d,80h - call 0e624h - - call 0e627h - - pop h - pop d - pop b - pop psw - ret - - PUBLIC bioscall_ -bioscall_: - - push b - push d - push h - push psw - - lhld iregbc_ - mov b,h - mov c,l - - lhld iregde_ - mov d,h - mov e,l - - lhld ireghl_ - shld mycall+1 - - lda irega_ - -mycall: call 5 - - sta irega_ - - shld ireghl_ - - mov l,e - mov h,d - shld iregde_ - - mov l,c - mov h,b - shld iregbc_ - - pop psw - pop h - pop d - pop b - - RET - - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BIOSCALL.H b/branches/s100/Apps/crossdev/BIOSCALL.H deleted file mode 100644 index a563b075..00000000 --- a/branches/s100/Apps/crossdev/BIOSCALL.H +++ /dev/null @@ -1,8 +0,0 @@ -/* bioscall.h 3/10/2012 dwg - header file for bdoscall */ - - extern char irega; - extern unsigned int iregbc; - extern unsigned int iregde; - extern unsigned int ireghl; - extern bioscall(); - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/BIOSHDR.LIB b/branches/s100/Apps/crossdev/BIOSHDR.LIB deleted file mode 100644 index f315a292..00000000 --- a/branches/s100/Apps/crossdev/BIOSHDR.LIB +++ /dev/null @@ -1,385 +0,0 @@ -; biohdr.lib 2/19/2012 dwg - BIOS header display macros -; copyright (C) 2011 Douglas Goodall. All Rights Reserved. -; Licensed to N8VEM Community for non-commercial use only. - -; 2/19/2012 dwg - review for release 1.5.1.0 -; 2/05/2012 dwg - added DSKM (DM_ROM...) better late than never -; 2/05/2012 dwg - added prpsdenable,prpsdtrace, and prpsdcapacity -; 1/16/2012 dwg - extend LU numbers to 0x1C entries (256MB) -; 1/11/2012 dwg - added new setlu for 1.4 slice technique -; 12/18/2011 dwg - added REVISION (from svn) -; 12/07/2011 dwg - BIOS header enhancement for version 1.3 - -; Common Configuration items, -; Valid in all configurations -RMJ equ 0E64Bh -RMN equ RMJ+1 -RUP equ RMN+1 -RTP equ RUP+1 - - if 0 -BANPTR equ RTP+1 -DKMP equ BANPTR+2 -DBBOOL equ DKMP+2 ; Disk Boot Boolean -DBDRV equ DBBOOL+1 ; Disk Boot Drive Code -FREQ equ DBDRV+1 -PLAT equ FREQ+1 ; Hardware Platform -DIOPLT equ PLAT+1 -VDUPLT equ DIOPLT+1 -ROMSIZ equ VDUPLT+1 -RAMSIZ equ ROMSIZ+2 -CRAM equ RAMSIZ+2 -DSKY equ CRAM+1 ; Is Display/Keyboard Attached? -UART equ DSKY+1 ; Is UART Enabled? -VDUEN equ UART+1 -FDEN equ VDUEN+1 ; Is Floppy Disk Support Enabled -FDTR equ FDEN+1 ; Is Floppy Disk Error Tracing Enabled? -FMED equ FDTR+1 ; Floppy Disk Media Type -FALT equ FMED+1 ; Alternative Floppy Disk Media Type -FAUT equ FALT+1 ; Is Floppy Disk Automatic Sensing Enabled? -IDEN equ FAUT+1 ; Is On-Board IDE Support Enabled -IDTR equ IDEN+1 -IDE8 equ IDTR+1 -IDCP equ IDE8+1 ; 1/13/2012 IDE Capacity -PPEN equ IDCP+2 ; Is PPIDE Support Enablned? -PPTR equ PPEN+1 ; Is PPIDE Tracing Enabled? -PP8B equ PPTR+1 -PPCP equ PP8B+1 ; 1/13/2012 PPIDE Capacity -PSLW equ PPCP+2 ; Use NOPs for recovery-time compensation -BTYP equ PSLW+1 -BTTO equ BTYP+1 -BTDF equ BTTO+1 -BAUD equ BTDF+1 ; What is the Console Baud Rate - -; Only Valid if PLATFORM == PLT_N8 -CLKDIV equ BAUD+2 ; Z180_CLKDIV -MEMWAIT equ CLKDIV+1 ; Z180_MEMWAIT -IOWAIT equ MEMWAIT+1 ; Z180_IOWAIT -CNTLB0 equ IOWAIT+1 ; Z180_CNTLB0 -CNTLB1 equ CNTLB0+1 ; Z180_CNTLB1 -SDENABLE equ CNTLB1+1 -SDTRACE equ SDENABLE+1 -SDCP equ SDTRACE+1 ; 1/13/2012 SD Capacity -VDPTR equ SDCP+2 ; pointer to VDU Data -FDPTR equ VDPTR+2 ; pointer to FD Data -IDEPTR equ FDPTR+2 ; pointer to IDE Data -PPIPTR equ IDEPTR+2 ; pointer to PPIDE_DATA Data -PPIPTR2 equ PPIPTR+2 ; pointer to PPIDE.ASM DATA - -DEFIO equ PPIPTR2+2 ; pointer to DEFIOBYTE -LDRC equ DEFIO+1 ; pointer to LDRCON -DBGC equ LDRC+1 ; pointer to DBGCON -TTYP equ DBGC+1 ; pointer to TERMTYPE -REV equ TTYP+1 ; subversion revision - -TMDT equ REV+2 ; startup date and time - -PSDE equ TMDT+6 ; prpsdenable -PSDT equ PSDE+1 ; prpsdtrace -PSDC equ PSDT+1 ; prpsdcapacity -PRCE equ PSDC+2 - -DSKM equ PRCE+1 ; DM_ROM... - -DTSZ equ DSKM+1 ; DATASIZE - -; LU0 LU1 LU2 LU3 LU4 LU5 LU6 LU7 LU8 LU9 -; 41 82 c3 104 145 186 1c7 208 249 286 -; -; LU10 LU11 LU12 LU13 LU14 LU15 LU16 -; 2c7 308 349 38a 3cb 40c 44d - -LU0 equ 0 ; 041h ; PPIDE1 offset for first slice (default) -LU1 equ 1 ; 082h ; PPIDE1 offset for second slice -LU2 equ 2 ; 0C3h ; PPIDE1 offset for third slice -LU3 equ 3 ; 104h ; PPIDE1 offset for fourth slice -LU4 equ 4 ; 145h ; PPIDE1 offset for fifth slice -LU5 equ 5 ; 186h ; PPIDE1 offset for sixth slice -LU6 equ 6 ; 1c7h ; PPIDE1 offset for seventh slice -LU7 equ 7 ; 208h ; PPIDE1 offset for eighth slice -LU8 equ 8 ; 249h ; PPIDE1 offset for ninth slice -LU9 equ 9 ; 286h ; PPIDE1 offset for tenth slice -LU10 equ 10 -LU11 equ 11 -LU12 equ 12 -LU13 equ 13 -LU14 equ 14 -LU15 equ 15 -LU16 equ 16 -LU17 equ 17 -LU18 equ 18 -LU19 equ 19 -LU20 equ 20 -LU21 equ 21 -LU22 equ 22 -LU23 equ 23 -LU24 equ 24 -LU25 equ 25 -LU26 equ 26 ; 0x1a -LU27 equ 27 ; 0x1b (1Cth entry) - - endif - -DRIVEB equ 1 ; 0=A, 1=B... - - -setlu13 macro offset - lxi h,PPIPTR2 ; set pointer to ppide.asm data - mov e,m ; dereference pointer - inx h - mov d,m ; de -> ppide.asm data - xchg ; hl -> ppide.asm data - lxi d,6 ; offset to offset - dad d ; hl -> offset in ppide.asm data - lxi d,offset ; load caller's parameter in de - mov m,e ; stuff LO offset byte into offset - inx h ; bump ptr - mov m,d ; stuff HO offset byte into offset - mvi c,13 ; BDOS DSKRESET - call 5 ; call BDOS - endm - -getlu13 macro - lxi h,PPIPTR2 ; set pointer to ppide.asm data - mov e,m ; dereference pointer - inx h - mov d,m ; de -> ppide.asm data - xchg ; hl -> ppide.asm data - lxi d,6 ; offset to offset - dad d ; hl -> offset in ppide.asm data - mov e,m ; pick up LO byte of offset - inx h ; bump ptr - mov d,m ; pick up HO byte of offset - xchg ; hl = offset - endm - -setlu14 macro offset - lxi h,PPIPTR2 ; set pointer to ppide.asm data - mov e,m ; dereference pointer - inx h - mov d,m ; de -> ppide.asm data - xchg ; hl -> ppide.asm data - lxi d,6 ; offset to offset - dad d ; hl -> offset in ppide.asm data - lxi d,offset ; load caller's parameter in de - mov m,e ; stuff LO offset byte into offset - inx h ; bump ptr - mov m,d ; stuff HO offset byte into offset - mvi c,13 ; BDOS DSKRESET - call 5 ; call BDOS - endm - -getlu14 macro - lxi h,PPIPTR2 ; set pointer to ppide.asm data - mov e,m ; dereference pointer - inx h - mov d,m ; de -> ppide.asm data - xchg ; hl -> ppide.asm data - lxi d,6 ; offset to offset - dad d ; hl -> offset in ppide.asm data - mov e,m ; pick up LO byte of offset - inx h ; bump ptr - mov d,m ; pick up HO byte of offset - xchg ; hl = offset - endm - -setlu macro drive,slice - local dontboth,msg,msg2 - mvi c,drive - call BISELDSK - lxi d,16 - dad d - mov a,m - cpi 'L' - jnz dontboth - inx h - mov a,m - cpi 'U' - jnz dontboth - inx h - mvi a,slice - mov m,a - print msg - mvi a,drive - adi 'A' - mov e,a - mvi c,2 - call BDOS - print msg2 - lxi h,slice - call pr$d$word - jmp dontboth -msg db CR,LF,'Drive $' -msg2 db ': set to Logical Unit (slice) $' -dontboth: - endm - - -xluset macro - local ldrive,lslice,dontboth,msg,msg2 - ; C = DRIVE - ; A = SLICE - sta lslice - mov a,c - sta ldrive - - call BISELDSK ; uses c parameter (drive) - lxi d,16 - dad d - mov a,m - cpi 'L' - jnz dontboth - inx h - mov a,m - cpi 'U' - jnz dontboth - inx h - lda lslice - mov m,a ; put slice into CURRENT - -; print msg -; lda ldrive -; adi 'A' -; mov e,a -; mvi c,2 -; call BDOS -; print msg2 -; lda lslice -; mov l,a -; mvi h,0 -; call pr$d$word - - jmp dontboth -msg db CR,LF,'Drive $' -msg2 db ': set to Logical Unit (slice) $' -ldrive db 0 -lslice db 0 -dontboth: - endm - - - - - - - -hdrlit macro ptr,val,msg - local notval - lxi h,ptr - mvi a,val - cmp m - jnz notval - print msg -notval: - endm - - -hdrbool macro ptr,tmsg,fmsg - local itstrue,itsfalse,imdone - enter - lxi h,ptr - mov a,m - cpi TRUE - jnz itsfalse - lxi d,tmsg - jmp imdone -itsfalse: lxi d,fmsg -imdone: mvi c,PRINTSTR - call BDOS - leave - endm - -hdrbyte macro ptr,msg - enter - mvi c,PRINTSTR - lxi d,msg - call BDOS - lxi h,ptr - mov a,m - call pr$h$byte - - conout '(' - mov e,m - mov d,0 - xchg - call pr$d$word - conout ')' - - leave - endm - -hdrpbyte macro ptr,msg - enter - mvi c,PRINTSTR - lxi d,msg - call BDOS - lxi h,PTR - mov e,m - inx h - mov d,m - xchg - mov a,m - call pr$h$byte - -; conout ' ' - conout '(' - mov e,m - mov d,0 - xchg - call pr$d$word - conout ')' - leave - endm - -hdrword macro ptr,msg - enter - - mvi c,PRINTSTR - lxi d,msg - call BDOS - - lxi h,ptr - inx h - mov a,m - call pr$h$byte - - lxi h,ptr - mov a,m - call pr$h$byte - - conout '(' - lxi h,ptr - mov e,m - inx h - mov d,m - xchg - call pr$d$word - conout ')' - leave - endm - -syncerr macro - print syncmsg - exit - endm - -hdrvalid macro - local byte1ok,byte2ok - enter - lxi h,CFDA - mov a,m - cpi 0DAh - jz byte1ok - syncerr -byte1ok: - inx h - mov al,m - cpi 0CFh - jz byte2ok - syncerr -byte2ok: - leave - endm - -; eof - bioshdr.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/C.LIB b/branches/s100/Apps/crossdev/C.LIB deleted file mode 100644 index 2ca5ab78..00000000 Binary files a/branches/s100/Apps/crossdev/C.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CBANNER.C b/branches/s100/Apps/crossdev/CBANNER.C deleted file mode 100644 index 0735bee5..00000000 --- a/branches/s100/Apps/crossdev/CBANNER.C +++ /dev/null @@ -1,41 +0,0 @@ -/* cbanner.c 3/12/2012 dwg - */ - -#include "portab.h" -#include "globals.h" -#include "applvers.h" - -char * lines = "----------------------------------------"; -char * line1 = "12345678.123 mm/dd/yyyy Version x.x.x.x"; -char * line2 = "S/N CPM80-DWG-654321 Licensed under GPL3"; -char * line3 = "Copyright (C) 2011-12 Douglas W. Goodall"; - -sbanner(program) - char *program; -{ - char szTemp[128]; - - printf("%s ",program); - printf("%2d/%2d/%4d ",A_MONTH,A_DAY,A_YEAR); - printf("Version %d.%d.%d.%d ",A_RMJ,A_RMN,A_RUP,A_RTP); - printf("COPR Douglas Goodall Licensed w/GPLv3\n"); -} - -banner(program) - char *program; -{ - char szTemp[128]; - - printf("%s\n",lines); - strcpy(szTemp,program); - while(12 > strlen(szTemp)) { - strcat(szTemp," "); - } - printf("%s ",szTemp); - printf("%2d/%2d/%4d ",A_MONTH,A_DAY,A_YEAR); - printf("Version %d.%d.%d.%d\n",A_RMJ,A_RMN,A_RUP,A_RTP); - printf("%s\n",line2); - printf("%s\n",line3); - printf("%s\n",lines); -} - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CBANNER.H b/branches/s100/Apps/crossdev/CBANNER.H deleted file mode 100644 index 43c1908a..00000000 --- a/branches/s100/Apps/crossdev/CBANNER.H +++ /dev/null @@ -1 +0,0 @@ -åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CC.COM b/branches/s100/Apps/crossdev/CC.COM deleted file mode 100644 index 1fbf701b..00000000 Binary files a/branches/s100/Apps/crossdev/CC.COM and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CC.TMP b/branches/s100/Apps/crossdev/CC.TMP deleted file mode 100644 index 24a91743..00000000 --- a/branches/s100/Apps/crossdev/CC.TMP +++ /dev/null @@ -1,333 +0,0 @@ - extrn .begin,.chl,.swt - extrn zsave,zret - global termtype_,1 - DSEG - public wy50row_ -wy50row_: - DB 32 - DB 33 - DB 34 - DB 35 - DB 36 - DB 37 - DB 38 - DB 39 - DB 40 - DB 41 - DB 42 - DB 43 - DB 44 - DB 45 - DB 46 - DB 47 - DB 48 - DB 49 - DB 50 - DB 51 - DB 52 - DB 53 - DB 54 - DB 55 - CSEG - DSEG - public wy50col_ -wy50col_: - DB 32 - DB 33 - DB 34 - DB 35 - DB 36 - DB 37 - DB 38 - DB 39 - DB 40 - DB 41 - DB 42 - DB 43 - DB 44 - DB 45 - DB 46 - DB 47 - DB 48 - DB 49 - DB 50 - DB 51 - DB 52 - DB 53 - DB 54 - DB 55 - DB 56 - DB 57 - DB 58 - DB 59 - DB 60 - DB 61 - DB 62 - DB 63 - DB 64 - DB 65 - DB 66 - DB 67 - DB 68 - DB 69 - DB 70 - DB 71 - DB 72 - DB 73 - DB 74 - DB 75 - DB 76 - DB 77 - DB 78 - DB 79 - DB 80 - DB 81 - DB 82 - DB 83 - DB 84 - DB 85 - DB 86 - DB 87 - DB 88 - DB 89 - DB 90 - DB 91 - DB 92 - DB 93 - DB 94 - DB 95 - DB 96 - DB 97 - DB 98 - DB 99 - DB 100 - DB 101 - DB 102 - DB 103 - DB 104 - DB 105 - DB 106 - DB 107 - DB 108 - DB 109 - DB 110 - DB 111 - CSEG - PUBLIC crtinit_ -crtinit_: lxi d,.2 - call zsave - LXI H,12-.2 - DAD SP - MOV E,M - XCHG - MOV A,L - STA termtype_ - RET -.2 EQU 0 - PUBLIC crtclr_ -crtclr_: lxi d,.3 - call zsave - LDA termtype_ - MOV L,A - MVI H,0 - JMP .4 -.6: - LXI H,0 - XCHG - LXI H,6-.3 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .8 -.7: - LXI H,6-.3 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.8: - LXI H,6-.3 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,43 - CALL .lt - JZ .9 - LXI H,10 - PUSH H - LXI H,13 - PUSH H - LXI H,.1+0 - PUSH H - CALL printf_ - POP D - POP D - POP D - JMP .7 -.9: - JMP .5 -.10: - LXI H,27 - PUSH H - LXI H,.1+5 - PUSH H - CALL printf_ - POP D - POP D - JMP .5 -.11: - LXI H,27 - PUSH H - LXI H,.1+11 - PUSH H - CALL printf_ - POP D - POP D - JMP .5 -.12: - LXI H,27 - PUSH H - LXI H,27 - PUSH H - LXI H,.1+15 - PUSH H - CALL printf_ - POP D - POP D - POP D - JMP .5 -.4: - CALL .swt - DW 4 - DW 0,.6 - DW 1,.10 - DW 2,.11 - DW 3,.12 - DW .5 -.5: - RET -.3 EQU -2 -.1: - DB 37,99,37,99,0,37,99,91,50,74,0,37,99,43,0 - DB 37,99,74,37,99,72,0 - PUBLIC crtlc_ -crtlc_: lxi d,.14 - call zsave - LDA termtype_ - MOV L,A - MVI H,0 - JMP .15 -.17: - JMP .16 -.18: - LXI H,102 - PUSH H - LXI H,16-.14 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,16-.14 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,27 - PUSH H - LXI H,.13+0 - PUSH H - CALL printf_ - XCHG - LXI H,10 - DAD SP - SPHL - JMP .16 -.19: - LXI H,14-.14 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,wy50col_ - DAD D - DCX H - MOV E,M - MVI D,0 - PUSH D - LXI H,14-.14 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,wy50row_ - DAD D - DCX H - MOV E,M - MVI D,0 - PUSH D - LXI H,27 - PUSH H - LXI H,.13+11 - PUSH H - CALL printf_ - XCHG - LXI H,8 - DAD SP - SPHL - JMP .16 -.20: - LXI H,14-.14 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,32 - DAD D - PUSH H - LXI H,14-.14 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,32 - DAD D - PUSH H - LXI H,27 - PUSH H - LXI H,.13+19 - PUSH H - CALL printf_ - XCHG - LXI H,8 - DAD SP - SPHL - JMP .16 -.15: - CALL .swt - DW 4 - DW 0,.17 - DW 1,.18 - DW 2,.19 - DW 3,.20 - DW .16 -.16: - RET -.14 EQU -2 -.13: - DB 37,99,91,37,100,59,37,100,37,99,0,37,99,61,37 - DB 99,37,99,0,37,99,89,37,99,37,99,0 - extrn printf_ - extrn .lt - END diff --git a/branches/s100/Apps/crossdev/CHARS.C b/branches/s100/Apps/crossdev/CHARS.C deleted file mode 100644 index 10d3fd1e..00000000 --- a/branches/s100/Apps/crossdev/CHARS.C +++ /dev/null @@ -1,152 +0,0 @@ -/* chars.c 6/7/2012 dwg - test command line arguments */ - -#include "stdio.h" - -#include "portab.h" -#include "globals.h" -#include "std.h" -#include "cpm80.h" -#include "cpmappl.h" -#include "applvers.h" -#include "cnfgdata.h" -#include "syscfg.h" - -#define TOP 0 -#define LEFT 4 - -#define BDOS 5 /* memory address of BDOS invocation */ -#define HIGHSEG 0x0C000 /* memory address of system config */ - -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - -struct SYSCFG * pSYSCFG = HIGHSEG; - -char map[256] = -{ -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 0 - 9 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 A - O */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 P - Z */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 a - o */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 7 p - z */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B 0 - 9 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C A - O */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D P - Z */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E a - o */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* F p - z */ -}; - -char attroff[] = { 27, '[', 'm', 0 }; -char attrbold[] = { 27, '[', '1', 'm', 0 }; -char attrlow[] = { 27, '[', '2', 'm', 0 }; -char attrundr[] = { 27, '[', '4', 'm', 0 }; -char attrblnk[] = { 27, '[', '5', 'm', 0 }; -char attrrevs[] = { 27, '[', '7', 'm', 0 }; -char attrinvs[] = { 27, '[', '8', 'm', 0 }; -char graphon[] = { 27, 'F', 0 }; -char graphoff[] = { 27, 'G', 0 }; - - -char atreset[] = "0"; -char atbold[] = "1"; -char atdim[] = "2"; -char atundrscr[] = "4"; -char atblink[] = "5"; -char atrevs[] = "7"; -char athidden[] = "8"; - -char fgblack[] = "30"; -char fgred[] = "31"; -char fggreen[] = "32"; -char fgyellow[] = "33"; -char fgblue[] = "34"; -char fgmagenta[] = "35"; -char fgcyan[] = "36"; -char fgwhite[] = "37"; - -char bgblack[] = "40"; -char bgred[] = "41"; -char bggreen[] = "42"; -char bgyellow[] = "43"; -char bgblue[] = "44"; -char bgmagenta[] = "45"; -char bgcyan[] = "46"; -char bgwhite[] = "47"; - -dispattr(attr,fg,bg) - char * attr; - char * fg; - char * bg; -{ - printf("%c[%s;%s;%sm",27,attr,fg,bg); -} - -int main(argc,argv) - int argc; - char *argv[]; -{ - int i,j,k; - int x,y; - - if(1 < argc) { - for(i=1;icnfgdata.termtype); */ - - - crtinit(pSYSCFG->cnfgdata.termtype); - crtclr(); - crtlc(0,0); - - dispattr(atbold,fggreen,bgblack); - banner("CHARS"); - - printf("%s",attroff); - - dispattr(atbold,fgcyan,bgblack); - for(x=0;x<16;x++) { - crtlc(TOP+6,LEFT+(x*4)+5); - printf("[%x]",x); - } - printf("%s",attroff); - - for(y=0;y<16;y++) { - crtlc(TOP+y+7,LEFT+0); - dispattr(atbold,fgcyan,bgblack); - printf("[%x]",y); - printf("%s",attroff); - - for(x=0;x<16;x++) { - crtlc(TOP+y+7,LEFT+(x*4)+6); - if(1 == map[(y*16)+x]) { - printf("."); - } else { - printf("%c",(y*16)+x); - } - } - dispattr(atbold,fgcyan,bgblack); - printf(" [%x]",y); - printf("%s",attroff); - } - } - - return 0; -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CHARS.SUB b/branches/s100/Apps/crossdev/CHARS.SUB deleted file mode 100644 index 3a21c6d9..00000000 --- a/branches/s100/Apps/crossdev/CHARS.SUB +++ /dev/null @@ -1,18 +0,0 @@ -e:rem chars.sub 7/22/2012 dwg - build chars from source -cc chars -as chars -as bdoscall -as bioscall -as diagnose -cc cbanner -as cbanner -cc ctermcap -as ctermcap -ln chars.o bdoscall.o bioscall.o cbanner.o diagnose.o ctermcap.o c.lib -era chars.o -era bdoscall.o -era bioscall.o -era diagose.o -era cbanner.o -era ctermcap.o - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CHECK.SUB b/branches/s100/Apps/crossdev/CHECK.SUB deleted file mode 100644 index bc711968..00000000 --- a/branches/s100/Apps/crossdev/CHECK.SUB +++ /dev/null @@ -1,12 +0,0 @@ -e:access access.com -e:access cpmname.com -e:access findfile.com -e:access map.com -e:access meta.com -e:access multifmt.com -e:access rem.com -e:access setlabel.com -e:access sysgen.com -e:access termtype.com -e:access view.com - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CLEAN.BAT b/branches/s100/Apps/crossdev/CLEAN.BAT deleted file mode 100644 index 0d83b8e4..00000000 --- a/branches/s100/Apps/crossdev/CLEAN.BAT +++ /dev/null @@ -1,118 +0,0 @@ -if exist *.bak erase *.bak -if exist *.prn erase *.prn -if exist *.o erase *.o -if exist *.rel erase *.rel -if exist *.cpm erase *.cpm -if exist 2drive.asm erase 2drive.asm -if exist 2map.asm erase 2map.asm -if exist banker.asm erase banker.asm -if exist cbanner.asm erase cbanner.asm -if exist chars.asm erase chars.asm -if exist clear.asm erase clear.asm -if exist clogical.asm erase clogical.asm -if exist cls.asm erase cls.asm -if exist cmemory.asm erase cmemory.asm -if exist cnamept*.asm erase cnamept*.asm -if exist convert.asm erase convert.asm -if exist cpmname.asm erase cpmname.asm -if exist ctermcap.asm erase ctermcap.asm -if exist cvt2h.asm erase cvt2h.asm -if exist diskcopy.asm erase diskcopy.asm -if exist doit.asm erase doit.asm -if exist dump.asm erase dump.asm -if exist editor.asm erase editor.asm -if exist flip.asm erase flip.asm -if exist form.asm erase form.asm -if exist formfeed.asm erase formfeed.asm -if exist getcfg.asm erase getcfg.asm -if exist hello.asm erase hello.asm -if exist help.asm erase help.asm -if exist label.asm erase label.asm -if exist map.asm erase map.asm -if exist menu.asm erase menu.asm -if exist menu1.asm erase menu1.asm -if exist menucol.asm erase menucol.asm -if exist meta.asm erase meta.asm -if exist mkrasm80.asm erase mkrasm80.asm -if exist monitor.asm erase monitor.asm -if exist multifmt.asm erase multifmt.asm -if exist n8chars.asm erase n8chars.asm -if exist n8vidtst.asm erase n8vidtst.asm -if exist portio.asm erase portio.asm -if exist psecio.asm erase psecio.asm -if exist putc.asm erase putc.asm -if exist reconv.asm erase reconv.asm -if exist remote.asm erase remote.asm -if exist sectorio.asm erase sectorio.asm -if exist stat9918.asm erase stat9918.asm -if exist sysgen.asm erase sysgen.asm -if exist termtype.asm erase termtype.asm -if exist test.asm ertase test.asm -if exist tester.asm erase tester.asm -if exist testn8.asm erase testn8.asm -if exist testv5.asm erase testv5.asm -if exist testv6.asm erase testv6.asm -if exist tms9918.asm erase tms9918.asm -if exist tms9918x.asm erase tms9918x.asm -if exist tmsbind.asm erase tmsbind.asm -if exist tmsstat.asm erase tmsstat.asm -if exist trackio.asm erase trackio.asm -if exist video.asm erase video.asm -if exist view.asm erase view.asm -if exist 2drive.o erase 2drive.o -if exist 2map.o erase 2map.o -if exist banker.o erase banker.o -if exist cbanner.o erase cbanner.o -if exist chars.o erase chars.o -if exist clear.o erase clear.o -if exist clogical.o erase clogical.o -if exist cls.o erase cls.o -if exist cmemory.o erase cmemory.o -if exist cnamept*.o erase cnamept*.o -if exist convert.o erase convert.o -if exist cpmname.o erase cpmname.o -if exist ctermcap.o erase ctermcap.o -if exist cvt2h.o erase cvt2h.o -if exist diskcopy.o erase diskcopy.o -if exist doit.o erase doit.o -if exist dump.o erase dump.o -if exist editor.o erase editor.o -if exist flip.o erase flip.o -if exist form.o erase form.o -if exist formfeed.o erase formfeed.o -if exist getcfg.o erase getcfg.o -if exist hello.o erase hello.o -if exist help.o erase help.o -if exist label.o erase label.o -if exist map.o erase map.o -if exist menu.o erase menu.o -if exist menu1.o erase menu1.o -if exist menucol.o erase menucol.o -if exist meta.o erase meta.o -if exist metadata.o erase metadata.o -if exist mkrasm80.o erase mkrasm80.o -if exist monitor.o erase monitor.o -if exist multifmt.o erase multifmt.o -if exist n8chars.o erase n8chars.o -if exist n8vidtst.o erase n8vidtst.o -if exist portio.o erase portio.o -if exist psecio.o erase psecio.o -if exist putc.o erase putc.o -if exist reconv.o erase reconv.o -if exist remote.o erase remote.o -if exist sectorio.o erase sectorio.o -if exist stat9918.o erase stat9918.o -if exist sysgen.o erase sysgen.o -if exist termtype.o erase termtype.o -if exist test.o ertase test.o -if exist tester.o erase tester.o -if exist testn8.o erase testn8.o -if exist testv5.o erase testv5.o -if exist testv6.o erase testv6.o -if exist tms9918.o erase tms9918.o -if exist tms9918x.o erase tms9918x.o -if exist tmsbind.o erase tmsbind.o -if exist tmsstat.o erase tmsstat.o -if exist trackio.o erase trackio.o -if exist video.o erase video.o -if exist view.o erase view.o diff --git a/branches/s100/Apps/crossdev/CLEAN.SUB b/branches/s100/Apps/crossdev/CLEAN.SUB deleted file mode 100644 index 46363e2d..00000000 --- a/branches/s100/Apps/crossdev/CLEAN.SUB +++ /dev/null @@ -1,27 +0,0 @@ -era *.bak -era *.prn -era *.rel -era *.sym -era *.lst -era *.o -era sect0*.h -era sect1*.h -era sect2*.h -era sect3*.h -era sect4*.h -era sect5*.h -era sect6*.h -era sect7*.h -era sect8*.h -era sect9*.h -era sect0*.inc -era sect1*.inc -era sect2*.inc -era sect3*.inc -era sect4*.inc -era sect5*.inc -era sect6*.inc -era sect7*.inc -era sect8*.inc -era sect9*.inc - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CLEAR.C b/branches/s100/Apps/crossdev/CLEAR.C deleted file mode 100644 index 2edfea8d..00000000 --- a/branches/s100/Apps/crossdev/CLEAR.C +++ /dev/null @@ -1,48 +0,0 @@ -/* clear.c 11/23/2012 dwg - */ - -#include "portab.h" -#include "globals.h" - -#include "stdio.h" -#include "stdlib.h" -#include "memory.h" -#include "applvers.h" -#include "n8chars.h" -#include "tms9918.h" -#include "std.h" -#include "ctermcap.h" -#include "cpmbdos.h" -#include "bdoscall.h" -#include "hbios.h" -#include "asmiface.h" -#include "diagnose.h" -#include "cnfgdata.h" -#include "syscfg.h" -#include "cpmbind.h" -#include "infolist.h" -#include "metadata.h" -#include "clogical.h" - -#define HIGHSEG 0x0C000 /* memory address of system config */ - -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - -struct CNFGDATA * pCNFGDATA; -struct SYSCFG * pSYSCFG; - -int main(argc,argv) - int argc; - char *argv[]; -{ - char column; - - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the NBIOS function */ - pSYSCFG = HIGHSEG; - crtinit(pSYSCFG->cnfgdata.termtype); - crtclr(); - crtlc(0,0); -} - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CLEAR.SUB b/branches/s100/Apps/crossdev/CLEAR.SUB deleted file mode 100644 index 5a9b9907..00000000 --- a/branches/s100/Apps/crossdev/CLEAR.SUB +++ /dev/null @@ -1,10 +0,0 @@ -e:rem clear.sub 7/22/2012 dwg - build clear from sources -cc clear -as clear -as bdoscall -as bioscall -cc ctermcap -as ctermcap -as diagnose -ln clear.o diagnose.o bioscall.o bdoscall.o ctermcap.o c.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CLOGICAL.C b/branches/s100/Apps/crossdev/CLOGICAL.C deleted file mode 100644 index c3975c11..00000000 --- a/branches/s100/Apps/crossdev/CLOGICAL.C +++ /dev/null @@ -1,57 +0,0 @@ -/* clogical.c 6/4/2012 dwg - */ - -#include "portab.h" -#include "cpmbios.h" -#include "asmiface.h" - -lugcur(drive) -{ - asmif(pGETLU,drive,0,0); - return xregde; -} - -lugnum(drive) -{ - asmif(pGETLU,drive,0,0); - return xreghl; -} - -lugdu(drive) -{ - asmif(pGETLU,drive,0,0); - return xregbc>>8; -} - -luscur(drive,lunum) -{ - asmif(pGETLU,drive,0,0); - /* A = Result 0=OK */ - /* B = devunit */ - /* DE = current */ - /* HL = numlu */ - - /* BC = devunit*256+drive */ - /* DE = current */ - /* HL = numlu */ - asmif(pSETLU,xregbc,lunum,xreghl); -} - -lusnum(drive,numlu) -{ - asmif(pGETLU,drive,0,0); - /* A = Result 0=OK */ - /* B = devunit */ - /* DE = current */ - /* HL = numlu */ - - /* BC = devunit*256+drive */ - /* DE = current */ - /* HL = numlu */ - asmif(pSETLU,xregbc,xregde,numlu); -} - - -/********************/ -/* eof - clogical.c */ -/********************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CLOGICAL.H b/branches/s100/Apps/crossdev/CLOGICAL.H deleted file mode 100644 index c0624494..00000000 --- a/branches/s100/Apps/crossdev/CLOGICAL.H +++ /dev/null @@ -1,14 +0,0 @@ -/*****************************/ -/* clogical.H 6/4/2012 dwg - */ -/*****************************/ - -extern lugdu(); -extern lugcur(); -extern luscur(); -extern lugnum(); -extern lusnum(); - -/********************/ -/* eof - clogical.h */ -/********************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CLS.C b/branches/s100/Apps/crossdev/CLS.C deleted file mode 100644 index 2bbf9c2f..00000000 --- a/branches/s100/Apps/crossdev/CLS.C +++ /dev/null @@ -1,127 +0,0 @@ -/* cls.c 7/21/2012 dwg - elegant form of clear screen program */ - -/* -#include "stdio.h" -#include "applvers.h" -*/ - -/* declarations for HBIOS access */ -extern char hrega; -extern unsigned int hregbc; -extern unsigned int hregde; -extern unsigned int hreghl; -extern diagnose(); - -/* declaration dir BIOS and BDOS and low level calls */ -extern char xrega; -extern unsigned int xregbc; -extern unsigned int xregde; -extern unsigned int xreghl; -extern asmif(); /* asmif(0x0E6**,bc,de,hl); */ - -#define BDOS 5 /* memory address of BDOS invocation */ -#define HIGHSEG 0x0C000 /* memory address of system config */ - -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - -/* pointer based Configuration Data structure */ -struct CNFGDATA { - unsigned char rmj; - unsigned char rmn; - unsigned char rup; - unsigned char rtp; - unsigned char diskboot; - unsigned char devunit; - unsigned int bootlu; - unsigned char hour; - unsigned char minute; - unsigned char second; - unsigned char month; - unsigned char day; - unsigned char year; - unsigned char freq; - unsigned char platform; - unsigned char dioplat; - unsigned char vdumode; - unsigned int romsize; - unsigned int ramsize; - unsigned char clrramdk; - unsigned char dskyenable; - unsigned char uartenable; - unsigned char vduenable; - unsigned char fdenable; - unsigned char fdtrace; - unsigned char fdmedia; - unsigned char fdmediaalt; - unsigned char fdmauto; - unsigned char ideenable; - unsigned char idetrace; - unsigned char ide8bit; - unsigned int idecapacity; - unsigned char ppideenable; - unsigned char ppidetrace; - unsigned char ppide8bit; - unsigned int ppidecapacity; - unsigned char ppideslow; - unsigned char boottype; - unsigned char boottimeout; - unsigned char bootdefault; - unsigned int baudrate; - unsigned char ckdiv; - unsigned char memwait; - unsigned char iowait; - unsigned char cntlb0; - unsigned char cntlb1; - unsigned char sdenable; - unsigned char sdtrace; - unsigned int sdcapacity; - unsigned char sdcsio; - unsigned char sdcsiofast; - unsigned char defiobyte; - unsigned char termtype; - unsigned int revision; - unsigned char prpsdenable; - unsigned char prpsdtrace; - unsigned int prpsdcapacity; - unsigned char prpconenable; - unsigned int biossize; - unsigned char pppenable; - unsigned char pppsdenable; - unsigned char pppsdtrace; - unsigned int pppsdcapacity; - unsigned char pppconenable; - unsigned char prpenable; -}; - -struct JMP { - unsigned char opcode; /* JMP opcode */ - unsigned int address; /* JMP address */ -}; - -struct SYSCFG { - struct JMP jmp; - void * cnfloc; - void * tstloc; - void * varloc; - struct CNFGDATA cnfgdata; - char filler[256-3-2-2-2-sizeof(struct CNFGDATA)]; -} * pSYSCFG = HIGHSEG; - - -main(argc,argv) - int argc; - char *argv[]; -{ - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the HBIOS function */ - - crtinit(pSYSCFG->cnfgdata.termtype); /* pass termtype to init */ - - crtclr(); - - crtlc(0,0); -} - - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CMEMORY.ASM b/branches/s100/Apps/crossdev/CMEMORY.ASM deleted file mode 100644 index cb11cdc3..00000000 --- a/branches/s100/Apps/crossdev/CMEMORY.ASM +++ /dev/null @@ -1,283 +0,0 @@ - extrn .begin,.chl,.swt - extrn csave,cret,.move - PUBLIC memcmp_ -memcmp_: lxi d,.2 - call csave - LXI H,8-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,2-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,10-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,0-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,0 - XCHG - LXI H,-2-.2 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .4 -.3: - LXI H,-2-.2 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.4: - LXI H,-2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,12-.2 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .lt - JZ .5 - LXI H,0-.2 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D - XCHG - DCX H - MOV E,M - MVI D,0 - PUSH D - LXI H,4-.2 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D - XCHG - DCX H - MOV E,M - MVI D,0 - POP H - CALL .ne - JZ .6 - LXI H,0 - RET -.6: - JMP .3 -.5: - LXI H,1 - RET -.2 EQU -6 - PUBLIC memcpy_ -memcpy_: lxi d,.7 - call csave - LXI H,10-.7 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,2-.7 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,8-.7 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,0-.7 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,0 - XCHG - LXI H,-2-.7 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .9 -.8: - LXI H,-2-.7 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.9: - LXI H,-2-.7 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,12-.7 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .lt - JZ .10 - LXI H,2-.7 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D - XCHG - DCX H - MOV E,M - PUSH D - LXI H,2-.7 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D - XCHG - DCX H - POP D - MOV M,E - JMP .8 -.10: - RET -.7 EQU -6 - PUBLIC memset_ -memset_: lxi d,.11 - call csave - LXI H,8-.11 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,2-.11 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,0 - XCHG - LXI H,0-.11 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .13 -.12: - LXI H,0-.11 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.13: - LXI H,0-.11 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,12-.11 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .ul - JZ .14 - LXI H,10-.11 - DAD SP - MOV E,M - PUSH D - LXI H,4-.11 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D - XCHG - DCX H - POP D - MOV M,E - JMP .12 -.14: - RET -.11 EQU -4 - extrn .ne - extrn .lt - extrn .ul - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CMEMORY.C b/branches/s100/Apps/crossdev/CMEMORY.C deleted file mode 100644 index ba33be0e..00000000 --- a/branches/s100/Apps/crossdev/CMEMORY.C +++ /dev/null @@ -1,53 +0,0 @@ -/* cmemory.c 3/13/2012 dwg - */ - -#include "portab.h" -/* #include "cpmbind.h" */ - -memcmp(xptr,yptr,count) - u8 * xptr; - u8 * yptr; - int count; -{ - u8 * x; - u8 * y; - int i; - - x = xptr; - y = yptr; - for(i=0;idphmap; - pDPH = pDPHVEC[drive] - pDPB = pDPH->dpb; - if(0 < pDPB->off) { - return TRUE; - } else { - return FALSE; - } - -} - -int getmeta(drive,buffer) - int drive; - struct METADATA * buffer; -{ - if(TRUE == hasmeta(drive)) { - rdsector(drive,track,sector,buffer,0); - return SUCCESS; - } else { - return FAILURE; - } -} - -int putmeta(drive,buffer) - int drive; - struct METADATA * buffer; -{ - if(TRUE == hasmeta(drive)) { - wrsector(drive,track,sector,buffer,0); - return SUCCESS; - } else { - return FAILURE; - } -} - -/********************/ -/* eof - metadata.c */ -/********************/ - - - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CNAMEPT1.C b/branches/s100/Apps/crossdev/CNAMEPT1.C deleted file mode 100644 index 582b5254..00000000 --- a/branches/s100/Apps/crossdev/CNAMEPT1.C +++ /dev/null @@ -1,108 +0,0 @@ -/* cnamept1.c 5/24/2012 dwg - added bootlu */ - -#include "stdio.h" -#include "stdlib.h" - -#include "portab.h" -#include "std.h" - -#include "cnfgdata.h" -#include "syscfg.h" - -extern pager(); - -char cache[17]; - -cnamept1(syscfg) - struct SYSCFG * syscfg; -{ - strcpy(cache,"syscfg->cnfgdata"); - - printf("syscfg->jmp jp 0%04xh",syscfg->jmp.address); - pager(); - - printf("syscfg->cnfloc .dw 0%04xh",syscfg->cnfloc); - pager(); - - printf("syscfg->tstloc .dw 0%04xh",syscfg->tstloc); - pager(); - - printf("syscfg->varloc .dw 0%04xh",syscfg->varloc); - pager(); - - printf("%s.rmj = %d",cache,syscfg->cnfgdata.rmj); - pager(); - - printf("%s.rmn = %d",cache,syscfg->cnfgdata.rmn); - pager(); - - printf("%s.rup = %d",cache,syscfg->cnfgdata.rup); - pager(); - - printf("%s.rtp = %d",cache,syscfg->cnfgdata.rtp); - pager(); - - printf("%s.diskboot = ",cache); - switch(syscfg->cnfgdata.diskboot) { - case TRUE: printf("TRUE"); break; - case FALSE: printf("FALSE"); break; - } - pager(); - - printf("%s.devunit = 0x%02x",cache, - syscfg->cnfgdata.devunit); - pager(); - - printf("%s.bootlu = 0x%04x",cache, - syscfg->cnfgdata.bootlu); - pager(); - - printf("%s.freq = %dMHz",cache,syscfg->cnfgdata.freq); - pager(); - - printf("%s.platform = ",cache); - switch(syscfg->cnfgdata.platform) { - case PLT_N8VEM: printf("N8VEM"); break; - case PLT_ZETA: printf("ZETA"); break; - case PLT_N8: printf("N8"); break; - } - pager(); - - printf("%s.dioplat = ",cache); - switch(syscfg->cnfgdata.dioplat) { - case DPNONE: printf("DIOPLT_NONE"); break; - case DPDIO: printf("DIOPLT_DISKIO"); break; - case DPZETA: printf("DIOPLT_ZETA"); break; - case DPDIDE: printf("DIOPLT_DIDE"); break; - case DPN8: printf("DIOPLT_N8"); break; - case DPDIO3: printf("DIOPLT_DISKIO3"); break; - default: printf("Unknown"); break; - } - pager(); - - printf("%s.vdumode = ",cache); - switch(syscfg->cnfgdata.vdumode) { - case VPNONE: printf("VDUPLT_NONE"); break; - case VPVDU: printf("VDUPLT_VDU"); break; - case VPVDUC: printf("VDUPLT_VDUC"); break; - case VPPROPIO: printf("VDUPLT_PROPIO"); break; - case VPN8: printf("VDUPLT_VPN8"); break; - default: printf("Unknown!!"); break; - } - pager(); - - printf("%s.romsize = %d",cache, - syscfg->cnfgdata.romsize); - pager(); - - printf("%s.ramsize = %d",cache, - syscfg->cnfgdata.ramsize); - pager(); - -} - - -/********************/ -/* eof - cnamecp1.c */ -/********************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CNAMEPT2.C b/branches/s100/Apps/crossdev/CNAMEPT2.C deleted file mode 100644 index fb76a21d..00000000 --- a/branches/s100/Apps/crossdev/CNAMEPT2.C +++ /dev/null @@ -1,113 +0,0 @@ -/* cnamept2.c 5/24/2012 dwg - */ - -#include "stdio.h" -#include "stdlib.h" - -#include "portab.h" -#include "std.h" - -#include "cnfgdata.h" -#include "syscfg.h" - -extern pager(); - -char cache[17]; - -cnamept2(syscfg) - struct SYSCFG * syscfg; -{ - strcpy(cache,"syscfg->cnfgdata"); - - printf("%s.clrramdk = ",cache); - switch(syscfg->cnfgdata.clrramdk) { - case CLRNEV: printf("CLR_NEVER"); break; - case CLRAUTO: printf("CLR_AUTO"); break; - case CLRALLW: printf("CLR_ALLWAYS"); break; - } - pager(); - - printf("%s.dskyenable = ",cache); - switch(syscfg->cnfgdata.dskyenable) { - case TRUE: printf("TRUE"); break; - case FALSE: printf("FALSE"); break; - } - pager(); - - printf("%s.uartenable = ",cache); - switch(syscfg->cnfgdata.uartenable) { - case TRUE: printf("TRUE"); break; - case FALSE: printf("FALSE"); break; - } - pager(); - - printf("%s.vduenable = ",cache); - switch(syscfg->cnfgdata.vduenable) { - case TRUE: printf("TRUE"); break; - case FALSE: printf("FALSE"); break; - } - pager(); - - printf("%s.fdenable = ",cache); - switch(syscfg->cnfgdata.fdenable) { - case TRUE: printf("TRUE"); break; - case FALSE: printf("FALSE"); break; - } - pager(); - - if(TRUE == syscfg->cnfgdata.fdenable) { - - printf("%s.fdtrace = ",cache); - switch(syscfg->cnfgdata.fdtrace) { - case 0: printf("Silent"); break; - case 1: printf("Fatal Errors"); break; - case 2: printf("All Errors"); break; - case 3: printf("Everything"); break; - default: printf("Unknown!!"); break; - } - pager(); - - printf("%s.fdmedia = ",cache); - switch(syscfg->cnfgdata.fdmedia) { - case FDM720: printf("FDM720"); - printf(" 3.5 720KB 2-sided 80 Trks 9 Sectors"); - break; - case FDM144: printf("FDM144"); - printf(" 3.5 1.44MB 2-sided 80 Trks 18 Sectors"); - break; - case FDM360: printf("FDM360"); - printf(" 5.25 360KB 2-sided 40 Trks 9 Sectors"); - break; - case FDM120: printf("FDM120"); - printf(" 3.5 1.2MB 2-sided 80 Trks 15 Sectors"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.fdmediaalt = ",cache); - switch(syscfg->cnfgdata.fdmediaalt) { - case FDM720: printf("FDM720"); - printf(" 3.5 720KB 2-sided 80 Trks 9 Sectors"); - break; - case FDM144: printf("FDM144"); - printf(" 3.5 1.44MB 2-sided 80 Trks 18 Sectors"); - break; - case FDM360: printf("FDM360"); - printf(" 5.25 360KB 2-sided 40 Trks 9 Sectors"); - break; - case FDM120: printf("FDM120"); - printf(" 3.5 1.2MB 2-sided 80 Trks 15 Sectors"); - break; - } - pager(); - - } -} - - -/********************/ -/* eof - cnamept2.c */ -/********************/ - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CNAMEPT3.C b/branches/s100/Apps/crossdev/CNAMEPT3.C deleted file mode 100644 index 26284b2c..00000000 --- a/branches/s100/Apps/crossdev/CNAMEPT3.C +++ /dev/null @@ -1,216 +0,0 @@ -/* cnamept2.c 5/24/2012 dwg - */ - -#include "stdio.h" -#include "stdlib.h" - -#include "portab.h" -#include "std.h" - -#include "cnfgdata.h" -#include "syscfg.h" - -extern pager(); - -char cache[17]; - -cnamept3(syscfg) - struct SYSCFG * syscfg; -{ - strcpy(cache,"syscfg->cnfgdata"); - - printf("%s.fdmauto = ",cache); - switch(syscfg->cnfgdata.fdmauto) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - } - pager(); - - printf("%s.ideenable = ",cache); - switch(syscfg->cnfgdata.ideenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - } - pager(); - - if(TRUE == syscfg->cnfgdata.ideenable) { - - printf("%s.idetrace = ",cache); - switch(syscfg->cnfgdata.idetrace) { - case 0: printf("SILENT"); - break; - case 1: printf("ERRORS"); - break; - case 2: printf("EVERYTHING"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.de8bit = ",cache); - switch(syscfg->cnfgdata.ide8bit) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.idecapacity = %dMB",cache, - syscfg->cnfgdata.idecapacity); - pager(); - - } - - printf("%s.ppideenable = ",cache); - switch(syscfg->cnfgdata.ppideenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - } - pager(); - - if(TRUE == syscfg->cnfgdata.ppideenable) { - - printf("%s.ppidetrace = ",cache); - switch(syscfg->cnfgdata.ppidetrace) { - case 0: printf("SILENT"); - break; - case 1: printf("ERRORS"); - break; - case 2: printf("EVERYTHING"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - - printf("%s.ppide8bit = ",cache); - switch(syscfg->cnfgdata.ppide8bit) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.ppidecapacity = %dKB",cache, - syscfg->cnfgdata.ppidecapacity); - pager(); - - printf("%s.ppideslow = ",cache); - switch(syscfg->cnfgdata.ppideslow) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - } - - printf("%s.boottype = ",cache); - switch(syscfg->cnfgdata.boottype) { - case BTMENU: printf("BT_MENU"); - break; - case BTAUTO: printf("BT_AUTO"); - break; - } - pager(); - - printf("%s.boottimeout = %d seconds",cache, - syscfg->cnfgdata.boottimeout); - pager(); - - printf("%s.bootdefault = %c:",cache, - syscfg->cnfgdata.bootdefault); - pager(); - - printf("%s.baudrate = %u (0x%04x) Baud",cache, - syscfg->cnfgdata.baudrate,syscfg->cnfgdata.baudrate); - pager(); - - if(PLT_N8 == syscfg->cnfgdata.platform) { - - printf("%s.ckdiv = %d",cache, - syscfg->cnfgdata.ckdiv); - pager(); - - printf("%s.memwait = 0x%02x",cache, - syscfg->cnfgdata.memwait); - pager(); - - printf("%s.iowait = 0x%02x",cache,syscfg->cnfgdata.iowait); - pager(); - - printf("%s.cntlb0 = 0x%02x",cache,syscfg->cnfgdata.cntlb0); - pager(); - - printf("%s.cntlb1 = 0x%02x",cache,syscfg->cnfgdata.cntlb1); - pager(); - - - printf("%s.sdenable = ",cache); - switch(syscfg->cnfgdata.sdenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.sdtrace = ",cache); - switch(syscfg->cnfgdata.sdtrace) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - } -} - - -/********************/ -/* eof - cnamept3.c */ -/********************/ - -/* - unsigned char ckdiv; - unsigned char memwait; - - unsigned char iowait; - unsigned char cntlb0; - unsigned char cntlb1; - unsigned char sdenable; - unsigned char sdtrace; - unsigned int sdcapacity; - unsigned char sdcsio; - unsigned char sdcsiofast; - unsigned char defiobyte; - unsigned char termtype; - unsigned int revision; - unsigned char prpsdenable; - unsigned char prpsdtrace; - unsigned int prpsdcapacity; - unsigned char prpconenable; - unsigned int biossize; -*/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CNAMEPT4.C b/branches/s100/Apps/crossdev/CNAMEPT4.C deleted file mode 100644 index 9e0b9e92..00000000 --- a/branches/s100/Apps/crossdev/CNAMEPT4.C +++ /dev/null @@ -1,198 +0,0 @@ -/* cnamept2.c 5/24/2012 dwg - */ - -#include "stdio.h" -#include "stdlib.h" - -#include "portab.h" -#include "std.h" - -#include "cnfgdata.h" -#include "syscfg.h" - -extern pager(); - -char cache[17]; - -cnamept4(syscfg) - struct SYSCFG * syscfg; -{ - strcpy(cache,"syscfg->cnfgdata"); - - if(PLT_N8 == syscfg->cnfgdata.platform) { - - printf("%s.sdcapacity = %uKB",cache, - syscfg->cnfgdata.sdcapacity); - pager(); - - - printf("%s.sdcsio = ",cache); - switch(syscfg->cnfgdata.sdcsio) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: - printf("Unknown!!"); - break; - } - pager(); - - printf("%s.sdcsiofast = ",cache); - switch(syscfg->cnfgdata.sdcsiofast) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - } - - printf("%s.defiobyte = 0x%02x",cache, - syscfg->cnfgdata.defiobyte); - pager(); - - printf("%s.termtype = ",cache); - switch(syscfg->cnfgdata.termtype) { - case TERM_TTY: printf("TERM_TTY"); - break; - case TERM_ANSI: printf("TERM_ANSI"); - break; - case TERM_WYSE: printf("TERM_WYSE"); - break; - case TERM_VT52: printf("TERM_VT52"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.revision = %d",cache, - syscfg->cnfgdata.revision); - pager(); - - printf("%s.prpenable = ",cache); - switch(syscfg->cnfgdata.prpenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - if(TRUE == syscfg->cnfgdata.prpenable) { - - printf("%s.prpsdenable = "); - switch(syscfg->cnfgdata.prpsdenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - if(TRUE == syscfg->cnfgdata.prpsdenable) { - - printf("%s.prpsdtrace = ",cache); - switch(syscfg->cnfgdata.prpsdtrace) { - case 0: printf("SILENT"); - break; - case 1: printf("ERRORS"); - break; - case 2: printf("EVERYTHING"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.prpsdcapacity = ",cache); - pager(); - - printf("%s.prpconenable = ",cache); - switch(syscfg->cnfgdata.prpconenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - } - - } - - printf("%s.biossize = %d",cache, - syscfg->cnfgdata.biossize); - pager(); - - - printf("%s.pppenable = ",cache); - switch(syscfg->cnfgdata.pppenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - if(TRUE == syscfg->cnfgdata.pppenable) { - - printf("%s.pppsdenable = ",cache); - switch(syscfg->cnfgdata.pppsdenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - printf("%s.pppsdtrace = ",cache); - switch(syscfg->cnfgdata.pppsdtrace) { - case 0: printf("SILENT"); - break; - case 1: printf("ERRORS"); - break; - case 2: printf("EVERYTHING"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - - printf("%s.pppcapacity = %d",cache, - syscfg->cnfgdata.prpsdcapacity); - pager(); - - printf("%s.pppconenable = ",cache); - switch(syscfg->cnfgdata.pppconenable) { - case TRUE: printf("TRUE"); - break; - case FALSE: printf("FALSE"); - break; - default: printf("Unknown!!"); - break; - } - pager(); - - } - -} - -/********************/ -/* eof - cnamept4.c */ -/********************/ - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CNFGDATA.H b/branches/s100/Apps/crossdev/CNFGDATA.H deleted file mode 100644 index 5b365015..00000000 --- a/branches/s100/Apps/crossdev/CNFGDATA.H +++ /dev/null @@ -1,73 +0,0 @@ -/* cnfgdata.h 6/04/2012 dwg - */ - -struct CNFGDATA { - unsigned char rmj; - unsigned char rmn; - unsigned char rup; - unsigned char rtp; - unsigned char diskboot; - unsigned char devunit; - unsigned int bootlu; - unsigned char hour; - unsigned char minute; - unsigned char second; - unsigned char month; - unsigned char day; - unsigned char year; - unsigned char freq; - unsigned char platform; - unsigned char dioplat; - unsigned char vdumode; - unsigned int romsize; - unsigned int ramsize; - unsigned char clrramdk; - unsigned char dskyenable; - unsigned char uartenable; - unsigned char vduenable; - unsigned char fdenable; - unsigned char fdtrace; - unsigned char fdmedia; - unsigned char fdmediaalt; - unsigned char fdmauto; - unsigned char ideenable; - unsigned char idetrace; - unsigned char ide8bit; - unsigned int idecapacity; - unsigned char ppideenable; - unsigned char ppidetrace; - unsigned char ppide8bit; - unsigned int ppidecapacity; - unsigned char ppideslow; - unsigned char boottype; - unsigned char boottimeout; - unsigned char bootdefault; - unsigned int baudrate; - unsigned char ckdiv; - unsigned char memwait; - unsigned char iowait; - unsigned char cntlb0; - unsigned char cntlb1; - unsigned char sdenable; - unsigned char sdtrace; - unsigned int sdcapacity; - unsigned char sdcsio; - unsigned char sdcsiofast; - unsigned char defiobyte; - unsigned char termtype; - unsigned int revision; - unsigned char prpsdenable; - unsigned char prpsdtrace; - unsigned int prpsdcapacity; - unsigned char prpconenable; - unsigned int biossize; - unsigned char pppenable; - unsigned char pppsdenable; - unsigned char pppsdtrace; - unsigned int pppsdcapacity; - unsigned char pppconenable; - unsigned char prpenable; -}; - -/********************/ -/* eof - cnfgdata.h */ -/********************/ \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CNFGDATA.LIB b/branches/s100/Apps/crossdev/CNFGDATA.LIB deleted file mode 100644 index 10b24d99..00000000 --- a/branches/s100/Apps/crossdev/CNFGDATA.LIB +++ /dev/null @@ -1,210 +0,0 @@ -; cnfgdata.lib 7/19/2012 dwg - - -byte equ 1 -word equ 2 - -;; /* cnfgdata.h 6/04/2012 dwg - */ -;; -;; struct CNFGDATA { -;; unsigned char rmj; -cfgrmj equ 08009h -;; -;; unsigned char rmn; -cfgrmn equ cfgrmj + byte -;; -;; unsigned char rup; -cfgrup equ cfgrmn + byte -;; -;; unsigned char rtp; -cfgrtp equ cfgrup + byte -;; -;; unsigned char diskboot; -diskboot equ cfgrtp + byte -;; -;; unsigned char devunit; -devunit equ diskboot + byte -;; -;; unsigned int bootlu; -bootlu equ devunit + byte -;; -;; unsigned char hour; -hour equ bootlu + word -;; -;; unsigned char minute; -minute equ hour + byte -;; -;; unsigned char second; -second equ minute + byte -;; -;; unsigned char month; -month equ second + byte -;; -;; unsigned char day; -day equ month + byte -;; -;; unsigned char year; -year equ day + byte -;; -;; unsigned char freq; -freq equ year + byte -;; -;; unsigned char platform; -platform equ freq+ byte -;; -;; unsigned char dioplat; -dioplat equ platform + byte -;; -;; unsigned char vdumode; -vdumode equ dioplat + byte -;; -;; unsigned int romsize; -romsize equ vdumode + byte -;; -;; unsigned int ramsize; -ramsize equ romsize + word -;; -;; unsigned char clrramdk; -clrramdk equ ramsize + word -;; -;; unsigned char dskyenable; -dskyenable equ clrramdk + byte -;; -;; unsigned char uartenable; -uartenable equ dskyenable + byte -;; -;; unsigned char vduenable; -vduenable equ uartenable + byte -;; -;; unsigned char fdenable; -fdenable equ vduenable + byte -;; -;; unsigned char fdtrace; -fdtrace equ fdenable + byte -;; -;; unsigned char fdmedia; -fdmedia equ fdtrace + byte -;; -;; unsigned char fdmediaalt; -fdmediaalt equ fdmedia + byte -;; -;; unsigned char fdmauto; -fdmauto equ fdmediaalt + byte -;; -;; unsigned char ideenable; -ideenable equ fdmauto + byte -;; -;; unsigned char idetrace; -idetrace equ ideenable + byte -;; -;; unsigned char ide8bit; -ide8bit equ idetrace + byte -;; -;; unsigned int idecapacity; -idecapacity equ ide8bit + byte -;; -;; unsigned char ppideenable; -ppideenable equ idecapacity + word -;; -;; unsigned char ppidetrace; -ppidetrace equ ppideenable + byte -;; -;; unsigned char ppide8bit; -ppide8bit equ ppidetrace + byte -;; -;; unsigned int ppidecapacity; -ppidecapacity equ ppide8bit + byte -;; -;; unsigned char ppideslow; -ppideslow equ ppidecapacity + word -;; -;; unsigned char boottype; -boottype equ ppideslow + byte -;; -;; unsigned char boottimeout; -boottimeout equ boottype + byte -;; -;; unsigned char bootdefault; -bootdefault equ boottimeout + byte -;; -;; unsigned int baudrate; -baudrate equ bootdefault + byte -;; -;; unsigned char ckdiv; -ckdiv equ baudrate + word -;; -;; unsigned char memwait; -memwait equ ckdiv + byte -;; -;; unsigned char iowait; -iowait equ memwait + byte -;; -;; unsigned char cntlb0; -cntlb0 equ iowait + byte -;; -;; unsigned char cntlb1; -cntlb1 equ cntlb0 + byte -;; -;; unsigned char sdenable; -sdenable equ cntlb1 + byte -;; -;; unsigned char sdtrace; -sdtrace equ sdenable + byte -;; -;; unsigned int sdcapacity; -sdcapacity equ sdtrace + byte -;; -;; unsigned char sdcsio; -sdcsio equ sdcapacity + word -;; -;; unsigned char sdcsiofast; -sdcsiofast equ sdcsio + byte -;; -;; unsigned char defiobyte; -defiobyte equ sdcsiofast + byte -;; -;; unsigned char termtype; -termtype equ defiobyte + byte -;; -;; unsigned int revision; -revision equ termtype + byte -;; -;; unsigned char prpsdenable; -prpsdenable equ revision + word -;; -;; unsigned char prpsdtrace; -prpsdtrace equ prpsdenable + byte -;; -;; unsigned int prpsdcapacity; -prpsdcapacity equ prpsdtrace + byte -;; -;; unsigned char prpconenable; -prpconenable equ prpsdcapacity + word -;; -;; unsigned int biossize; -biossize equ prpconenable + byte -;; -;; unsigned char pppenable; -pppenable equ biossize + word -;; -;; unsigned char pppsdenable; -pppsdenable equ pppenable + byte -;; -;; unsigned char pppsdtrace; -pppsdtrace equ pppsdenable + byte -;; -;; unsigned int pppsdcapacity; -pppsdcapacity equ pppsdtrace + byte -;; -;; unsigned char pppconenable; -pppconenable equ pppsdcapacity + word -;; -;; unsigned char prpenable; -prpenable equ pppconenable + byte -;; -;; }; -;; -;; /********************/ -;; /* eof - cnfgdata.h */ -;; /********************/ - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CONVERT.C b/branches/s100/Apps/crossdev/CONVERT.C deleted file mode 100644 index 57cfdf2a..00000000 --- a/branches/s100/Apps/crossdev/CONVERT.C +++ /dev/null @@ -1,80 +0,0 @@ -/* convert.c 7/11/2012 dwg - - - The purpose of this program is similar to the CP/M dump program - except that in addition to the normal hexadecimal bytes, a field - of ascii bytes to the right are displayed as well. - -*/ - -#include "stdio.h" - - -char visible[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 10 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 20 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 30 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 40 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 50 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 60 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, /* 70 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 80 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* A0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* B0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* C0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* D0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* E0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* F0 */ -}; - -#include "cvt2h.h" - -unsigned char sector[32767]; - -main(argc,argv) - int argc; - char *argv[]; -{ - int i,j; - int offset; - int result; - unsigned char byte; - char name[32]; - - - FILE * fd; - - for(i=0;i0;i--) { - if(sector[i] != 0) break; - } - - sprintf(name,"sect%04x.h",0); - cvt2h(sector,i,name); - fclose(fd); - - exit(0); -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/COREAPPS.BAK b/branches/s100/Apps/crossdev/COREAPPS.BAK deleted file mode 100644 index 18062749..00000000 --- a/branches/s100/Apps/crossdev/COREAPPS.BAK +++ /dev/null @@ -1,49 +0,0 @@ -@rem coreapps.bat 2/15/2013 dwg - build all core apps using batch files - -@@if not exist access.cpm call access.bat -@@if not exist access.cpm echo WARNING ACCESS DIDN'T BUILD -@@if not exist access.cpm pause - -@@if not exist cpmname.cpm call cpmname.bat -@@if not exist cpmname.cpm echo WARNING CPMNAME DIDN'T BUILD -@@if not exist cpmname.cpm pause - -@if not exist findfile.cpm call findfile.bat -@if not exist findfile.cpm echo WARNING FINDFILE DIDN'T BUILD -@if not exist findfile.cpm pause - -@if not exist map.cpm call map.bat -@if not exist map.cpm echo WARNING MAP DIDN'T BUILD -@if not exist map.cpm pause - -@if not exist meta.cpm call meta.bat -@if not exist meta.cpm echo WARNING META DIDN'T BUILD -@if not exist meta.cpm pause - -@if not exist multifmt.cpm call multifmt.bat -@if not exist multifmt.cpm echo WARNING MULTIFMT DIDN'T BUILD -@if not exist multifmt.cpm pause - -@if not exist rem.cpm call makerem.bat -@if not exist rem.cpm echo WARNING REM DIDN'T BUILD -@if not exist rem.cpm pause - -@if not exist setlabel.cpm call setlabel.bat -@if not exist setlabel.cpm echo WARNING SETLABEL DIDN'T BUILD -@if not exist setlabel.cpm pause - -@if not exist sysgen.cpm call sysgen.bat -@if not exist sysgen.cpm echo WARNING SYSGEN DIDN'T BUILD -@if not exist sysgen.cpm pause - -@if not exist termtype.cpm call termtype.bat -@if not exist termtype.cpm echo WARNING TERMTYPE DIDN'T BUILD -@if not exist termtype.cpm pause - -@if not exist view.cpm call view.bat -@if not exist view.cpm echo WARNING VIEW DIDN'T BUILD -@if not exist view.cpm pause - -@echo All Core Apps Built -@dir *.cpm /w - diff --git a/branches/s100/Apps/crossdev/COREAPPS.BAT b/branches/s100/Apps/crossdev/COREAPPS.BAT deleted file mode 100644 index e7c06b5f..00000000 --- a/branches/s100/Apps/crossdev/COREAPPS.BAT +++ /dev/null @@ -1,49 +0,0 @@ -@rem coreapps.bat 2/15/2013 dwg - build all core apps using batch files - -@@if not exist access.cpm call access.bat -@@if not exist access.cpm echo WARNING ACCESS DIDN'T BUILD -@@if not exist access.cpm pause - -@@if not exist cpmname.cpm call cpmname.bat -@@if not exist cpmname.cpm echo WARNING CPMNAME DIDN'T BUILD -@@if not exist cpmname.cpm pause - -@if not exist findfile.cpm call findfile.bat -@if not exist findfile.cpm echo WARNING FINDFILE DIDN'T BUILD -@if not exist findfile.cpm pause - -@if not exist map.cpm call map.bat -@if not exist map.cpm echo WARNING MAP DIDN'T BUILD -@if not exist map.cpm pause - -@if not exist meta.cpm call meta.bat -@if not exist meta.cpm echo WARNING META DIDN'T BUILD -@if not exist meta.cpm pause - -@if not exist multifmt.cpm call multifmt.bat -@if not exist multifmt.cpm echo WARNING MULTIFMT DIDN'T BUILD -@if not exist multifmt.cpm pause - -@if not exist rem.cpm call makerem.bat -@if not exist rem.cpm echo WARNING REM DIDN'T BUILD -@if not exist rem.cpm pause - -@if not exist setlabel.cpm call setlabel.bat -@if not exist setlabel.cpm echo WARNING SETLABEL DIDN'T BUILD -@if not exist setlabel.cpm pause - -@if not exist sysgen.cpm call sysgen.bat -@if not exist sysgen.cpm echo WARNING SYSGEN DIDN'T BUILD -@if not exist sysgen.cpm pause - -@if not exist termtype.cpm call termtype.bat -@if not exist termtype.cpm echo WARNING TERMTYPE DIDN'T BUILD -@if not exist termtype.cpm pause - -@if not exist view.cpm call view.bat -@if not exist view.cpm echo WARNING VIEW DIDN'T BUILD -@if not exist view.cpm pause - -@echo All Core Apps Built -@dir *.cpm - diff --git a/branches/s100/Apps/crossdev/COREAPPS.SUB b/branches/s100/Apps/crossdev/COREAPPS.SUB deleted file mode 100644 index e6681ac7..00000000 --- a/branches/s100/Apps/crossdev/COREAPPS.SUB +++ /dev/null @@ -1,71 +0,0 @@ -e:rmac access -e:rmac banner -e:rmac findfile -e:rmac hbios -e:rmac identity -e:rmac labelib -e:rmac memory -e:rmac metadata -e:rmac printers -e:rmac rem -e:rmac setlabel -e:rmac terminal -as asmiface -as bdoscall -as bioscall -cc cbanner -as cbanner -cc clogical -as clogical -cc cmemory -as cmemory -cc cnamept1 -as cnamept1 -cc cnamept2 -as cnamept2 -cc cnamept3 -as cnamept3 -cc cnamept4 -as cnamept4 -cc cpmname -as cpmname -cc ctermcap -as ctermcap -as diagnose -cc map -as map -cc meta -as meta -cc multifmt -as multifmt -cc sectorio -as sectorio -cc sysgen -as sysgen -cc termtype -as termtype -cc view -as view -e:link access,memory,banner,printers -ln cpmname.o ctermcap.o cnamept1.o cnamept2.o cnamept3.o cnamept4.o cmemory.o diagnose.o bioscall.o bdoscall.o c.lib -e:link findfile,hbios,identity,banner,memory,printers,terminal -ln map.o asmiface.o bioscall.o bdoscall.o clogical.o diagnose.o ctermcap.o c.lib -ln meta.o asmiface.o bioscall.o bdoscall.o cbanner.o clogical.o diagnose.o ctermcap.o sectorio.o c.lib -ln multifmt.o asmiface.o bioscall.o bdoscall.o clogical.o cmemory.o sectorio.o diagnose.o ctermcap.o c.lib -e:link rem -e:link setlabel,labelib,identity,printers,banner,metadata,memory -ln sysgen.o sectorio.o ctermcap.o diagnose.o bdoscall.o bioscall.o c.lib -ln termtype.o asmiface.o ctermcap.o diagnose.o c.lib -ln view.o ctermcap.o diagnose.o bdoscall.o bioscall.o c.lib -e:access access.com -e:access cpmname.com -e:access findfile.com -e:access map.com -e:access meta.com -e:access multifmt.com -e:access rem.com -e:access setlabel.com -e:access sysgen.com -e:access termtype.com -e:access view.com - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPM80.H b/branches/s100/Apps/crossdev/CPM80.H deleted file mode 100644 index 20d45f51..00000000 --- a/branches/s100/Apps/crossdev/CPM80.H +++ /dev/null @@ -1,195 +0,0 @@ -/* cpmbios.h 3/11/2012 dwg - added CURDRV */ - -/*************************/ -/* BIOS Memory Locations */ -/*************************/ - -#define CURDRV 0x00004 -#define BIOSAD 0x0e600 - -#define pBOOT 0x0E600 -#define pWBOOT 0x0E603 -#define pCONST 0x0E606 -#define pCONIN 0x0E609 -#define pCONOUT 0x0E60C -#define pLIST 0x0E60F -#define pPUNCH 0x0E612 -#define pREADER 0x0E615 -#define pHOME 0x0E618 -#define pSELDSK 0x0E61B -#define pSETTRK 0x0E61E -#define pSETSEC 0x0E621 -#define pSETDMA 0x0E624 -#define pREAD 0x0E627 -#define pWRITE 0x0E62A -#define pLISTST 0x0E62D -#define pSECTRN 0x0E630 -#define pBNKSEL 0x0E633 -#define pGETLU 0x0E636 -#define pSETLU 0x0E639 -#define pGETINFO 0x0E63C - -struct JMP { - unsigned char opcode; - unsigned int address; -}; - -struct BIOS { - struct JMP boot; - struct JMP wboot; - struct JMP const; - struct JMP conin; - struct JMP conout; - struct JMP list; - struct JMP punch; - struct JMP reader; - struct JMP home; - struct JMP seldsk; - struct JMP settrk; - struct JMP setsec; - struct JMP setdma; - struct JMP read; - struct JMP write; - struct JMP listst; - struct JMP sectrn; - struct JMP bnksel; - struct JMP getlu; - struct JMP setlu; - struct JMP getinfo; - struct JMP rsvd1; - struct JMP rsvd2; - struct JMP rsvd3; - struct JMP rsvd4; - - char diskboot; - char bootdrive; - - char rmj; - char rmn; - char rup; - char rtp; -}; - - -struct DPH { - unsigned int xlt; - unsigned int rv1; - unsigned int rv2; - unsigned int rv3; - unsigned int dbf; - unsigned int dpb; - unsigned int csv; - unsigned int alv; - unsigned char sigl; - unsigned char sigu; - unsigned int current; - unsigned int number; -}; - -struct DPB { - unsigned int spt; - unsigned char bsh; - unsigned char blm; - unsigned char exm; - unsigned int dsm; - unsigned int drm; - unsigned char al0; - unsigned char al1; - unsigned int cks; - unsigned int off; -}; - -/* bioscall.h 3/10/2012 dwg - header file for bdoscall */ - - extern char irega; - extern unsigned int iregbc; - extern unsigned int iregde; - extern unsigned int ireghl; - extern bioscall(); - - -/* bdoscall.h 3/10/2012 dwg - header file for bdoscall */ - - extern char drega; - extern unsigned int dregbc; - extern unsigned int dregde; - extern unsigned int dreghl; - extern bdoscall(); - -/* diagnose.h 5/23/2012 dwg - */ - - extern char hrega; - extern unsigned int hregbc; - extern unsigned int hregde; - extern unsigned int hreghl; - -extern diagnose(); - -/* ctermcap.h 3/11/2012 dwg - declarations for termal capability */ - -extern crtinit(); -extern crtclr(); -extern crtlc(); - -/* cpmbdos.h */ -#define TERMCPM 0 -#define CONIN 1 -#define CWRITE 2 -#define DIRCONIO 6 -#define PRINTSTR 9 -#define RDCONBUF 10 -#define GETCONST 11 -#define RETVERNUM 12 -#define RESDISKSYS 13 -#define SELECTDISK 14 -#define FOPEN 15 -#define FCLOSE 16 -#define SEARCHFIRST 17 -#define SEARCHNEXT 18 -#define FDELETE 19 -#define FREADSEQ 20 -#define FWRITESEQ 21 -#define FMAKEFILE 22 -#define FRENAME 23 -#define RETLOGINVEC 24 -#define RETCURRDISK 25 -#define SETDMAADDR 26 -#define GETALLOCVEC 27 -#define WRPROTDISK 28 -#define GETROVECTOR 29 -#define FSETATTRIB 30 -#define GETDPBADDR 31 -#define SETGETUSER 32 -#define FREADRANDOM 33 -#define FWRITERAND 34 -#define FCOMPSIZE 35 -#define SETRANDREC 36 -#define RESETDRIVE 37 -#define WRRANDFILL 38 - -#define DRIVEA 0 - -/* dphmap.h 5/29/2012 dwg - declaration of DPH MAP structure */ - -struct DPHMAP { - struct DPH * drivea; - struct DPH * driveb; - struct DPH * drivec; - struct DPH * drived; - struct DPH * drivee; - struct DPH * drivef; - struct DPH * driveg; - struct DPH * driveh; -} * pDPHMAP; - -struct DPHMAP * pDPHVEC[MAXDRIVE]; - - -/******************/ -/* eof - dphmap.h */ -/******************/ - -/*****************/ -/* eof - cpm80.h */ -/*****************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPM86/AME86.EXE b/branches/s100/Apps/crossdev/CPM86/AME86.EXE deleted file mode 100644 index 663b7bd5..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/AME86.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/AME86DOS.EXE b/branches/s100/Apps/crossdev/CPM86/AME86DOS.EXE deleted file mode 100644 index 99b32591..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/AME86DOS.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/ARCV.COM b/branches/s100/Apps/crossdev/CPM86/ARCV.COM deleted file mode 100644 index 2dccca48..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/ARCV.COM and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/AS.EXE b/branches/s100/Apps/crossdev/CPM86/AS.EXE deleted file mode 100644 index 40e27101..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/AS.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/ASSERT.H b/branches/s100/Apps/crossdev/CPM86/ASSERT.H deleted file mode 100644 index a03a1015..00000000 --- a/branches/s100/Apps/crossdev/CPM86/ASSERT.H +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef NDEBUG -#ifndef stderr -#include -#endif -#define assert(x) if (!(x)) {fprintf(stderr,"Assertion failed: x, file %s, line %d\n",__FILE__,__LINE__); exit(1);} -#else -#define assert(x) -#endif diff --git a/branches/s100/Apps/crossdev/CPM86/C.LIB b/branches/s100/Apps/crossdev/CPM86/C.LIB deleted file mode 100644 index 5337a8b3..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/C.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/CC.EXE b/branches/s100/Apps/crossdev/CPM86/CC.EXE deleted file mode 100644 index b78e091b..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/CC.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/CCB.EXE b/branches/s100/Apps/crossdev/CPM86/CCB.EXE deleted file mode 100644 index 8f0b5a25..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/CCB.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/CNM.EXE b/branches/s100/Apps/crossdev/CPM86/CNM.EXE deleted file mode 100644 index 2bf71d82..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/CNM.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/CPM.EXE b/branches/s100/Apps/crossdev/CPM86/CPM.EXE deleted file mode 100644 index df873a9f..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/CPM.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/CRC.EXE b/branches/s100/Apps/crossdev/CPM86/CRC.EXE deleted file mode 100644 index f010c3e2..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/CRC.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/CTYPE.H b/branches/s100/Apps/crossdev/CPM86/CTYPE.H deleted file mode 100644 index 390ffb31..00000000 --- a/branches/s100/Apps/crossdev/CPM86/CTYPE.H +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright (C) 1984 by Manx Software Systems */ - -extern char ctp_[]; - -#define isalpha(x) (ctp_[(x)+1]&0x03) -#define isupper(x) (ctp_[(x)+1]&0x01) -#define islower(x) (ctp_[(x)+1]&0x02) -#define isdigit(x) (ctp_[(x)+1]&0x04) -#define isxdigit(x) (ctp_[(x)+1]&0x08) -#define isalnum(x) (ctp_[(x)+1]&0x07) -#define isspace(x) (ctp_[(x)+1]&0x10) -#define ispunct(x) (ctp_[(x)+1]&0x40) -#define iscntrl(x) (ctp_[(x)+1]&0x20) -#define isprint(x) (ctp_[(x)+1]&0xc7) -#define isgraph(x) (ctp_[(x)+1]&0x47) -#define isascii(x) (((x)&0x80)==0) - -#define toascii(x) ((x)&127) -#define _tolower(x) ((x)|0x20) -#define _toupper(x) ((x)&0x5f) diff --git a/branches/s100/Apps/crossdev/CPM86/D11.LIB b/branches/s100/Apps/crossdev/CPM86/D11.LIB deleted file mode 100644 index a4e2fac7..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/D11.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/D20.LIB b/branches/s100/Apps/crossdev/CPM86/D20.LIB deleted file mode 100644 index bc64a01d..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/D20.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/DIFF.EXE b/branches/s100/Apps/crossdev/CPM86/DIFF.EXE deleted file mode 100644 index f25fb626..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/DIFF.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/DIOCTL.H b/branches/s100/Apps/crossdev/CPM86/DIOCTL.H deleted file mode 100644 index 092740d1..00000000 --- a/branches/s100/Apps/crossdev/CPM86/DIOCTL.H +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (C) 1983 by Manx Software Systems */ - -#define TIOCGETP 0 /* read contents of tty control structure */ -#define TIOCSETP 1 /* set contents of tty control structure */ -#define TIOCSETN 1 /* ditto only don't wait for output to flush */ - -/* special codes for MSDOS 2.x only */ -#define TIOCREAD 2 /* read control info from device */ -#define TIOCWRITE 3 /* write control info to device */ -#define TIOCDREAD 4 /* same as 2 but for drives */ -#define TIOCDWRITE 5 /* same as 3 but for drives */ -#define GETISTATUS 6 /* get input status */ -#define GETOSTATUS 7 /* get output status */ - -struct sgttyb { - short sg_flags; /* control flags */ - char sg_erase; /* ignored */ - char sg_kill; /* ignored */ -}; - -/* settings for flags */ -#define RAW 0x20 /* no echo or mapping of input/output BDOS(6) */ - -/* Refer to the MSDOS technical reference for detailed information on - * the remaining flags. - */ diff --git a/branches/s100/Apps/crossdev/CPM86/ERRNO.H b/branches/s100/Apps/crossdev/CPM86/ERRNO.H deleted file mode 100644 index 2ab0591c..00000000 --- a/branches/s100/Apps/crossdev/CPM86/ERRNO.H +++ /dev/null @@ -1,29 +0,0 @@ -extern int errno; -extern char *sys_errlist[]; -extern int sys_nerr; - -/* MsDos return codes */ -#define EINVAL 1 -#define ENOENT 2 -#define ENOTDIR 3 -#define EMFILE 4 -#define EACCES 5 -#define EBADF 6 -#define EARENA 7 -#define ENOMEM 8 -#define EFAULT 9 -#define EINVENV 10 -#define EBADFMT 11 -#define EINVACC 12 -#define EINVDAT 13 -#define ENODEV 15 -#define ERMCD 16 -#define EXDEV 17 -#define ENOMORE 18 - -/* additional codes used by Aztec C */ -#define EEXIST 19 -#define ENOTTY 20 -/* used by the math library */ -#define ERANGE 21 -#define EDOM 22 diff --git a/branches/s100/Apps/crossdev/CPM86/FCNTL.H b/branches/s100/Apps/crossdev/CPM86/FCNTL.H deleted file mode 100644 index e9d60acb..00000000 --- a/branches/s100/Apps/crossdev/CPM86/FCNTL.H +++ /dev/null @@ -1,7 +0,0 @@ -#define O_RDONLY 0 -#define O_WRONLY 1 -#define O_RDWR 2 -#define O_CREAT 0x0100 -#define O_TRUNC 0x0200 -#define O_EXCL 0x0400 -#define O_APPEND 0x0800 diff --git a/branches/s100/Apps/crossdev/CPM86/G.LIB b/branches/s100/Apps/crossdev/CPM86/G.LIB deleted file mode 100644 index 6c5fe3e0..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/G.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/GRAPH.C b/branches/s100/Apps/crossdev/CPM86/GRAPH.C deleted file mode 100644 index 3f80a80e..00000000 --- a/branches/s100/Apps/crossdev/CPM86/GRAPH.C +++ /dev/null @@ -1,16 +0,0 @@ -main() -{ - char buffer[100]; - - /* set to 25 row x 80 column monochrome mode 6 (HIRES) */ - mode('H'); - printf("Please enter your name: "); - gets(buffer); - /* set to 25 row x 40 column 4-color mode 4 (MEDRES) */ - mode('M'); - printf("Hello %s!\nWelcome to the growing family of\nAZTEC C users...\n", - buffer); - getchar(); - /* set to 25 row x 80 column color text mode 3 (LOWRES) */ - mode('L'); -} diff --git a/branches/s100/Apps/crossdev/CPM86/GRAPH.EXE b/branches/s100/Apps/crossdev/CPM86/GRAPH.EXE deleted file mode 100644 index eee18462..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/GRAPH.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/GRAPH.O b/branches/s100/Apps/crossdev/CPM86/GRAPH.O deleted file mode 100644 index a247de10..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/GRAPH.O and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/HELLO.C b/branches/s100/Apps/crossdev/CPM86/HELLO.C deleted file mode 100644 index daab2005..00000000 --- a/branches/s100/Apps/crossdev/CPM86/HELLO.C +++ /dev/null @@ -1,4 +0,0 @@ -main() -{ - printf("Hello Woprd!!"); -} diff --git a/branches/s100/Apps/crossdev/CPM86/HELLO.CMD b/branches/s100/Apps/crossdev/CPM86/HELLO.CMD deleted file mode 100644 index 4444d964..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/HELLO.CMD and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/HELLO.EXE b/branches/s100/Apps/crossdev/CPM86/HELLO.EXE deleted file mode 100644 index 58027d8f..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/HELLO.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/HELLO.O b/branches/s100/Apps/crossdev/CPM86/HELLO.O deleted file mode 100644 index 7529c4ec..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/HELLO.O and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/HEX86.EXE b/branches/s100/Apps/crossdev/CPM86/HEX86.EXE deleted file mode 100644 index 84b75110..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/HEX86.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/IO.H b/branches/s100/Apps/crossdev/CPM86/IO.H deleted file mode 100644 index d78d6a3c..00000000 --- a/branches/s100/Apps/crossdev/CPM86/IO.H +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 1982 by Manx Software Systems */ -/* - * if MAXCHAN is changed then the initialization of chantab in croot.c - * should be adjusted so that it initializes EXACTLY MAXCHAN elements of - * the array. If this is not done, the I/O library may exhibit - * strange behavior. - */ -#define MAXCHAN 11 /* maximum number of I/O channels */ - -/* - * argument to device routines. - * this is a typedef to allow future redeclaration to guarantee - * enough space to store either a pointer or an integer. - */ -typedef char *_arg; - -/* - * device control structure - */ -struct device { - char d_read; - char d_write; - char d_ioctl; /* used by character special devices (eg CON:) */ - char d_seek; /* used by random I/O devices (eg: a file) */ - int (*d_open)(); /* for special open handling */ -}; - -/* - * device table, contains names and pointers to device entries - */ -struct devtabl { - char *d_name; - struct device *d_dev; - _arg d_arg; -}; - -/* - * channel table: relates fd's to devices - */ -struct channel { - char c_read; - char c_write; - char c_ioctl; - char c_seek; - int (*c_close)(); - _arg c_arg; -} ; -extern struct channel chantab[MAXCHAN]; - -struct fcb { - char f_driv; - char f_name[8]; - char f_type[3]; - char f_ext; - char f_resv[2]; - char f_rc; - char f_sydx[16]; - char f_cr; - unsigned f_record; char f_overfl; -}; - -struct fcbtab { - struct fcb fcb; - char offset; - char flags; - char user; -}; - -#define OPNFIL 15 -#define CLSFIL 16 -#define DELFIL 19 -#define READSQ 20 -#define WRITSQ 21 -#define MAKFIL 22 -#define SETDMA 26 -#define GETUSR 32 -#define READRN 33 -#define WRITRN 34 -#define FILSIZ 35 -#define SETREC 36 - -#define Wrkbuf ((char *)0x80) diff --git a/branches/s100/Apps/crossdev/CPM86/LIBC.H b/branches/s100/Apps/crossdev/CPM86/LIBC.H deleted file mode 100644 index 1251d336..00000000 --- a/branches/s100/Apps/crossdev/CPM86/LIBC.H +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 1981, 1982 by Manx Software Systems */ - -extern int errno; -#define FLT_FAULT 0 /* vector for floating-point faults */ -extern int (*Sysvec[])(); - -#define NULL 0 -#define EOF -1 -#define BUFSIZ 1024 - -#define _BUSY 0x01 -#define _ALLBUF 0x02 -#define _DIRTY 0x04 -#define _EOF 0x08 -#define _IOERR 0x10 -#define _TEMP 0x20 /* temporary file (delete on close) */ - -typedef struct { - char *_bp; /* current position in buffer */ - char *_bend; /* last character in buffer + 1 */ - char *_buff; /* address of buffer */ - char _flags; /* open mode, etc. */ - char _unit; /* token returned by open */ - char _bytbuf; /* single byte buffer for unbuffer streams */ - int _buflen; /* length of buffer */ - char *_tmpname; /* name of file for temporaries */ -} FILE; - -extern FILE Cbuffs[]; -extern char *Stdbufs; /* free list of buffers */ -long ftell(); - -#define stdin (&Cbuffs[0]) -#define stdout (&Cbuffs[1]) -#define stderr (&Cbuffs[2]) -#define getchar() agetc(stdin) -#define putchar(c) aputc(c, stdout) -#define feof(fp) (((fp)->_flags&_EOF)!=0) -#define ferror(fp) (((fp)->_flags&_IOERR)!=0) -#define clearerr(fp) ((fp)->_flags &= ~(_IOERR|_EOF)) -#define fileno(fp) ((fp)->_unit) diff --git a/branches/s100/Apps/crossdev/CPM86/LMACROS.H b/branches/s100/Apps/crossdev/CPM86/LMACROS.H deleted file mode 100644 index c3686de2..00000000 --- a/branches/s100/Apps/crossdev/CPM86/LMACROS.H +++ /dev/null @@ -1,210 +0,0 @@ - nlist -; Copyright (C) 1985 by Manx Software Systems, Inc. -; :ts=8 - ifndef MODEL -MODEL equ 0 - endif - if MODEL and 1 - largecode -FARPROC equ 1 -FPTRSIZE equ 4 - else -FPTRSIZE equ 2 - endif - if MODEL and 2 -LONGPTR equ 1 - endif - -;this macro to be used on returning -;restores bp and registers -pret macro -if havbp - pop bp -endif - ret - endm - -internal macro pname - public pname -pname proc - endm - -intrdef macro pname - public pname -ifdef FARPROC - pname label far -else - pname label near -endif - endm - -procdef macro pname, args - public pname&_ -ifdef FARPROC - _arg = 6 - pname&_ proc far -else - _arg = 4 - pname&_ proc near -endif -ifnb - push bp - mov bp,sp - havbp = 1 - decll -else - havbp = 0 -endif - endm - -entrdef macro pname, args - public pname&_ -ifdef FARPROC - _arg = 6 - pname&_: -else - _arg = 4 - pname&_: -endif -ifnb -if havbp - push bp - mov bp,sp -else - error must declare main proc with args, if entry has args -endif - decll -endif - endm - -;this macro equates 'aname' to arg on stack -decl macro aname, type -;;'byte' or anything else -havtyp = 0 -ifidn , - aname equ byte ptr _arg[bp] - _arg = _arg + 2 - havtyp = 1 -endif -ifidn , - aname equ dword ptr _arg[bp] - _arg = _arg + 4 - havtyp = 1 -endif -ifidn , - aname equ qword ptr _arg[bp] - _arg = _arg + 8 - havtyp = 1 -endif -ifidn , - ifdef LONGPTR - aname equ dword ptr _arg[bp] - _arg = _arg + 4 - else - aname equ word ptr _arg[bp] - _arg = _arg + 2 - endif - havtyp = 1 -endif -ifidn , - ifdef FARPROC - aname equ dword ptr _arg[bp] - _arg = _arg + 4 - else - aname equ word ptr _arg[bp] - _arg = _arg + 2 - endif - havtyp = 1 -endif -ifidn , - aname equ word ptr _arg[bp] - _arg = _arg + 2 - havtyp = 1 -endif -ife havtyp - error -- type is unknown. -endif - endm - -;this macro loads an arg pointer into DEST, with optional SEGment -ldptr macro dest, argname, seg -ifdef LONGPTR - ifnb ;;get segment if specified - ifidn , - les dest,argname - else - ifidn , - lds dest,argname - else - mov dest, word ptr argname - mov seg, word ptr argname[2] - endif - endif - else - ifidn , ;;si gets seg in ds - lds si, argname - else - ifidn , ;;or, es:di - les di, argname - else - garbage error: no seg for long pointer - endif - endif - endif -else - mov dest, word ptr argname ;;get the pointer -ENDIF - ENDM - -decll macro list - IRP i, - decl i - ENDM - ENDM - -pend macro pname -pname&_ endp - endm - -retptrm macro src,seg -mov ax, word ptr src -ifdef LONGPTR - mov dx, word ptr src+2 -endif - endm - -retptrr macro src,seg -mov ax,src -ifdef LONGPTR - ifnb - mov dx, seg - endif -endif - endm - -retnull macro -ifdef LONGPTR - sub dx,dx -endif - sub ax,ax - endm - -pushds macro - ifdef LONGPTR - push ds - endif - endm - -popds macro - ifdef LONGPTR - pop ds - endif - endm - -finish macro -codeseg ends - endm - - list -codeseg segment byte public 'code' - assume cs:codeseg diff --git a/branches/s100/Apps/crossdev/CPM86/LN.EXE b/branches/s100/Apps/crossdev/CPM86/LN.EXE deleted file mode 100644 index a8a38c53..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/LN.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/M.LIB b/branches/s100/Apps/crossdev/CPM86/M.LIB deleted file mode 100644 index 776dafa6..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/M.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/M87.LIB b/branches/s100/Apps/crossdev/CPM86/M87.LIB deleted file mode 100644 index 73c30bca..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/M87.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/M87S.LIB b/branches/s100/Apps/crossdev/CPM86/M87S.LIB deleted file mode 100644 index edb56309..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/M87S.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/MAKE.EXE b/branches/s100/Apps/crossdev/CPM86/MAKE.EXE deleted file mode 100644 index de7a09a5..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/MAKE.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/MAKEFILE b/branches/s100/Apps/crossdev/CPM86/MAKEFILE deleted file mode 100644 index 18140338..00000000 --- a/branches/s100/Apps/crossdev/CPM86/MAKEFILE +++ /dev/null @@ -1,8 +0,0 @@ - - -hello.cmd: hello.c - cc hello - ln -o hello.cmd hello.o -lc - -clean: - erase hello.cmd diff --git a/branches/s100/Apps/crossdev/CPM86/MAP.BAT b/branches/s100/Apps/crossdev/CPM86/MAP.BAT deleted file mode 100644 index 9b2a2117..00000000 --- a/branches/s100/Apps/crossdev/CPM86/MAP.BAT +++ /dev/null @@ -1 +0,0 @@ -z:mount i /Users/doug/Downloads/azcpm32d diff --git a/branches/s100/Apps/crossdev/CPM86/MATH.H b/branches/s100/Apps/crossdev/CPM86/MATH.H deleted file mode 100644 index bc2ebd77..00000000 --- a/branches/s100/Apps/crossdev/CPM86/MATH.H +++ /dev/null @@ -1,11 +0,0 @@ -double sin(), cos(), tan(), cotan(); -double asin(), acos(), atan(), atan2(); -double ldexp(), frexp(), modf(); -double floor(), ceil(), fabs(); -double log(), log10(), exp(), sqrt(), pow(); -double sinh(), cosh(), tanh(); - -#define HUGE_VAL 1.79e+308 -#define LOGHUGE 709.778 -#define TINY_VAL 2.2e-308 -#define LOGTINY -708.396 diff --git a/branches/s100/Apps/crossdev/CPM86/MEMORY.H b/branches/s100/Apps/crossdev/CPM86/MEMORY.H deleted file mode 100644 index 85cc4c88..00000000 --- a/branches/s100/Apps/crossdev/CPM86/MEMORY.H +++ /dev/null @@ -1,2 +0,0 @@ -extern char *memcpy(), *memchr(), *memcpy(), memset(); -extern int memcmp(); diff --git a/branches/s100/Apps/crossdev/CPM86/OBD.EXE b/branches/s100/Apps/crossdev/CPM86/OBD.EXE deleted file mode 100644 index 95006b9d..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/OBD.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/ORD.EXE b/branches/s100/Apps/crossdev/CPM86/ORD.EXE deleted file mode 100644 index 939b095a..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/ORD.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/REGS.H b/branches/s100/Apps/crossdev/CPM86/REGS.H deleted file mode 100644 index f7395c80..00000000 --- a/branches/s100/Apps/crossdev/CPM86/REGS.H +++ /dev/null @@ -1,55 +0,0 @@ -/* regs.h for aztec.c (C) Copyright Bill Buckels 2008. All rights reserved. */ - -#ifndef REGS_DEFINED - -/* word registers */ -/* different than M$oft so don't mix the two */ -struct WORDREGS { - unsigned int ax; - unsigned int bx; - unsigned int cx; - unsigned int dx; - unsigned int si; - unsigned int di; - unsigned int ds; - unsigned int es; - }; - -/* byte registers */ -/* I made these the same as M$oft since - the first 6 word regs are the same between the two */ -struct BYTEREGS { - unsigned char al, ah; - unsigned char bl, bh; - unsigned char cl, ch; - unsigned char dl, dh; - }; - -/* general purpose registers union - - * overlays the corresponding word and byte registers. - */ - -union REGS { - struct WORDREGS x; - struct BYTEREGS h; - }; - - -/* segment registers */ -/* different than M$oft so don't mix the two */ -struct SREGS { - unsigned int cs; - unsigned int ss; - unsigned int ds; - unsigned int es; - }; - - -/* the following makes it a little easier - to port code from M$soft and Turbo C - over to Aztec C unless you want to be - an Aztec C purist */ -#define int86(x,y,z) sysint(x,y,z) - -#define REGS_DEFINED 1 -#endif \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPM86/S.LIB b/branches/s100/Apps/crossdev/CPM86/S.LIB deleted file mode 100644 index 36906898..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/S.LIB and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/SEARCH.H b/branches/s100/Apps/crossdev/CPM86/SEARCH.H deleted file mode 100644 index a32fdf35..00000000 --- a/branches/s100/Apps/crossdev/CPM86/SEARCH.H +++ /dev/null @@ -1,5 +0,0 @@ -typedef int VISIT; -#define preorder 1 -#define postorder 2 -#define endorder 3 -#define leaf 4 diff --git a/branches/s100/Apps/crossdev/CPM86/SETJMP.H b/branches/s100/Apps/crossdev/CPM86/SETJMP.H deleted file mode 100644 index 0205583d..00000000 --- a/branches/s100/Apps/crossdev/CPM86/SETJMP.H +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright (C) 1983 by Manx Software Systems */ -#define JBUFSIZE (6*sizeof(int)) - -typedef char jmp_buf[JBUFSIZE]; diff --git a/branches/s100/Apps/crossdev/CPM86/SGTTY.H b/branches/s100/Apps/crossdev/CPM86/SGTTY.H deleted file mode 100644 index a2a5cad3..00000000 --- a/branches/s100/Apps/crossdev/CPM86/SGTTY.H +++ /dev/null @@ -1,19 +0,0 @@ -/* Copyright (C) 1983 by Manx Software Systems */ - -#define TIOCGETP 0 /* read contents of tty control structure */ -#define TIOCSETP 1 /* set contents of tty control structure */ -#define TIOCSETN 1 /* ditto only don't wait for output to flush */ - -struct sgttyb { - char sg_erase; /* ignored */ - char sg_kill; /* ignored */ - short sg_flags; /* control flags */ -}; - -/* settings for flags */ -#define _VALID 0x3a -#define RAW 0x20 /* no echo or mapping of input/output BDOS(6) */ -#define CRMOD 0x10 /* map input CR to NL, output NL to CR LF */ -#define ECHO 0x08 /* ignored unless CBREAK is set */ -#define CBREAK 0x02 /* input using BDOS(1), unless echo off then */ - /* same as RAW */ diff --git a/branches/s100/Apps/crossdev/CPM86/SIGNAL.H b/branches/s100/Apps/crossdev/CPM86/SIGNAL.H deleted file mode 100644 index 2bea52f2..00000000 --- a/branches/s100/Apps/crossdev/CPM86/SIGNAL.H +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright (C) 1985 by Manx Software Systems, Inc. */ - -#define SIG_DFL ((void (*)())0) -#define SIG_IGN ((void (*)())1) -#define SIG_ERR ((void (*)())-1) - -#define SIGINT 1 -#define SIGTERM 2 -#define SIGABRT 3 -#define SIGFPE 4 -#define SIGILL 5 -#define SIGSEGV 6 - -#define _NUMSIG 6 -#define _FSTSIG 1 diff --git a/branches/s100/Apps/crossdev/CPM86/SQZ.EXE b/branches/s100/Apps/crossdev/CPM86/SQZ.EXE deleted file mode 100644 index b4a27ffe..00000000 Binary files a/branches/s100/Apps/crossdev/CPM86/SQZ.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPM86/STAT.H b/branches/s100/Apps/crossdev/CPM86/STAT.H deleted file mode 100644 index 5e10dbaf..00000000 --- a/branches/s100/Apps/crossdev/CPM86/STAT.H +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 1984 by Manx Software Systems */ - -struct stat { - char st_attr; - long st_mtime; - long st_size; -}; - -/* settings of the st_attr field */ -#define ST_RDONLY 0x01 /* read only file */ -#define ST_HIDDEN 0x02 /* hidden file */ -#define ST_SYSTEM 0x04 /* system file */ -#define ST_VLABEL 0x08 /* volume label */ -#define ST_DIRECT 0x10 /* file is a sub-directory */ -#define ST_ARCHIV 0x20 /* set when file has been written and closed */ - -/* the format of the st_mtime field is: - < year > < month> < day > < hours > < minutes > < sec/2 > - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - -where: - year is from 0-119 for 1980-2099 - month is 1-12 - day is 1-31 - hours is 0-23 - minutes is 0-59 - sec/2 is 0-29 -*/ diff --git a/branches/s100/Apps/crossdev/CPM86/STDIO.H b/branches/s100/Apps/crossdev/CPM86/STDIO.H deleted file mode 100644 index aa5bec1e..00000000 --- a/branches/s100/Apps/crossdev/CPM86/STDIO.H +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 1982, 1984 by Manx Software Systems */ -#define fgetc getc -#define fputc putc -#define NULL (void *)0 -#define EOF -1 - - -#define BUFSIZ 1024 -#define MAXSTREAM 20 - -#define _BUSY 0x01 -#define _ALLBUF 0x02 -#define _DIRTY 0x04 -#define _EOF 0x08 -#define _IOERR 0x10 -#define _TEMP 0x20 /* temporary file (delete on close) */ - -typedef struct { - char *_bp; /* current position in buffer */ - char *_bend; /* last character in buffer + 1 */ - char *_buff; /* address of buffer */ - char _flags; /* open mode, etc. */ - char _unit; /* token returned by open */ - char _bytbuf; /* single byte buffer for unbuffer streams */ - int _buflen; /* length of buffer */ - char *_tmpname; /* name of file for temporaries */ -} FILE; - -extern FILE Cbuffs[]; -FILE *fopen(); -long ftell(); - -#define stdin (&Cbuffs[0]) -#define stdout (&Cbuffs[1]) -#define stderr (&Cbuffs[2]) -#define getchar() agetc(stdin) -#define putchar(c) aputc(c, stdout) -#define feof(fp) (((fp)->_flags&_EOF)!=0) -#define ferror(fp) (((fp)->_flags&_IOERR)!=0) -#define clearerr(fp) ((fp)->_flags &= ~(_IOERR|_EOF)) -#define fileno(fp) ((fp)->_unit) -#define fflush(fp) flsh_(fp,-1) - -#define P_tmpdir "" -#define L_tmpnam 40 diff --git a/branches/s100/Apps/crossdev/CPM86/TIME.H b/branches/s100/Apps/crossdev/CPM86/TIME.H deleted file mode 100644 index 07c73a42..00000000 --- a/branches/s100/Apps/crossdev/CPM86/TIME.H +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright (C) 1984, 1985 by Manx Software Systems */ - -#define CLK_TCK 100 -typedef long time_t; -typedef long clock_t; - -struct tm { - short tm_sec; - short tm_min; - short tm_hour; - short tm_mday; - short tm_mon; - short tm_year; - short tm_wday; - short tm_yday; - short tm_isdst; - short tm_hsec; -}; - -struct tm *gmtime(), *localtime(); -char *asctime(), *ctime(); -time_t time(); diff --git a/branches/s100/Apps/crossdev/CPMAPPL.H b/branches/s100/Apps/crossdev/CPMAPPL.H deleted file mode 100644 index a68ac9f2..00000000 --- a/branches/s100/Apps/crossdev/CPMAPPL.H +++ /dev/null @@ -1,8 +0,0 @@ -/* cpmappl.h */ - -extern banner(); - -/*******************/ -/* eof - cpmappl.h */ -/*******************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMAPPL.LIB b/branches/s100/Apps/crossdev/CPMAPPL.LIB deleted file mode 100644 index fa626600..00000000 --- a/branches/s100/Apps/crossdev/CPMAPPL.LIB +++ /dev/null @@ -1,82 +0,0 @@ -; cpmappl.lib 2/10/2012 dwg - begin 1.6 development -; cpmappl.lib 2/04/2012 dwg - fix typo mov becomes mvi -; cpmappl.lib 2/ 2/2012 dwg - initial version - -; -; Copyright (C) 2011-2012 Douglas Goodall Licensed under GPL Ver 3. -; -; This file is part of NuBiosDWG and is free software: you can -; redistribute it and/or modify it under the terms of the GNU -; General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. -; This file is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; You should have received a copy of the GNU General Public License -; along with it. If not, see . -; - -do$start macro - -start: jmp begin - - public hexref -hexref db '0123456789ABCDEF' - - public id$sig,id$rmj,id$rmn,id$rup,id$rtp,id$mon,id$day,id$yr -id$sig db 'ID' -id$rmj db A$RMJ -id$rmn db A$RMN -id$rup db A$RUP -id$rtp db A$RTP -id$mon db A$MONTH -id$day db A$DAY -id$yr dw A$YEAR -id$argv dw argv - db 0e5h - - - public pre$stk -pre$stk ds 2 - - public begin -begin: lxi h,0 - dad sp - shld pre$stk - lxi sp,stack$top - nop - endm - - -;--------------------------------- - - -do$end macro - lhld pre$stk - sphl - - mvi c,13 - call BDOS - - ret - ds stack$size -stack$top: - - endm - -movfcb macro destn,source - lxi d,destn - lxi h,source - lxi b,LENFCB - ldir - endm - -copyfcb macro fcbname,source - local around - jmp around -fcbname ds 32 -around: - endm - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMBDOS.H b/branches/s100/Apps/crossdev/CPMBDOS.H deleted file mode 100644 index 5ee0c55f..00000000 --- a/branches/s100/Apps/crossdev/CPMBDOS.H +++ /dev/null @@ -1,52 +0,0 @@ - -#define TERMCPM 0 -#define CONIN 1 -#define CWRITE 2 -#define DIRCONIO 6 -#define PRINTSTR 9 -#define RDCONBUF 10 -#define GETCONST 11 -#define RETVERNUM 12 -#define RESDISKSYS 13 -#define SELECTDISK 14 -#define FOPEN 15 -#define FCLOSE 16 -#define SEARCHFIRST 17 -#define SEARCHNEXT 18 -#define FDELETE 19 -#define FREADSEQ 20 -#define FWRITESEQ 21 -#define FMAKEFILE 22 -#define FRENAME 23 -#define RETLOGINVEC 24 -#define RETCURRDISK 25 -#define SETDMAADDR 26 -#define GETALLOCVEC 27 -#define WRPROTDISK 28 -#define GETROVECTOR 29 -#define FSETATTRIB 30 -#define GETDPBADDR 31 -#define SETGETUSER 32 -#define FREADRANDOM 33 -#define FWRITERAND 34 -#define FCOMPSIZE 35 -#define SETRANDREC 36 -#define RESETDRIVE 37 -#define WRRANDFILL 38 - -#define BDOSDRA 1 -#define BDOSDRB 2 -#define BDOSDRC 3 -#define BDOSDRD 4 -#define BDOSDRE 5 -#define BDOSDRF 6 -#define BDOSDRG 7 -#define BDOSDRH 8 - -struct FCB { - char drive; - char filename[8]; - char filetype[3]; - char filler[24]; -}; - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMBDOS.LIB b/branches/s100/Apps/crossdev/CPMBDOS.LIB deleted file mode 100644 index a5c8db6f..00000000 --- a/branches/s100/Apps/crossdev/CPMBDOS.LIB +++ /dev/null @@ -1,174 +0,0 @@ -; cpmbdos.lib 1/19/2012 dwg - add READ$CON$BUF (10) -; cpmbdos.lib 1/15/2012 dwg - add more functions - -; -; Copyright (C) 2011-2012 Douglas Goodall Licensed under GPL Ver 3. -; -; This file is part of NuBiosDWG and is free software: you can -; redistribute it and/or modify it under the terms of the GNU -; General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. -; This file is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; You should have received a copy of the GNU General Public License -; along with it. If not, see . -; - -; BDOS function codes - -TERMCPM equ 0 ; return to command line -CREAD equ 1 ; read a character -CWRITE equ 2 ; write a character -PRINTSTR equ 9 ; print string -READ$CON$BUF equ 10 ; read console buffer -RETVERNO equ 12 ; return version number -DSKRESET equ 13 ; disk reset -SELDSK equ 14 ; select disk -FOPEN equ 15 ; open file -FCLOSE equ 16 ; close file -FDELETE equ 19 ; delete file -READSEQ equ 20 ; read sequential -WRITESEQ equ 21 ; write sequential -FMAKE equ 22 ; make file -FRENAME equ 23 ; rename file -RETCURR equ 25 ; return current disk, 0=a -SETDMA equ 26 ; set dma address -WRITERAND equ 34 ; write random record -FCOMPSIZE equ 35 ; compute file size -SETRANDREC equ 36 ; set random record -RESETDRIVE equ 37 ; reset drive -WRITERANDZF equ 40 ; write random with zero fill - -OEMID equ 0E5h - -; File Control Block -DR$OFS equ 0 -F1$OFS equ DR$OFS+BYTESIZE -F2$OFS equ F1$OFS+BYTESIZE -F3$OFS equ F2$OFS+BYTESIZE -F4$OFS equ F3$OFS+BYTESIZE -F5$OFS equ F4$OFS+BYTESIZE -F6$OFS equ F5$OFS+BYTESIZE -F7$OFS equ F6$OFS+BYTESIZE -F8$OFS equ F7$OFS+BYTESIZE -T1$OFS equ F8$OFS+BYTESIZE -T2$OFS equ T1$OFS+BYTESIZE -T3$OFS equ T2$OFS+BYTESIZE -EX$OFS equ T3$OFS+BYTESIZE -S1$OFS equ EX$OFS+BYTESIZE -S2$OFS equ S1$OFS+BYTESIZE -RC$OFS equ S2$OFS+BYTESIZE -D0$OFS equ RC$OFS+BYTESIZE -CR$OFS equ DR$OFS+32 -R0$OFS equ CR$OFS+BYTESIZE -R1$OFS equ R0$OFS+BYTESIZE -R2$OFS equ R1$OFS+BYTESIZE -FCB$LEN equ R2$OFS+BYTESIZE - -; Memory Locations - -BDOS equ 5 ; entry point fo BDOS function calls -PRIFCB equ 5Ch ; primary file control block address -SECFCB equ 6Ch ; secondary file control block address -LENFCB equ 32 ; length of file control block -DEFBUF equ 80h ; address of default buffer - - -EXIT macro - mvi c,TERMCPM - call BDOS - endm - -conin macro - push b ; save context B&C - push d ; save context D&E - push h ; save context H&L - mvi c,CREAD ; set up for console input BDOS call - call BDOS ; call BDOS function entry point - pop h ; restore context H&L - pop d ; restore context D&E - pop b ; restore context B&C - endm - -conout macro char - enter ; save all context regs - mvi c,CWRITE ; set for console output BDOS call - mvi e,char ; place output character in E as required - call bdos ; call BDOS function entry point - leave ; restore all context regs - endm - -conouta macro - enter - mvi c,CWRITE - mov e,a - call bdos - leave - endm - -PRINT macro addr - enter - mvi c,PRINTSTR - lxi d,addr - call BDOS - leave - endm - -PTRPRT macro addr - enter ; save all context registers - lxi h,addr ; load the address parameter into H&L - mov e,m ; pick up LO byte of new pointer - inx h ; bump index register - mov d,m ; pick up HO byte of new pointer - mvi c,PRINTSTR ; assembled pointer used for printstring call - call BDOS - leave ; restore all context registers - endm - - -movfcb macro destn,source - lxi d,destn - lxi h,source - lxi b,LENFCB - ldir - endm - -copyfcb macro fcbname,source - local around - jmp around -fcbname ds 32 -around: - endm - -printf macro parmdata - local around - local string - print string - jmp around -string db parmdata - db '$' -around: - endm - -printmsg macro parmdata - enter - local around - local string - print string - jmp around -string db parmdata - db '$' -around: - leave - endm - -newfcb macro fcbname,drive,filename -fcbname db drive,filename - db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - endm - - -; eof - cpmbdos.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMBIND.H b/branches/s100/Apps/crossdev/CPMBIND.H deleted file mode 100644 index ae14800b..00000000 --- a/branches/s100/Apps/crossdev/CPMBIND.H +++ /dev/null @@ -1,684 +0,0 @@ -/* cpmbind.h 5/21/2012 dwg - added b1f0peek and b1f0poke */ -/* cpmbind.h 3/16/2012 dgw - created */ - - -#define CR 0x0d -#define LF 0x0a -#define ESC 27 - -#define BIOSAD 0x0e600 -#define pTermType 0x0E679 - -/*************************/ -/* BIOS Memory Locations */ -/*************************/ - -#define CURDRV 0x00004 -#define BIOSAD 0x0e600 - -#define pBOOT 0x0E600 -#define pWBOOT 0x0E603 -#define pCONST 0x0E606 -#define pCONIN 0x0E609 -#define pCONOUT 0x0E60C -#define pLIST 0x0E60F -#define pPUNCH 0x0E612 -#define pREADER 0x0E615 -#define pHOME 0x0E618 -#define pSELDSK 0x0E61B -#define pSETTRK 0x0E61E -#define pSETSEC 0x0E621 -#define pSETDMA 0x0E624 -#define pREAD 0x0E627 -#define pWRITE 0x0E62A -#define pLISTST 0x0E62D -#define pSECTRN 0x0E630 -#define pBNKSEL 0x0E633 -#define pGETLU 0x0E636 -#define pSETLU 0x0E639 -#define pGETINFO 0x0E63C -#define pB1F0PEEK 0x0E63F -#define pB1F0POKE 0x0E642 - -/* - -struct JMP { - unsigned char opcode; - unsigned int address; -}; - -struct BIOS { - struct JMP boot; - struct JMP wboot; - struct JMP const; - struct JMP conin; - struct JMP conout; - struct JMP list; - struct JMP punch; - struct JMP reader; - struct JMP home; - struct JMP seldsk; - struct JMP settrk; - struct JMP setsec; - struct JMP setdma; - struct JMP read; - struct JMP write; - struct JMP listst; - struct JMP sectrn; - struct JMP bnksel; - struct JMP getlu; - struct JMP setlu; - struct JMP getinfo; - struct JMP b1f0peek; - struct JMP b1f0poke; - struct JMP res1; - struct JMP res2; - - char rmj; - char rmn; - char rup; - char rtp; - char diskboot; - char bootdrive; - char timedate[6]; - char cpufreq; - char platform; - char dioplat; - char vduplt; - unsigned int romsize; - unsigned int ramsize; - char clrramdisk; - char dskyenable; - char uartenable; - char vduenable; - char fdenable; - char fdtrace; - char fdmedia; - char fdmediaalt; - char fdmauto; - char ideenable; - char idetrace; - char ide8bit; - unsigned int idecapacity; - char ppideenable; - char ppidetrace; - char ppide8bit; - unsigned int ppidecapacity; - char ppideslow; - char boottype; - char boot_timeout; - char boot_default; - unsigned int baudrate; - char clkdiv; - char memwait; - char iowait; - char cntlb0; - char cntlb1; - char sdenable; - char sdtrace; - unsigned int sdcapacity; - char sdcsio; - char sdcsiofast; - char defiobyte; - char termtype; - unsigned int revision; - char prpsdenable; - char prpsdtrace; - char prpsdcapacity; - char prpconenable; - unsigned int biossize; -}; - -*/ - -/* - - -*/ - -/* bioscall.h 3/10/2012 dwg - header file for bdoscall */ - - extern char irega; - extern unsigned int iregbc; - extern unsigned int iregde; - extern unsigned int ireghl; - extern bioscall(); - - -/*********************/ -/* BDOS Declarations */ -/*********************/ - -#define TERMCPM 0 -#define CONIN 1 -#define CWRITE 2 -#define DIRCONIO 6 -#define PRINTSTR 9 -#define RDCONBUF 10 -#define GETCONST 11 -#define RETVERNUM 12 -#define RESDISKSYS 13 -#define SELECTDISK 14 -#define FOPEN 15 -#define FCLOSE 16 -#define SEARCHFIRST 17 -#define SEARCHNEXT 18 -#define FDELETE 19 -#define FREADSEQ 20 -#define FWRITESEQ 21 -#define FMAKEFILE 22 -#define FRENAME 23 -#define RETLOGINVEC 24 -#define RETCURRDISK 25 -#define SETDMAADDR 26 -#define GETALLOCVEC 27 -#define WRPROTDISK 28 -#define GETROVECTOR 29 -#define FSETATTRIB 30 -#define GETDPBADDR 31 -#define SETGETUSER 32 -#define FREADRANDOM 33 -#define FWRITERAND 34 -#define FCOMPSIZE 35 -#define SETRANDREC 36 -#define RESETDRIVE 37 -#define WRRANDFILL 38 - -#define DRIVEA 0 - -/* bdoscall.h 3/10/2012 dwg - header file for bdoscall */ - - extern char drega; - extern unsigned int dregbc; - extern unsigned int dregde; - extern unsigned int dreghl; - extern bdoscall(); - -/* std.h 3/11/2012 dwg - c version of std.asm */ - -#define TERM_TTY 0 -#define TERM_ANSI 1 -#define TERM_WYSE 2 -#define TERM_VT52 3 - -#define DEV_MD 0x00 -#define DEV_FD 0x10 -#define DEV_IDE 0x20 -#define DEV_ATAPI 0x30 -#define DEV_PPIDE 0x40 -#define DEV_SD 0x50 -#define DEV_PRPSD 0x60 -#define DEV_PPPSD 0x70 -#define DEV_HDSK 0x80 - -#define PLT_N8VEM 1 -#define PLT_ZETA 2 -#define PLT_N8 3 - - -/* - - -; std.lib 2/21/2012 dwg - added TERM$VT52 - -; TRUE equ 1 -; FALSE equ 00 -; -; PRIMARY HARDWARE PLATFORMS -; PLT$N8VEM equ 1 ; N8VEM ECB Z80 SBC -; PLT$ZETA equ 2 ; ZETA Z80 SBC -; PLT$N8 equ 3 ; N8 (HOME COMPUTER) Z180 SBC -; -; BOOT STYLE -; BT$MENU equ 1 ; WAIT FOR MENU SELECTION AT LOADER PROMPT -; BT$AUTO equ 2 ; AUTO SELECT BOOT$DEFAULT AFTER BOOT$TIMEOUT -; -; VDU PLATFORM SELECTIONS -; -; -; VDUPLT$NONE equ 0 ; NO VDU -; VDUPLT$VDU equ 1 ; ORIGINAL ECB VDU (6545 CHIP) -; VDUPLT$VDUC equ 2 ; ECB VDU COLOR (PENDING HARDWARE DEVELOPMENT) -; VDUPLT$PROPIO equ 3 ; ECB PROPIO (NOT IMPLEMENTED) -; VDUPLT$N8 equ 4 ; N8 ONBOARD VIDEO SUBSYSTEM (NOT IMPLEMENTED) -; -; RAM DISK INITIALIZATION OPTIONS -; CLR$NEVER equ 0 ; NEVER CLEAR RAM DISK -; CLR$AUTO equ 1 ; CLEAR RAM DISK IF INVALID DIR ENTRIES -; CLR$ALWAYS equ 2 ; ALWAYS CLEAR RAM DISK -; -; -; ; DISK MAP SELECTION OPTIONS -; -; DM$ROM equ 1 ; ROM DRIVE PRIORITY -; DM$RAM equ 2 ; RAM DRIVE PRIORITY -; DM$FD equ 3 ; FLOPPY DRIVE PRIORITY -; DM$IDE equ 4 ; IDE DRIVE PRIORITY -; DM$PPIDE equ 5 ; PPIDE DRIVE PRIORITY -; DM$SD equ 6 ; SD DRIVE PRIORITY -; DM$PRPSD equ 7 ; PROPIO SD DRIVE PRIORITY -; -; -; ; FLOPPY DISK MEDIA SELECTIONS (ID'S MUST BE INDEX OF ENTRY IN FCD$TBL) -; -; -; FDM720 equ 0 ; 3.5" FLOPPY, 720KB, 2 SIDES, 80 TRKS, 9 SECTORS -; FDM144 equ 1 ; 3.5" FLOPPY, 1.44MB, 2 SIDES, 80 TRKS, 18 SECTORS -; FDM360 equ 2 ; 5.25" FLOPPY, 360KB, 2 SIDES, 40 TRKS, 9 SECTORS -; FDM120 equ 3 ; 3.5" FLOPPY, 1.2MB, 2 SIDES, 80 TRKS, 15 SECTORS -; -; -; ; DISK PLATFORM SELECTIONS -; -; DIOPLT$NONE equ 0 ; NO DISK IO HARDWARE -; DIOPLT$DISKIO equ 1 ; N8VEM ECB DISK IO BOARD -; DIOPLT$ZETA equ 2 ; ZETA BUILT-IN DISK IO SECTION -; DIOPLT$DIDE equ 3 ; N8VEM ECB DUAL IDE W/ FLOPPY BOARD -; DIOPLT$N8 equ 4 ; N8 BUILT-IN DISK IO SECTION -; DIOPLT$DISKIO3 equ 5 ; N8VEM ECB DISK IO V3 BOARD -; -; CONSOLE DEVICE CHOICES FOR LDRCON AND DBGCON IN CONFIG SETTINGS -; -; CON$UART equ 1 -; CON$VDU equ 2 -; CON$PRP equ 3 -; -; CONSOLE TERMINAL TYPE CHOICES -; -TERM$TTY equ 0 -TERM$ANSI equ 1 -TERM$WYSE equ 2 -TERM$VT52 equ 3 -; -; -; ; SYSTEM GENERATION SETTINGS -; -; SYS$CPM equ 1 ; CPM (IMPLIES BDOS + CCP) -; SYS$ZSYS equ 2 ; ZSYSTEM OS (IMPLIES ZSDOS + ZCPR) -; -; DOS$BDOS equ 1 ; BDOS -; DOS$ZDDOS equ 2 ; ZDDOS VARIANT OF ZSDOS -; DOS$ZSDOS equ 3 ; ZSDOS -; -; CP$CCP equ 1 ; CCP COMMAND PROCESSOR -; CP$ZCPR equ 2 ; ZCPR COMMAND PROCESSOR -; -; CONFIGURE DOS (DOS) AND COMMAND PROCESSOR (CP) BASED ON SYSTEM SETTING (SYS) -; -; -; #IFNDEF BLD$SYS -; SYS equ SYS$CPM -; #ELSE -; SYS equ BLD$SYS -; #ENDIF -; -; #IF (SYS == SYS$CPM) -; DOS equ DOS$BDOS -; CP equ CP$CCP -; #DEFINE OSLBL "CP/M-80 2.2C" -; #ENDIF -; -; #IF (SYS == SYS$ZSYS) -; DOS equ DOS$ZSDOS -; CP equ CP$ZCPR -; #DEFINE OSLBL "ZSYSTEM (ZSDOS 1.2, ZCPR 1.0)" -; #ENDIF -; -; -; ; INCLUDE VERSION AND BUILD SETTINGS -; -; #INCLUDE "ver.inc" ; ADD BIOSVER -; -; -; #INCLUDE "build.inc" ; INCLUDE USER CONFIG, ADD VARIANT, TIMESTAMP, & ROMSIZE -; -; -; #IF (PLATFORM NE PLT$N8) -; -; -; ; N8VEM HARDWARE IO PORT ADDRESSES AND MEMORY LOCATIONS -; MPCL$RAM equ 78H ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH -; MPCL$ROM equ 7CH ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH -; -; -; ; HARDWARE INTERFACES -; -; PIO 82C55 I/O IS DECODED TO PORT 60-67 -; PIOA equ 60H ; PORT A -; PIOB equ 61H ; PORT B -; PIOC equ 62H ; PORT C -; PIOX equ 63H ; PIO CONTROL PORT -; -; 16C550 SERIAL LINE UART -; -; SIO$BASE equ 68H -; SIO$RBR equ SIO$BASE + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY) -; SIO$THR equ SIO$BASE + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY) -; SIO$IER equ SIO$BASE + 1 ; DLAB=0: INT ENABLE REG -; SIO$IIR equ SIO$BASE + 2 ; INT IDENT REGISTER (READ ONLY) -; SIO$FCR equ SIO$BASE + 2 ; FIFO CONTROL REG (WRITE ONLY) -; SIO$LCR equ SIO$BASE + 3 ; LINE CONTROL REG -; SIO$MCR equ SIO$BASE + 4 ; MODEM CONTROL REG -; SIO$LSR equ SIO$BASE + 5 ; LINE STATUS REG -; SIO$MSR equ SIO$BASE + 6 ; MODEM STATUS REG -; SIO$SCR equ SIO$BASE + 7 ; SCRATCH REGISTER -; SIO$DLL equ SIO$BASE + 0 ; DLAB=1: DIVISOR LATCH (LS) -; SIO$DLM equ SIO$BASE + 1 ; DLAB=1: DIVISOR LATCH (MS) -; #ENDIF ; (PLATFORM NE PLT$N8) -; -; -; #IF (PLATFORM NE PLT$N8) -; -; -; ; Z180 REGISTERS -; -; -; CPU$IOBASE equ 40H ; ONLY RELEVANT FOR Z180 -; CPU$CNTLA0 equ CPU$IOBASE+$00 ;ASCI0 control A -; CPU$CNTLA1 equ CPU$IOBASE+$01 ;ASCI1 control A -; CPU$CNTLB0 equ CPU$IOBASE+$02 ;ASCI0 control B -; CPU$CNTLB1 equ CPU$IOBASE+$03 ;ASCI1 control B -; CPU$STAT0 equ CPU$IOBASE+$04 ;ASCI0 status -; CPU$STAT1 equ CPU$IOBASE+$05 ;ASCI1 status -; CPU$TDR0 equ CPU$IOBASE+$06 ;ASCI0 transmit -; CPU$TDR1 equ CPU$IOBASE+$07 ;ASCI1 transmit -; CPU$RDR0 equ CPU$IOBASE+$08 ;ASCI0 receive -; CPU$RDR1 equ CPU$IOBASE+$09 ;ASCI1 receive -; CPU$CNTR equ CPU$IOBASE+$0A ;CSI/O control -; CPU$TRDR equ CPU$IOBASE+$0B ;CSI/O transmit/receive -; CPU$TMDR0L equ CPU$IOBASE+$0C ;Timer 0 data lo -; CPU$TMDR0H equ CPU$IOBASE+$0D ;Timer 0 data hi -; CPU$RLDR0L equ CPU$IOBASE+$0E ;Timer 0 reload lo -; CPU$RLDR0H equ CPU$IOBASE+$0F ;Timer 0 reload hi -; CPU$TCR equ CPU$IOBASE+$10 ;Timer control -; CPU$ASEXT0 equ CPU$IOBASE+$12 ;ASCI0 extension control (Z8S180) -; CPU$ASEXT1 equ CPU$IOBASE+$13 ;ASCI1 extension control (Z8S180) -; CPU$TMDR1L equ CPU$IOBASE+$14 ;Timer 1 data lo -; CPU$TMDR1H equ CPU$IOBASE+$15 ;Timer 1 data hi -; CPU$RLDR1L equ CPU$IOBASE+$16 ;Timer 1 reload lo -; CPU$RLDR1H equ CPU$IOBASE+$17 ;Timer 1 reload hi -; CPU$FRC equ CPU$IOBASE+$18 ;Free running counter -; CPU$ASTC0L equ CPU$IOBASE+$1A ;ASCI0 Time constant lo (Z8S180) -; CPU$ASTC0H equ CPU$IOBASE+$1B ;ASCI0 Time constant hi (Z8S180) -; CPU$ASTC1L equ CPU$IOBASE+$1C ;ASCI1 Time constant lo (Z8S180) -; CPU$ASTC1H equ CPU$IOBASE+$1D ;ASCI1 Time constant hi (Z8S180) -; CPU$CMR equ CPU$IOBASE+$1E ;Clock multiplier (latest Z8S180) -; CPU$CCR equ CPU$IOBASE+$1F ;CPU control (Z8S180) -; CPU$SAR0L equ CPU$IOBASE+$20 ;DMA0 source addr lo -; CPU$SAR0H equ CPU$IOBASE+$21 ;DMA0 source addr hi -; CPU$SAR0B equ CPU$IOBASE+$22 ;DMA0 source addr bank -; CPU$DAR0L equ CPU$IOBASE+$23 ;DMA0 dest addr lo -; CPU$DAR0H equ CPU$IOBASE+$24 ;DMA0 dest addr hi -; CPU$DAR0B equ CPU$IOBASE+$25 ;DMA0 dest addr bank -; CPU$BCR0L equ CPU$IOBASE+$26 ;DMA0 byte count lo -; CPU$BCR0H equ CPU$IOBASE+$27 ;DMA0 byte count hi -; CPU$MAR1L equ CPU$IOBASE+$28 ;DMA1 memory addr lo -; CPU$MAR1H equ CPU$IOBASE+$29 ;DMA1 memory addr hi -; CPU$MAR1B equ CPU$IOBASE+$2A ;DMA1 memory addr bank -; CPU$IAR1L equ CPU$IOBASE+$2B ;DMA1 I/O addr lo -; CPU$IAR1H equ CPU$IOBASE+$2C ;DMA1 I/O addr hi -; CPU$IAR1B equ CPU$IOBASE+$2D ;DMA1 I/O addr bank (Z8S180) -; CPU$BCR1L equ CPU$IOBASE+$2E ;DMA1 byte count lo -; CPU$BCR1H equ CPU$IOBASE+$2F ;DMA1 byte count hi -; CPU$DSTAT equ CPU$IOBASE+$30 ;DMA status -; CPU$DMODE equ CPU$IOBASE+$31 ;DMA mode -; CPU$DCNTL equ CPU$IOBASE+$32 ;DMA/WAIT control -; CPU$IL equ CPU$IOBASE+$33 ;Interrupt vector load -; CPU$ITC equ CPU$IOBASE+$34 ;INT/TRAP control -; CPU$RCR equ CPU$IOBASE+$36 ;Refresh control -; CPU$CBR equ CPU$IOBASE+$38 ;MMU common base register -; CPU$BBR equ CPU$IOBASE+$39 ;MMU bank base register -; CPU$CBAR equ CPU$IOBASE+$3A ;MMU common/bank area register -; CPU$OMCR equ CPU$IOBASE+$3E ;Operation mode control -; CPU$ICR equ $3F ;I/O control register (not relocated) -; -; N8 ONBOARD I/O REGISTERS -; N8$IOBASE equ $80 -; PIO equ N8$IOBASE+$00 -; PIOA equ PIO+$00 ; PORT A -; PIOB equ PIO+$01 ; PORT B -; PIOC equ PIO+$02 ; PORT C -; PIOX equ PIO+$03 ; PIO CONTROL PORT -; PIO2 equ N8$IOBASE+$04 -; PIO2A equ PIO2+$00 ; PORT A -; PIO2B equ PIO2+$01 ; PORT B -; PIO2C equ PIO2+$02 ; PORT C -; PIO2X equ PIO2+$03 ; PIO CONTROL PORT -; -; RTC equ N8$IOBASE+$08 ;RTC latch and buffer -; FDC equ N8$IOBASE+$0C ;Floppy disk controller -; UTIL equ N8$IOBASE+$10 ;Floppy disk utility -; ACR equ N8$IOBASE+$14 ;auxillary control register -; RMAP equ N8$IOBASE+$16 ;ROM page register -; VDP equ N8$IOBASE+$18 ;Video Display Processor (TMS9918A) -; PSG equ N8$IOBASE+$1C ;Programmable Sound Generator (AY-3-8910) -; -; DEFACR equ $1B -; -; #ENDIF -; -; -; ; CHARACTER DEVICE FUNCTIONS -; -; -; CF$INIT equ 0 -; CF$IN equ 1 -; CF$IST equ 2 -; CF$OUT equ 3 -; CF$OST equ 4 -; -; DISK OPERATIONS -; DOP$READ equ 0 ; READ OPERATION -; DOP$WRITE equ 1 ; WRITE OPERATION -; DOP$FORMAT equ 2 ; FORMAT OPERATION -; DOP$READID equ 3 ; READ ID OPERATION -; -; DISK DRIVER FUNCTIONS -; DF$READY equ 1 -; DF$SELECT equ 2 -; DF$READ equ 3 -; DF$WRITE equ 4 -; DF$FORMAT equ 5 -; -; DISK DEVICES (ONLY FIRST NIBBLE RELEVANT, SECOND NIBBLE MUST BE ZERO) -; DEV$MD equ 000H -; DEV$FD equ 010H -; DEV$IDE equ 020H -; DEV$ATAPI equ 030H -; DEV$PPIDE equ 040H -; DEV$SD equ 050H -; DEV$PRPSD equ 060H -; -; IMG$START equ 00000H ; IMMUTABLE: ROM IMAGE AREA START -; IMG$END equ 08000H ; IMMUTABLE: ROM IMAGE AREA END -; -; PG0$LOC equ 00000H ; IMMUTABLE -; PG0$SIZ equ 00100H ; IMMUTABLE -; PG0$END equ PG0$LOC + PG0$SIZ -; PG0$IMG equ IMG$START ; IMMUTABLE -; LDR$LOC equ PG0$END -; LDR$SIZ equ 02000H - PG0$SIZ ; CONFIGURABLE -; LDR$END equ LDR$LOC + LDR$SIZ -; LDR$IMG equ PG0$IMG + PG0$SIZ -; CPM$LOC equ 0D000H ; CONFIGURABLE: LOCATION OF CPM FOR RUNNING SYSTEM -; CPM$END equ 10000H ; IMMUTABLE: TOP OF MEMORY -; CPM$SIZ equ CPM$END - CPM$LOC ; SIZE OF CPM IMAGE (CCP + BDOS + CBIOS (INCLUDING DATA)) -; CPM$ENT equ CPM$LOC + 01600H ; IMMUTABLE: CPM ENTRY POINT -; CPM$IMG equ LDR$IMG + LDR$SIZ ; START OF CONCATENATED CPM IMAGE -; DAT$SIZ equ DATASIZE ; FROM CONFIG FILE -; DAT$END equ CPM$END -; DAT$LOC equ DAT$END - DAT$SIZ -; BIOS$LOC equ CPM$ENT -; BIOS$END equ DAT$LOC -; BIOS$SIZ equ DAT$LOC - CPM$ENT -; MON$IMG equ CPM$IMG + CPM$SIZ ; LOCATION OF MONITOR BINARY IMAGE IN ROM -; MON$LOC equ 08000H ; LOCATION OF MONITOR FOR RUNNING SYSTEM -; MON$SIZ equ 01000H ; SIZE OF MONITOR BINARY IMAGE -; MON$END equ MON$LOC + MON$SIZ -; MON$DSKY equ MON$LOC ; MONITOR ENTRY (DSKY) -; MON$UART equ MON$LOC + 3 ; MONITOR ENTRY (UART) -; ROMX$LOC equ MON$IMG + MON$SIZ ; LOCATION OF ROM EXTENSION CODE -; -; -; ROMX$SIZ equ 02000H ; FIXED -; ROMX$END equ ROMX$LOC + ROMX$SIZ -; -; -; VDU$LOC equ ROMX$LOC + 0 ; LOCATION OF ROM VDU DRIVER -; -; -; CBIOS$BOOT equ BIOS$LOC + 0 -; CBIOS$WBOOT equ BIOS$LOC + 3 -; CBIOS$CONST equ BIOS$LOC + 6 -; CBIOS$CONIN equ BIOS$LOC + 9 -; CBIOS$CONOUT equ BIOS$LOC + 12 -; CBIOS$LIST equ BIOS$LOC + 15 -; CBIOS$PUNCH equ BIOS$LOC + 18 -; CBIOS$READER equ BIOS$LOC + 21 -; CBIOS$HOME equ BIOS$LOC + 24 -; CBIOS$SELDSK equ BIOS$LOC + 27 -; CBIOS$SETTRK equ BIOS$LOC + 30 -; CBIOS$SETSEC equ BIOS$LOC + 33 -; CBIOS$SETDMA equ BIOS$LOC + 36 -; CBIOS$READ equ BIOS$LOC + 39 -; CBIOS$WRITE equ BIOS$LOC + 42 -; CBIOS$LISTST equ BIOS$LOC + 45 -; CBIOS$SECTRN equ BIOS$LOC + 48 -; -; MEMORY CONFIGURATION -; -; MSIZE equ 59 ; CP/M VERSION MEMORY SIZE IN KILOBYTES -; -; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS -; ; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT) -; -; BIAS equ (MSIZE-20)*1024 -; CCP equ 3400H+BIAS ; BASE OF CCP -; BDOS equ CCP+806H ; BASE OF BDOS -; BIOS equ CCP+1600H ; BASE OF BIOS -; CCPSIZ equ 00800H -; -; #IF (PLATFORM == PLT$N8VEM) -; -; -; ; #DEFINE PLATFORM$NAME "N8VEM Z80 SBC" -; -; -; ; #ENDIF -; -; -; ; #IF (PLATFORM == PLT$ZETA) -; ; #DEFINE PLATFORM$NAME "ZETA Z80 SBC" -; ; #ENDIF -; -; -; ; #IF (PLATFORM == PLT$N8) -; ; #DEFINE PLATFORM$NAME "N8 Z180 SBC" -; ; #ENDIF -; -; #IF (DSKYENABLE) -; ; #DEFINE DSKYLBL ", DSKY" -; ; #ELSE -; ; #DEFINE DSKYLBL "" -; ; #ENDIF -; -; #IF (VDUENABLE) -; #DEFINE VDULBL ", VDU" -; #ELSE -; #DEFINE VDULBL "" -; #ENDIF -; -; #IF (DIOPLT NE DIOPLT$NONE) -; -; -; #IF (DIOPLT EQ DIOPLT$DISKIO) -; #DEFINE DIOLBL ", DISKIO" -; #ENDIF -; -; -; #IF (DIOPLT EQ DIOPLT$ZETA) -; #DEFINE DIOLBL "" -; #ENDIF -; -; -; #IF (DIOPLT EQ DIOPLT$DIDE) -; #DEFINE DIOLBL ", DUALIDE" -; #ENDIF -; -; -; #IF (DIOPLT EQ DIOPLT$N8) -; #DEFINE DIOLBL "" -; #ENDIF -; -; #IF (DIOPLT EQ DIOPLT$DISKIO3) -; #DEFINE DIOLBL ", DISKIO-V3" -; #ENDIF -; -; #ELSE -; #DEFINE DIOLBL "" -; #ENDIF -; -; -; ; #ENDIF -; -; -; #IF (FDENABLE) -; #IF (FDMAUTO) -; #DEFINE FDLBL ", FLOPPY (AUTOSIZE)" -; #ELSE -; #IF (FDMEDIA == FDM720) -; #DEFINE FDLBL ", FLOPPY (720KB)" -; #ENDIF -; #IF (FDMEDIA == FDM144) -; #DEFINE FDLBL ", FLOPPY (1.44MB)" -; #ENDIF -; #ENDIF -; #ELSE -; #DEFINE FDLBL "" -; #ENDIF -; -; -; #IF (IDEENABLE) -; #DEFINE IDELBL ", IDE" -; #ELSE -; #DEFINE IDELBL "" -; #ENDIF -; -; -; #IF (PPIDEENABLE) -; #DEFINE PPIDELBL ", PPIDE" -; #ELSE -; #DEFINE PPIDELBL "" -; #ENDIF -; -; #IF (SDENABLE) -; #DEFINE SDLBL ", SD CARD" -; #ELSE -; #DEFINE SDLBL "" -; #ENDIF -; -; -; #IF (PRPSDENABLE) -; #DEFINE PRPSDLBL ", PROPIO SD CARD" -; #ELSE -; #DEFINE PRPSDLBL "" -; #ENDIF -; -; -; ; .ECHO "Configuration: " -; ; .ECHO PLATFORM$NAME -; ; .ECHO DSKYLBL -; ; .ECHO VDULBL -; ; .ECHO DIOLBL -; ; .ECHO FDLBL -; ; .ECHO IDELBL -; ; .ECHO PPIDELBL -; ; .ECHO SDLBL -; ; .ECHO PRPSDLBL -; ; .ECHO "\n" -; ; -; -; eof - std.lib - -*/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMBIOS.H b/branches/s100/Apps/crossdev/CPMBIOS.H deleted file mode 100644 index 9b4764fe..00000000 --- a/branches/s100/Apps/crossdev/CPMBIOS.H +++ /dev/null @@ -1,104 +0,0 @@ -/* cpmbios.h 6/ 4/2012 dwg - added bootlu */ -/* cpmbios.h 3/11/2012 dwg - added CURDRV */ - -/*************************/ -/* BIOS Memory Locations */ -/*************************/ - -#define CURDRV 0x00004 -#define BIOSAD 0x0e600 - -#define pBOOT 0x0E600 -#define pWBOOT 0x0E603 -#define pCONST 0x0E606 -#define pCONIN 0x0E609 -#define pCONOUT 0x0E60C -#define pLIST 0x0E60F -#define pPUNCH 0x0E612 -#define pREADER 0x0E615 -#define pHOME 0x0E618 -#define pSELDSK 0x0E61B -#define pSETTRK 0x0E61E -#define pSETSEC 0x0E621 -#define pSETDMA 0x0E624 -#define pREAD 0x0E627 -#define pWRITE 0x0E62A -#define pLISTST 0x0E62D -#define pSECTRN 0x0E630 -#define pBNKSEL 0x0E633 -#define pGETLU 0x0E636 -#define pSETLU 0x0E639 -#define pGETINFO 0x0E63C - -struct JMP { - unsigned char opcode; - unsigned int address; -}; - -struct BIOS { - struct JMP boot; - struct JMP wboot; - struct JMP const; - struct JMP conin; - struct JMP conout; - struct JMP list; - struct JMP punch; - struct JMP reader; - struct JMP home; - struct JMP seldsk; - struct JMP settrk; - struct JMP setsec; - struct JMP setdma; - struct JMP read; - struct JMP write; - struct JMP listst; - struct JMP sectrn; - struct JMP bnksel; - struct JMP getlu; - struct JMP setlu; - struct JMP getinfo; - struct JMP rsvd1; - struct JMP rsvd2; - struct JMP rsvd3; - struct JMP rsvd4; - -/* char diskboot; - char bootdrive; - int bootlu; */ - - char rmj; - char rmn; - char rup; - char rtp; -}; - - -struct DPH { - unsigned int xlt; - unsigned int rv1; - unsigned int rv2; - unsigned int rv3; - unsigned int dbf; - unsigned int dpb; - unsigned int csv; - unsigned int alv; - unsigned char sigl; - unsigned char sigu; - unsigned int current; - unsigned int number; -}; - -struct DPB { - unsigned int spt; - unsigned char bsh; - unsigned char blm; - unsigned char exm; - unsigned int dsm; - unsigned int drm; - unsigned char al0; - unsigned char al1; - unsigned int cks; - unsigned int off; -}; - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMBIOS.LIB b/branches/s100/Apps/crossdev/CPMBIOS.LIB deleted file mode 100644 index 82c80bea..00000000 --- a/branches/s100/Apps/crossdev/CPMBIOS.LIB +++ /dev/null @@ -1,137 +0,0 @@ -; cpmbios.lib 2/20/2012 dwg - get$off, get$drm, and get$spt need c=drvnum -; cpmbios.lib 12/26/2011 dwg - - -; Copyright (C) 2011-2012 Douglas Goodall All Rights Reserved. -; For non-commercial use by N8VEM community - -XLT$OFS equ 0 ; Translate Table -RV1$OFS equ XLT$OFS+WORDSIZE ; Reserved Field 1 -RV2$OFS equ RV1$OFS+WORDSIZE ; Reserved Field 2 -RV3$OFS equ RV2$OFS+WORDSIZE ; Reserved Field 3 -DBF$OFS equ RV3$OFS+WORDSIZE ; Directory Buffer -DPB$OFS equ DBF$OFS+WORDSIZE ; Diskk Parameter Block Pointer -CSV$OFS equ DPB$OFS+WORDSIZE ; Checksum Vector -ALV$OFS equ CSV$OFS+WORDSIZE ; Allocation Vector -DPH$LEN equ ALV$OFS+WORDSIZE ; size of normal DPH -LU1$OFS equ ALV$OFS+WORDSIZE ; Logical Unit Signature Byte 1 'L' -LU2$OFS equ LU1$OFS+BYTESIZE ; Logical Unit Signature Byte 2 'U' -CUR$OFS equ LU2$OFS+BYTESIZE ; Current Logical Unit (default) -NLU$OFS equ CUR$OFS+WORDSIZE ; Number of LU's (capacity/9) - - -SPT$OFS equ 0 ; Sectors Per Track -BSH$OFS equ SPT$OFS+WORDSIZE ; Block Shift Factor -BLM$OFS equ BSH$OFS+BYTESIZE ; Data Allocation Block Mask -EXM$OFS equ BLM$OFS+BYTESIZE ; Extend Mask -DSM$OFS equ EXM$OFS+BYTESIZE ; Disk Size Max -DRM$OFS equ DSM$OFS+WORDSIZE ; Number of Directory Entries -AL0$OFS equ DRM$OFS+WORDSIZE ; Allocation bitmask for directories -AL1$OFS equ AL0$OFS+BYTESIZE ; Allocation bitmask for directories -CKS$OFS equ AL1$OFS+BYTESIZE ; Size of Directory Check Vector -OFF$OFS equ CKS$OFS+WORDSIZE ; Number of Reserved Tracks -DPB$LEN equ OFF$OFS+WORDSIZE ; Disk Parameter Block Length - -; BIOS Memory Locations -BIBOOT equ 0E600h -BIWBOOT equ 0E603h -BICONST equ 0E606h -BICONIN equ 0E609h -BICONOUT equ 0E60Ch -BILIST equ 0E60Fh -BIPUNCH equ 0E612h -BIREADER equ 0E615h -BIHOME equ 0E618h -BISELDSK equ 0E61Bh -BISETTRK equ 0E61Eh -BISETSEC equ 0E621h -BISETDMA equ 0E624h -BIREAD equ 0E627h -BIWRITE equ 0E62Ah -BILISTST equ 0E62Dh -BISECTRN equ 0E630h - -; These are rel zero drive number for talking to the BIOS -; BDOS typically uses rel one drive codes - -BIDRVA equ 0 -BIDRVB equ 1 -BIDRVC equ 2 -BIDRVD equ 3 -BIDRVE equ 4 -BIDRVF equ 5 -BIDRVG equ 6 -BIDRVH equ 7 - -; On entry: c=drive number -get$spt macro - push psw - push b - push d - call BISELDSK - lxi d,DPB$OFS - dad d - mov e,m - inx h - mov d,m - xchg - lxi d,SPT$OFS - dad d - mov e,m - inx h - mov d,m - xchg - pop d - pop b - pop psw - endm - -; On entry: c=drive number -get$drm macro - push psw - push b - push d - call BISELDSK - lxi d,DPB$OFS - dad d - mov e,m - inx h - mov d,m - xchg - lxi d,DRM$OFS - dad d - mov e,m - inx h - mov d,m - xchg - pop d - pop b - pop psw - endm - -; On entry, c=drive number -get$off macro - push psw - push b - push d - call BISELDSK - lxi d,DPB$OFS - dad d - mov e,m - inx h - mov d,m - xchg - lxi d,OFF$OFS - dad d - mov e,m - inx h - mov d,m - xchg - pop d - pop b - pop psw - endm - - - -; eof - cpmbios.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMNAME.BAT b/branches/s100/Apps/crossdev/CPMNAME.BAT deleted file mode 100644 index 33a14847..00000000 --- a/branches/s100/Apps/crossdev/CPMNAME.BAT +++ /dev/null @@ -1,57 +0,0 @@ -rem cpmname.sub 9/5/2012 dwg - build cpmname from sources - -if not exist cpmname.asm erase cpmname.cpm -if not exist cpmname.asm erase cpmname.o -if not exist cpmname.asm z80mu cc cpmname -if not exist cpmname.o erase cpmname.cpm -if not exist cpmname.o z80mu as cpmname - -if not exist cnamept1.asm erase cpmname.cpm -if not exist cnamept1.asm erase cnamept1.o -if not exist cnamept1.asm z80mu cc cnamept1 -if not exist cnamept1.o erase cpmname.cpm -if not exist cnamept1.o z80mu as cnamept1 - -if not exist cnamept2.asm erase cpmname.cpm -if not exist cnamept2.asm erase cnamept2.o -if not exist cnamept2.asm z80mu cc cnamept2 -if not exist cnamept2.o erase cpmname.cpm -if not exist cnamept2.o z80mu as cnamept2 - -if not exist cnamept3.asm erase cpmname.cpm -if not exist cnamept3.asm erase cnamept3.o -if not exist cnamept3.asm z80mu cc cnamept3 -if not exist cnamept3.o erase cpmname.cpm -if not exist cnamept3.o z80mu as cnamept3 - -if not exist cnamept4.asm erase cpmname.cpm -if not exist cnamept4.asm erase cnamept4.o -if not exist cnamept4.asm z80mu cc cnamept4 -if not exist cnamept4.o erase cpmname.cpm -if not exist cnamept4.o z80mu as cnamept4 - -if not exist bdoscall.o erase cpmname.cpm -if not exist bdoscall.o z80mu as bdoscall - -if not exist bioscall.o erase cpmname.cpm -if not exist bioscall.o z80mu as bioscall - -if not exist cmemory.asm erase cpmname.cpm -if not exist cmemory.asm erase cmemory.o -if not exist cmemory.asm z80mu cc cmemory -if not exist cmemory.o erase cpmname.cpm -if not exist cmemory.o z80mu as cmemory - -if not exist ctermcap.asm erase cpmname.cpm -if not exist ctermcap.asm erase ctermcap.o -if not exist ctermcap.asm z80mu cc ctermcap -if not exist ctermcap.o erase cpmname.cpm -if not exist ctermcap.o z80mu as ctermcap - -if not exist diagnose.o erase cpmname.cpm -if not exist diagnose.o z80mu as diagnose - -if not exist cpmname.cpm z80mu ln cpmname.o ctermcap.o cnamept1.o cnamept2.o cnamept3.o cnamept4.o cmemory.o diagnose.o bioscall.o bdoscall.o c.lib -if not exist cpmanme.cpm rename cpmname.com cpmname.cpm - -dir cpmname.cpm diff --git a/branches/s100/Apps/crossdev/CPMNAME.C b/branches/s100/Apps/crossdev/CPMNAME.C deleted file mode 100644 index 4853815f..00000000 --- a/branches/s100/Apps/crossdev/CPMNAME.C +++ /dev/null @@ -1,105 +0,0 @@ -/* cpmname.c 5/21/2012 dwg - */ - -#include "stdio.h" -#include "stdlib.h" -#include "portab.h" -#include "memory.h" -#include "globals.h" -#include "cpmbind.h" -#include "applvers.h" -#include "infolist.h" -#include "cnfgdata.h" -#include "syscfg.h" -#include "diagnose.h" -#include "std.h" - -#define BDOS 5 /* memory address of BDOS invocation */ -#define HIGHSEG 0x0C000 /* memory address of system config */ - -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - - -extern cnamept1(); -extern cnamept2(); -extern cnamept3(); -extern cnamept4(); - - - -struct SYSCFG * pSYSCFG; -int line; - -int main(argc,argv) - int argc; - char *argv[]; -{ - - - char *p; - char c; - int i; - - char * pC; - - line = 5; - - - - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the NBIOS function */ - pSYSCFG = HIGHSEG; - - crtinit(pSYSCFG->cnfgdata.termtype); - crtclr(); - crtlc(0,0); - - printf("CPMNAME.COM %d/%d/%d v%d.%d.%d (%d)", - A_MONTH,A_DAY,A_YEAR,A_RMJ,A_RMN,A_RUP,A_RTP); - printf(" dwg - Display System Configuration"); - pager(); - pager(); - - ireghl = pGETINFO; - bioscall(); - pINFOLIST = ireghl; - - printf("pINFOLIST->banptr ==> "); - - dregde = pINFOLIST->banptr; - dregbc = 9; - bdoscall(); - pager(); - - - hregbc = 0xf000; - hregde = HIGHSEG; - diagnose(); - - pSYSCFG = HIGHSEG; - - - cnamept1(pSYSCFG); - cnamept2(pSYSCFG); - cnamept3(pSYSCFG); - cnamept4(pSYSCFG); - -} - -pager() -{ - line++; - printf("\n"); - if(24 == line) { - printf(" press any key to continue"); - dregbc = 1; - bdoscall(); - line = 1; - } -} - -/********************/ -/* eof - ccpmname.c */ -/********************/ - -  \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CPMNAME.CPM b/branches/s100/Apps/crossdev/CPMNAME.CPM deleted file mode 100644 index 665804f6..00000000 Binary files a/branches/s100/Apps/crossdev/CPMNAME.CPM and /dev/null differ diff --git a/branches/s100/Apps/crossdev/CPMNAME.SUB b/branches/s100/Apps/crossdev/CPMNAME.SUB deleted file mode 100644 index adba240b..00000000 --- a/branches/s100/Apps/crossdev/CPMNAME.SUB +++ /dev/null @@ -1,20 +0,0 @@ -e:rem cpmname.sub 9/5/2012 dwg - build cpmname from sources -cc cpmname -as cpmname -cc cnamept1 -as cnamept1 -cc cnamept2 -as cnamept2 -cc cnamept3 -as cnamept3 -cc cnamept4 -as cnamept4 -as bdoscall -as bioscall -cc cmemory -as cmemory -cc ctermcap -as ctermcap -as diagnose -ln cpmname.o ctermcap.o cnamept1.o cnamept2.o cnamept3.o cnamept4.o cmemory.o diagnose.o bioscall.o bdoscall.o c.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CTERMCAP.C b/branches/s100/Apps/crossdev/CTERMCAP.C deleted file mode 100644 index 04baf9c4..00000000 --- a/branches/s100/Apps/crossdev/CTERMCAP.C +++ /dev/null @@ -1,99 +0,0 @@ -/* ctermcap.c 3/11/2012 dwg - terminal capbility file */ - -#include "stdio.h" -#include "stdlib.h" -#include "cpmbind.h" -#include "applvers.h" -#include "cnfgdata.h" -#include "syscfg.h" -#include "diagnose.h" - -char termtype; - - - -char wy50row[24] = { ' ', '!', '"', '#', '$', '%', '&', 39, - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7' }; - -char wy50col[80] = { ' ', '!', '"', '#', '$', '%', '&', 39, - '(', ')', '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', - 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', - 96, 'a', 'b', 'c', 'd', 'e', 'f', 'g', - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o' }; - - - -crtinit(tt) - char tt; -{ - termtype = tt; -} - -crtclr() -{ - int i; - - switch(termtype) { - case TERM_TTY: - for(i=0;i<43;i++) { - printf("%c%c",CR,LF); - } - break; - case TERM_ANSI: - printf("%c[2J",ESC); - break; - case TERM_WYSE: - printf("%c+",ESC); - break; - case TERM_VT52: - printf("%cJ%cH",ESC,ESC); - break; - }; -} - -crtlc(line,col) -int line; -int col; -{ - int i; - - switch(termtype) { - case TERM_TTY: - break; - case TERM_ANSI: - printf("%c[%d;%d%c",ESC,line,col,0x66); - break; - case TERM_WYSE: - printf("%c=%c%c",ESC,wy50row[line-1],wy50col[col-1]); - break; - case TERM_VT52: - printf("%cY%c%c",ESC,' '+line,' '+col); - break; - }; -} - -/* - -wy50row db ' !"#$%&' - db 39 - db '()*+,-./01234567' - -wy50col db ' !"#$%&' - db 39 - db '()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' - db 96 - db 'abcdefghijklmno' - -*/ - - -/********************/ -/* eof - ctermcap.c */ -/********************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CTERMCAP.H b/branches/s100/Apps/crossdev/CTERMCAP.H deleted file mode 100644 index ed706792..00000000 --- a/branches/s100/Apps/crossdev/CTERMCAP.H +++ /dev/null @@ -1,6 +0,0 @@ -/* ctermcap.h 3/11/2012 dwg - declarations for termal capability */ - -extern crtinit(); /* void crtinit(char termtype); */ -extern crtclr(); /* void crtclr(void); */ -extern crtlc(); /* void crtlc(char line,char column); */ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/CVT2H.C b/branches/s100/Apps/crossdev/CVT2H.C deleted file mode 100644 index 0ecdc136..00000000 --- a/branches/s100/Apps/crossdev/CVT2H.C +++ /dev/null @@ -1,45 +0,0 @@ -/* cvt2h.h 7/11/2012 dwg - Copyright (C) 2012 Douglas Goodall */ - -/* This is an include file for a function which takes a pointer, - a length, and a filename, and converts a buffer into a C - header file that can be later incuded in some other compilation. */ - -#include "stdio.h" -#include "visible.h" - -cvt2h(buffer,length,name) - unsigned char * buffer; - int length; - char * name; -{ - FILE * fd; - int i,j,k,l; - char szTemp[32]; - fd = fopen(name,"w"); - fprintf(fd, - "/* %s produced automatically by cvt2h.h */\n",name); - strcpy(szTemp,name); - szTemp[8] = 0; - fprintf(fd, - "unsigned char %s[%d] = {\n\t", - szTemp,length); - for(i=0;i> 8; - device = devunit & 0xf0; - unit = devunit & 0x0f; - if(DEV_FD == device) { - gFDNums[gNumFD] = drive; - gbFD[gNumFD++] = iregbc & 0xff; - } - drive++; - } -} - - -int main(argc,argv) - int argc; - char *argv[] ; -{ - char drive; - int fd0,fd1; - int i; - int spt; - int track; - int tracks; - int bValid; - - sensefd(); - - if(2 != gNumFD) { - printf("Sorry, this version of diskcopy only supports dual drives"); - exit(FAILURE); - } - printf("The copy will be from drive %c: to drive %c:\n", - gFDNums[0]+'A',gFDNums[1]+'A'); - - printf("The media in FD0 is "); - fd0 = diomed(DEV_FD); - switch(fd0) { - case MID_NONE: - printf("Drive is empty"); - break; - case MID_MDROM: - printf("a memory ROM drive"); - break; - case MID_MDRAM: - printf("a memory RAM drive"); - break; - case MID_HD: - printf("an HD drive"); - break; - case MID_FD720: - printf("a 720KB floppy disk"); - tracks = 80 * 2; - break; - case MID_FD144: - printf("a 1.44MB floppy disk"); - tracks = 80 * 2; - break; - case MID_FD360: - printf("a 360KB floppy disk"); - tracks = 40 * 2; - break; - case MID_FD120: - printf("a 120KB floppy disk"); - tracks = 80 * 2; - break; - case MID_FD111: - printf("a 111KB floppy disk"); - tracks = 74 * 2; - break; - default: - printf("an unknown media type"); - break; - } - printf("\n"); - - - - printf("The media in FD1 is "); - fd1 = diomed(DEV_FD+1); - switch(fd1) { - case MID_NONE: - printf("Drive is empty"); - break; - case MID_MDROM: - printf("a memory ROM drive"); - break; - case MID_MDRAM: - printf("a memory RAM drive"); - break; - case MID_HD: - printf("an HD drive"); - break; - case MID_FD720: - printf("a 720KB floppy disk"); - break; - case MID_FD144: - printf("a 1.44MB floppy disk"); - break; - case MID_FD360: - printf("a 360KB floppy disk"); - break; - case MID_FD120: - printf("a 120KB floppy disk"); - break; - case MID_FD111: - printf("a 111KB floppy disk"); - break; - default: - printf("an unknown media type"); - break; - } - printf("\n"); - - if(fd0 != fd1) { - printf("Sorry, media types don't match, as required for diskcopy"); - exit(1); - } - - for(track=0;trackdpb; - spt = pDPB->spt; - ireghl = pSETTRK; - iregbc = track; - bioscall(); - printf("%3d ",track); - rdtrack(0,spt,buffer); - printf("%c",0x0d); - - bValid = FALSE; - for(i=0;idpb; - spt = pDPB->spt; - ireghl = pSETTRK; - iregbc = track; /* Track 0 */ - bioscall(); - printf("%3d ",track); - wrtrack(0,spt,buffer); - printf("%c",0x0d); - - } - - } -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/DOIT.C b/branches/s100/Apps/crossdev/DOIT.C deleted file mode 100644 index 80af4737..00000000 --- a/branches/s100/Apps/crossdev/DOIT.C +++ /dev/null @@ -1,12 +0,0 @@ -#include "stdio.h" - -main() -{ - FILE * fd; - fd = fopen("$$$.SUB","w"); - fprintf(fd,"%ca:getcfg\n",9); - fprintf(fd,"%ca:dump syscfg.bin\n",18); - fprintf(fd,"%ctype a:sect0000.h\n",17); - fclose(fd); -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/DPHDPB.H b/branches/s100/Apps/crossdev/DPHDPB.H deleted file mode 100644 index 01e69831..00000000 --- a/branches/s100/Apps/crossdev/DPHDPB.H +++ /dev/null @@ -1,30 +0,0 @@ - -struct DPH { - unsigned int xlt; - unsigned int rv1; - unsigned int rv2; - unsigned int rv3; - unsigned int dbf; - void * dpb; - void * csv; - void * alv; - /* extension */ - unsigned char sigl; - unsigned char sigu; - unsigned int current; - unsigned int number; -}; - -struct DPB { - unsigned int spt; - unsigned char bsh; - unsigned char blm; - unsigned char exm; - unsigned int dsm; - unsigned int drm; - unsigned char al0; - unsigned char al1; - unsigned int cks; - unsigned int off; -}; - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/DPHMAP.H b/branches/s100/Apps/crossdev/DPHMAP.H deleted file mode 100644 index 1fe765b4..00000000 --- a/branches/s100/Apps/crossdev/DPHMAP.H +++ /dev/null @@ -1,25 +0,0 @@ -/* dphmap.h 9/4/2012 dwg - expand to include I through L */ -/* dphmap.h 5/29/2012 dwg - declaration of DPH MAP structure */ - -struct DPHMAP { - struct DPH * drivea; - struct DPH * driveb; - struct DPH * drivec; - struct DPH * drived; - struct DPH * drivee; - struct DPH * drivef; - struct DPH * driveg; - struct DPH * driveh; - - struct DPH * drivei; - struct DPH * drivej; - struct DPH * drivek; - struct DPH * drivel; -} * pDPHMAP; - -struct DPHMAP * pDPHVEC[MAXDRIVE]; - - -/******************/ -/* eof - dphmap.h */ -/******************/ \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/DUMP.ASM b/branches/s100/Apps/crossdev/DUMP.ASM deleted file mode 100644 index 42fab378..00000000 --- a/branches/s100/Apps/crossdev/DUMP.ASM +++ /dev/null @@ -1,1494 +0,0 @@ - extrn .begin,.chl,.swt - extrn csave,cret,.move - DSEG - public visible_ -visible_: - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 1 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - DB 0 - CSEG - PUBLIC cvt2h_ -cvt2h_: lxi d,.2 - call csave - LXI H,.1+0 - PUSH H - LXI H,14-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fopen_ - POP D - POP D - XCHG - LXI H,2-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,12-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.1+2 - PUSH H - LXI H,6-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,12-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,-36-.2 - DAD SP - PUSH H - CALL strcpy_ - POP D - POP D - LXI H,0 - XCHG - LXI H,-30-.2 - DAD SP - MOV M,E - LXI H,10-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,-36-.2 - DAD SP - PUSH H - LXI H,.1+46 - PUSH H - LXI H,8-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - XCHG - LXI H,8 - DAD SP - SPHL - LXI H,0 - XCHG - LXI H,0-.2 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .4 -.3: - LXI H,0-.2 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.4: - LXI H,0-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,10-.2 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .lt - JZ .5 - LXI H,8-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,0-.2 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+73 - PUSH H - LXI H,6-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,0-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,7 - CALL .an - PUSH H - LXI H,7 - POP D - CALL .eq - JZ .6 - LXI H,.1+81 - PUSH H - LXI H,4-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - LXI H,0-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-8 - CALL .an - XCHG - LXI H,-2-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,8 - DAD D - XCHG - LXI H,-4-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.1+86 - PUSH H - LXI H,6-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,-2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-6-.2 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .8 -.7: - LXI H,-6-.2 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.8: - LXI H,-6-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-4-.2 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .lt - JZ .9 - LXI H,8-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-6-.2 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - MOV E,M - MVI D,0 - LXI H,visible_ - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,1 - POP D - CALL .eq - JZ .10 - LXI H,8-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-6-.2 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+94 - PUSH H - LXI H,6-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - JMP .11 -.10: - LXI H,.1+98 - PUSH H - LXI H,4-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D -.11: - JMP .7 -.9: - LXI H,.1+101 - PUSH H - LXI H,4-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - LXI H,.1+104 - PUSH H - LXI H,4-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D -.6: - JMP .3 -.5: - LXI H,12-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.1+107 - PUSH H - LXI H,6-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fclose_ - POP D - RET -.2 EQU -42 -.1: - DB 119,0,47,42,32,37,115,32,112,114,111,100,117,99,101 - DB 100,32,97,117,116,111,109,97,116,105,99,97,108,108,121 - DB 32,98,121,32,99,118,116,50,104,46,104,32,42,47,10 - DB 0,117,110,115,105,103,110,101,100,32,99,104,97,114,32 - DB 37,115,91,37,100,93,32,61,32,123,10,9,0,48,120 - DB 37,48,50,120,44,0,32,47,42,32,0,32,37,48,52 - DB 120,58,32,0,37,99,32,0,46,32,0,42,47,0,10 - DB 9,0,125,59,10,47,42,32,101,111,102,32,45,32,37 - DB 115,32,42,47,10,0 - PUBLIC cvt2inc_ -cvt2inc_: lxi d,.13 - call csave - LXI H,.12+0 - PUSH H - LXI H,14-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fopen_ - POP D - POP D - XCHG - LXI H,2-.13 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,12-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.12+2 - PUSH H - LXI H,6-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,12-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,-36-.13 - DAD SP - PUSH H - CALL strcpy_ - POP D - POP D - LXI H,0 - XCHG - LXI H,-30-.13 - DAD SP - MOV M,E - LXI H,-38-.13 - DAD SP - PUSH H - LXI H,.12+45 - PUSH H - LXI H,6-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,.12+50 - PUSH H - LXI H,4-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - LXI H,0 - XCHG - LXI H,0-.13 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,0 - XCHG - LXI H,0-.13 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .15 -.14: - LXI H,0-.13 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.15: - LXI H,0-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,10-.13 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .lt - JZ .16 - LXI H,8-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,0-.13 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.12+58 - PUSH H - LXI H,6-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,0-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,7 - CALL .an - PUSH H - LXI H,7 - POP D - CALL .eq - JZ .17 - LXI H,.12+64 - PUSH H - LXI H,4-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - LXI H,0-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-8 - CALL .an - XCHG - LXI H,-2-.13 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-2-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,8 - DAD D - XCHG - LXI H,-4-.13 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-2-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.12+69 - PUSH H - LXI H,6-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - LXI H,-2-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-6-.13 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .19 -.18: - LXI H,-6-.13 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.19: - LXI H,-6-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-4-.13 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .lt - JZ .20 - LXI H,8-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-6-.13 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - MOV E,M - MVI D,0 - LXI H,visible_ - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,1 - POP D - CALL .eq - JZ .21 - LXI H,8-.13 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,-6-.13 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.12+77 - PUSH H - LXI H,6-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - POP D - JMP .22 -.21: - LXI H,.12+81 - PUSH H - LXI H,4-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D -.22: - JMP .18 -.20: - LXI H,10-.13 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - DCX H - PUSH H - LXI H,2-.13 - DAD SP - MOV E,M - INX H - MOV D,M - POP H - CALL .ne - JZ .23 - LXI H,.12+84 - PUSH H - LXI H,4-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D -.23: - JMP .24 -.17: - LXI H,.12+93 - PUSH H - LXI H,4-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D -.24: - JMP .14 -.16: - LXI H,.12+95 - PUSH H - LXI H,4-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fprintf_ - POP D - POP D - LXI H,2-.13 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fclose_ - POP D - RET -.13 EQU -42 -.12: - DB 119,0,59,32,37,115,32,112,114,111,100,117,99,101,100 - DB 32,97,117,116,111,109,97,116,105,99,97,108,108,121,32 - DB 98,121,32,99,118,116,50,105,110,99,46,104,32,10,0 - DB 37,115,58,10,0,32,32,46,68,66,32,32,0,37,48 - DB 51,120,104,0,32,32,59,32,0,32,37,48,52,120,58 - DB 32,0,37,99,32,0,46,32,0,10,32,32,46,68,66 - DB 32,32,0,44,0,10,0 - PUBLIC main_ -main_: lxi d,.26 - call csave - LXI H,.25+0 - PUSH H - CALL banner_ - POP D - LXI H,1 - XCHG - LXI H,8-.26 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .eq - JZ .27 - LXI H,.25+9 - PUSH H - CALL printf_ - POP D - LXI H,1 - PUSH H - CALL exit_ - POP D -.27: - LXI H,.25+40 - PUSH H - LXI H,12-.26 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - INX H - INX H - MOV E,M - INX H - MOV D,M - PUSH D - CALL fopen_ - POP D - POP D - XCHG - LXI H,-167-.26 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-167-.26 - DAD SP - mov a,m - inx h - ora m - JNZ .28 - LXI H,.25+42 - PUSH H - CALL printf_ - POP D - LXI H,1 - PUSH H - CALL exit_ - POP D -.28: - LXI H,10-.26 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - INX H - INX H - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.25+72 - PUSH H - CALL printf_ - POP D - POP D - LXI H,0 - XCHG - LXI H,-2-.26 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-167-.26 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,1 - PUSH H - LXI H,128 - PUSH H - LXI H,-127-.26 - DAD SP - PUSH H - CALL fread_ - XCHG - LXI H,8 - DAD SP - SPHL - LXI H,-4-.26 - DAD SP - MOV M,E - INX H - MOV M,D -.29: - LXI H,0 - XCHG - LXI H,-4-.26 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .lt - JZ .30 - LXI H,-2-.26 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.25+85 - PUSH H - LXI H,-161-.26 - DAD SP - PUSH H - CALL sprintf_ - POP D - POP D - POP D - LXI H,-165-.26 - DAD SP - PUSH H - LXI H,128 - PUSH H - LXI H,-129-.26 - DAD SP - PUSH H - CALL cvt2h_ - POP D - POP D - POP D - LXI H,-2-.26 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.25+96 - PUSH H - LXI H,-161-.26 - DAD SP - PUSH H - CALL sprintf_ - POP D - POP D - POP D - LXI H,-165-.26 - DAD SP - PUSH H - LXI H,128 - PUSH H - LXI H,-129-.26 - DAD SP - PUSH H - CALL cvt2inc_ - POP D - POP D - POP D - LXI H,0 - XCHG - LXI H,2-.26 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .32 -.31: - LXI H,2-.26 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.32: - LXI H,2-.26 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,8 - CALL .lt - JZ .33 - LXI H,-2-.26 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.25+109 - PUSH H - CALL printf_ - POP D - POP D - LXI H,16 - XCHG - LXI H,-2-.26 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - XCHG - POP H - MOV M,E - INX H - MOV M,D - LXI H,0 - XCHG - LXI H,0-.26 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .35 -.34: - LXI H,0-.26 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.35: - LXI H,0-.26 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,16 - CALL .lt - JZ .36 - LXI H,2-.26 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - DAD H - DAD H - DAD H - XCHG - LXI H,0-.26 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - XCHG - LXI H,-133-.26 - DAD SP - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.25+116 - PUSH H - CALL printf_ - POP D - POP D - JMP .34 -.36: - LXI H,.25+122 - PUSH H - CALL printf_ - POP D - LXI H,0 - XCHG - LXI H,0-.26 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .38 -.37: - LXI H,0-.26 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.38: - LXI H,0-.26 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,16 - CALL .lt - JZ .39 - LXI H,2-.26 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - DAD H - DAD H - DAD H - XCHG - LXI H,0-.26 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - DAD D - XCHG - LXI H,-133-.26 - DAD SP - DAD D - MOV E,M - LXI H,-5-.26 - DAD SP - MOV M,E - LXI H,-5-.26 - DAD SP - MOV E,M - MVI D,0 - LXI H,visible_ - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,1 - POP D - CALL .eq - JZ .40 - LXI H,-5-.26 - DAD SP - MOV E,M - MVI D,0 - PUSH D - LXI H,.25+125 - PUSH H - CALL printf_ - POP D - POP D - JMP .41 -.40: - LXI H,.25+128 - PUSH H - CALL printf_ - POP D -.41: - JMP .37 -.39: - LXI H,.25+130 - PUSH H - CALL printf_ - POP D - JMP .31 -.33: - LXI H,.25+132 - PUSH H - CALL printf_ - POP D - LXI H,-167-.26 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,1 - PUSH H - LXI H,128 - PUSH H - LXI H,-127-.26 - DAD SP - PUSH H - CALL fread_ - XCHG - LXI H,8 - DAD SP - SPHL - LXI H,-4-.26 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .29 -.30: - LXI H,-167-.26 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fclose_ - POP D - LXI H,0 - PUSH H - CALL exit_ - POP D - RET -.26 EQU -171 -.25: - DB 68,85,77,80,46,67,79,77,0,83,111,114,114,121,44 - DB 32,110,111,32,105,110,112,117,116,32,102,105,108,101,32 - DB 115,112,101,99,105,102,105,101,100,0,114,0,83,111,114 - DB 114,121,44,32,99,97,110,110,111,116,32,111,112,101,110 - DB 32,105,110,112,117,116,32,102,105,108,101,0,68,117,109 - DB 112,105,110,103,32,37,115,10,10,0,115,101,99,116,37 - DB 48,52,120,46,104,0,115,101,99,116,37,48,52,120,46 - DB 105,110,99,0,37,48,52,120,58,32,0,37,48,50,120 - DB 32,0,32,32,0,37,99,0,46,0,10,0,10,0 - extrn sprintf_ - extrn fread_ - extrn exit_ - extrn printf_ - extrn banner_ - extrn fclose_ - extrn strcpy_ - extrn fprintf_ - extrn fopen_ - extrn .an - extrn .eq - extrn .ne - extrn .lt - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/DUMP.C b/branches/s100/Apps/crossdev/DUMP.C deleted file mode 100644 index 77655006..00000000 --- a/branches/s100/Apps/crossdev/DUMP.C +++ /dev/null @@ -1,101 +0,0 @@ -/* dump.c 7/11/2012 dwg - - - The purpose of this program is similar to the CP/M dump program - except that in addition to the normal hexadecimal bytes, a field - of ascii bytes to the right are displayed as well. - -*/ - -#include "stdio.h" - - -char visible[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 10 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 20 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 30 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 40 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 50 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 60 */ - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0, /* 70 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 80 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* A0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* B0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* C0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* D0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* E0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* F0 */ -}; - -#include "cvt2h.h" -#include "cvt2inc.h" - -main(argc,argv) - int argc; - char *argv[]; -{ - int i,j; - int offset; - int result; - unsigned char byte; - unsigned char sector[128]; - char name[32]; - - - FILE * fd; - - banner("DUMP.COM"); - -/* cvt2h(0x0100,12*1024,"dumpcomh.h"); */ - - - if(1 == argc) { - printf("Sorry, no input file specified"); - exit(1); - } - - fd = fopen(argv[1],"r"); - if(NULL == fd) { - printf("Sorry, cannot open input file"); - exit(1); - } - - printf("Dumping %s\n\n",argv[1]); - - offset = 0; - result = fread(sector,sizeof(sector),1,fd); - while(0 < result) { - - sprintf(name,"sect%04x.h",offset); - cvt2h(sector,sizeof(sector),name); - sprintf(name,"sect%04x.inc",offset); - cvt2inc(sector,sizeof(sector),name); - - for(i=0;i<8;i++) { - printf("%04x: ",offset); - - - offset += 16; - for(j=0;j<16;j++) { - printf("%02x ",sector[(i*8)+j]); - } - printf(" "); - for(j=0;j<16;j++) { - byte = sector[(i*8)+j]; - if(1 == visible[byte]) { - printf("%c",byte); - } else { - printf("."); - } - } - printf("\n"); - } - printf("\n"); - result = fread(sector,sizeof(sector),1,fd); - } - fclose(fd); - - exit(0); -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/DUMPCOM.H b/branches/s100/Apps/crossdev/DUMPCOM.H deleted file mode 100644 index 688a57ba..00000000 --- a/branches/s100/Apps/crossdev/DUMPCOM.H +++ /dev/null @@ -1,1542 +0,0 @@ -/* dumpcom.h produced automatically by cvt2h.h Do Not Edit */ - -unsigned char dumpcom.[12288] = { - 0xc3, 0xe4, 0x12, 0x11, 0xdc, 0xff, 0xcd, 0xbe, - 0x26, 0x21, 0x1b, 0x02, 0xe5, 0x21, 0x32, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x40, 0x0d, - 0xd1, 0xd1, 0xeb, 0x21, 0x26, 0x00, 0x39, 0x73, - 0x23, 0x72, 0x21, 0x30, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0xd5, 0x21, 0x1d, 0x02, 0xe5, 0x21, 0x2a, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0xe1, - 0x07, 0xd1, 0xd1, 0xd1, 0x21, 0x30, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x06, 0x00, 0x39, - 0xe5, 0xcd, 0xbc, 0x25, 0xd1, 0xd1, 0x21, 0x00, - 0x00, 0xeb, 0x21, 0x0c, 0x00, 0x39, 0x73, 0x21, - 0x2e, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x06, 0x00, 0x39, 0xe5, 0x21, 0x56, 0x02, 0xe5, - 0x21, 0x2c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, - 0xcd, 0xe1, 0x07, 0xeb, 0x21, 0x08, 0x00, 0x39, - 0xf9, 0x21, 0x00, 0x00, 0xeb, 0x21, 0x24, 0x00, - 0x39, 0x73, 0x23, 0x72, 0xc3, 0x96, 0x01, 0x21, - 0x24, 0x00, 0x39, 0xe5, 0x7e, 0x23, 0x66, 0x6f, - 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0x21, 0x24, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x2e, 0x00, - 0x39, 0x7e, 0x23, 0x66, 0x6f, 0xcd, 0xc6, 0x27, - 0xca, 0xfd, 0x01, 0x21, 0x2c, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0x21, 0x24, 0x00, 0x39, 0x7e, 0x23, - 0x66, 0x6f, 0x19, 0x5e, 0x16, 0x00, 0xd5, 0x21, - 0x71, 0x02, 0xe5, 0x21, 0x2a, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0xd5, 0xcd, 0xe1, 0x07, 0xd1, 0xd1, - 0xd1, 0x21, 0x24, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0x21, 0x07, 0x00, 0xcd, 0x64, 0x27, 0xe5, 0x21, - 0x07, 0x00, 0xd1, 0xcd, 0x8c, 0x27, 0xca, 0xfa, - 0x01, 0x21, 0x7a, 0x02, 0xe5, 0x21, 0x28, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0xe1, 0x07, - 0xd1, 0xd1, 0xc3, 0x87, 0x01, 0x21, 0x7d, 0x02, - 0xe5, 0x21, 0x28, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xd5, 0xcd, 0xe1, 0x07, 0xd1, 0xd1, 0x21, 0x26, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x3a, - 0x10, 0xd1, 0xc9, 0x77, 0x00, 0x2f, 0x2a, 0x20, - 0x25, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x65, 0x64, 0x20, 0x61, 0x75, 0x74, 0x6f, - 0x6d, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x6c, - 0x79, 0x20, 0x62, 0x79, 0x20, 0x63, 0x76, 0x74, - 0x32, 0x68, 0x2e, 0x68, 0x20, 0x44, 0x6f, 0x20, - 0x4e, 0x6f, 0x74, 0x20, 0x45, 0x64, 0x69, 0x74, - 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x00, 0x75, 0x6e, - 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x63, - 0x68, 0x61, 0x72, 0x20, 0x25, 0x73, 0x5b, 0x25, - 0x64, 0x5d, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, - 0x00, 0x30, 0x78, 0x25, 0x30, 0x32, 0x78, 0x2c, - 0x20, 0x00, 0x0a, 0x09, 0x00, 0x0a, 0x7d, 0x3b, - 0x0a, 0x00, 0x11, 0x55, 0xff, 0xcd, 0xbe, 0x26, - 0x21, 0x08, 0x05, 0xe5, 0xcd, 0xd3, 0x06, 0xd1, - 0x21, 0x11, 0x05, 0xe5, 0x21, 0x00, 0x30, 0xe5, - 0x21, 0x00, 0x01, 0xe5, 0xcd, 0x03, 0x01, 0xd1, - 0xd1, 0xd1, 0x21, 0x01, 0x00, 0xeb, 0x21, 0xb3, - 0x00, 0x39, 0x7e, 0x23, 0x66, 0x6f, 0xcd, 0x8c, - 0x27, 0xca, 0xc4, 0x02, 0x21, 0x1b, 0x05, 0xe5, - 0xcd, 0xc3, 0x07, 0xd1, 0x21, 0x01, 0x00, 0xe5, - 0xcd, 0x22, 0x15, 0xd1, 0x21, 0x3a, 0x05, 0xe5, - 0x21, 0xb7, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, - 0x23, 0x23, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x40, - 0x0d, 0xd1, 0xd1, 0xeb, 0x21, 0x04, 0x00, 0x39, - 0x73, 0x23, 0x72, 0x21, 0x04, 0x00, 0x39, 0x7e, - 0x23, 0xb6, 0xc2, 0xfd, 0x02, 0x21, 0x3c, 0x05, - 0xe5, 0xcd, 0xc3, 0x07, 0xd1, 0x21, 0x01, 0x00, - 0xe5, 0xcd, 0x22, 0x15, 0xd1, 0x21, 0xb5, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xeb, 0x23, 0x23, 0x5e, - 0x23, 0x56, 0xd5, 0x21, 0x5a, 0x05, 0xe5, 0xcd, - 0xc3, 0x07, 0xd1, 0xd1, 0x21, 0x00, 0x00, 0xeb, - 0x21, 0xa9, 0x00, 0x39, 0x73, 0x23, 0x72, 0x21, - 0x04, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x01, 0x00, 0xe5, 0x21, 0x80, 0x00, 0xe5, 0x21, - 0x2c, 0x00, 0x39, 0xe5, 0xcd, 0x01, 0x0e, 0xeb, - 0x21, 0x08, 0x00, 0x39, 0xf9, 0x21, 0xa7, 0x00, - 0x39, 0x73, 0x23, 0x72, 0x21, 0x00, 0x00, 0xeb, - 0x21, 0xa7, 0x00, 0x39, 0x7e, 0x23, 0x66, 0x6f, - 0xcd, 0xc6, 0x27, 0xca, 0xf3, 0x04, 0x21, 0xa9, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x67, - 0x05, 0xe5, 0x21, 0x0a, 0x00, 0x39, 0xe5, 0xcd, - 0x22, 0x08, 0xd1, 0xd1, 0xd1, 0x21, 0x06, 0x00, - 0x39, 0xe5, 0x21, 0x80, 0x00, 0xe5, 0x21, 0x2a, - 0x00, 0x39, 0xe5, 0xcd, 0x03, 0x01, 0xd1, 0xd1, - 0xd1, 0x21, 0x00, 0x00, 0xeb, 0x21, 0xad, 0x00, - 0x39, 0x73, 0x23, 0x72, 0xc3, 0x9e, 0x03, 0x21, - 0xad, 0x00, 0x39, 0xe5, 0x7e, 0x23, 0x66, 0x6f, - 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0x21, 0xad, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x08, 0x00, - 0xcd, 0xc6, 0x27, 0xca, 0xc3, 0x04, 0x21, 0xa9, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x72, - 0x05, 0xe5, 0xcd, 0xc3, 0x07, 0xd1, 0xd1, 0x21, - 0x10, 0x00, 0xeb, 0x21, 0xa9, 0x00, 0x39, 0xe5, - 0x7e, 0x23, 0x66, 0x6f, 0x19, 0xeb, 0xe1, 0x73, - 0x23, 0x72, 0x21, 0x00, 0x00, 0xeb, 0x21, 0xab, - 0x00, 0x39, 0x73, 0x23, 0x72, 0xc3, 0xef, 0x03, - 0x21, 0xab, 0x00, 0x39, 0xe5, 0x7e, 0x23, 0x66, - 0x6f, 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0x21, - 0xab, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x10, - 0x00, 0xcd, 0xc6, 0x27, 0xca, 0x2a, 0x04, 0x21, - 0xad, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0x29, - 0x29, 0x29, 0xeb, 0x21, 0xab, 0x00, 0x39, 0x7e, - 0x23, 0x66, 0x6f, 0x19, 0xeb, 0x21, 0x26, 0x00, - 0x39, 0x19, 0x5e, 0x16, 0x00, 0xd5, 0x21, 0x79, - 0x05, 0xe5, 0xcd, 0xc3, 0x07, 0xd1, 0xd1, 0xc3, - 0xe0, 0x03, 0x21, 0x7f, 0x05, 0xe5, 0xcd, 0xc3, - 0x07, 0xd1, 0x21, 0x00, 0x00, 0xeb, 0x21, 0xab, - 0x00, 0x39, 0x73, 0x23, 0x72, 0xc3, 0x4f, 0x04, - 0x21, 0xab, 0x00, 0x39, 0xe5, 0x7e, 0x23, 0x66, - 0x6f, 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0x21, - 0xab, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x10, - 0x00, 0xcd, 0xc6, 0x27, 0xca, 0xb8, 0x04, 0x21, - 0xad, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0x29, - 0x29, 0x29, 0xeb, 0x21, 0xab, 0x00, 0x39, 0x7e, - 0x23, 0x66, 0x6f, 0x19, 0xeb, 0x21, 0x26, 0x00, - 0x39, 0x19, 0x5e, 0x21, 0xa6, 0x00, 0x39, 0x73, - 0x21, 0xa6, 0x00, 0x39, 0x5e, 0x16, 0x00, 0x21, - 0x36, 0x28, 0x19, 0x5e, 0x16, 0x00, 0xd5, 0x21, - 0x01, 0x00, 0xd1, 0xcd, 0x8c, 0x27, 0xca, 0xad, - 0x04, 0x21, 0xa6, 0x00, 0x39, 0x5e, 0x16, 0x00, - 0xd5, 0x21, 0x82, 0x05, 0xe5, 0xcd, 0xc3, 0x07, - 0xd1, 0xd1, 0xc3, 0xb5, 0x04, 0x21, 0x85, 0x05, - 0xe5, 0xcd, 0xc3, 0x07, 0xd1, 0xc3, 0x40, 0x04, - 0x21, 0x87, 0x05, 0xe5, 0xcd, 0xc3, 0x07, 0xd1, - 0xc3, 0x8f, 0x03, 0x21, 0x89, 0x05, 0xe5, 0xcd, - 0xc3, 0x07, 0xd1, 0x21, 0x04, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0xd5, 0x21, 0x01, 0x00, 0xe5, 0x21, - 0x80, 0x00, 0xe5, 0x21, 0x2c, 0x00, 0x39, 0xe5, - 0xcd, 0x01, 0x0e, 0xeb, 0x21, 0x08, 0x00, 0x39, - 0xf9, 0x21, 0xa7, 0x00, 0x39, 0x73, 0x23, 0x72, - 0xc3, 0x44, 0x03, 0x21, 0x04, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0xd5, 0xcd, 0x3a, 0x10, 0xd1, 0x21, - 0x00, 0x00, 0xe5, 0xcd, 0x22, 0x15, 0xd1, 0xc9, - 0x44, 0x55, 0x4d, 0x50, 0x2e, 0x43, 0x4f, 0x4d, - 0x00, 0x64, 0x75, 0x6d, 0x70, 0x63, 0x6f, 0x6d, - 0x2e, 0x68, 0x00, 0x53, 0x6f, 0x72, 0x72, 0x79, - 0x2c, 0x20, 0x6e, 0x6f, 0x20, 0x69, 0x6e, 0x70, - 0x75, 0x74, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, - 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, - 0x64, 0x00, 0x72, 0x00, 0x53, 0x6f, 0x72, 0x72, - 0x79, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, - 0x74, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x20, 0x66, 0x69, 0x6c, - 0x65, 0x00, 0x44, 0x75, 0x6d, 0x70, 0x69, 0x6e, - 0x67, 0x20, 0x25, 0x73, 0x0a, 0x0a, 0x00, 0x73, - 0x65, 0x63, 0x74, 0x25, 0x30, 0x34, 0x78, 0x2e, - 0x68, 0x00, 0x25, 0x30, 0x34, 0x78, 0x3a, 0x20, - 0x00, 0x25, 0x30, 0x32, 0x78, 0x20, 0x00, 0x20, - 0x20, 0x00, 0x25, 0x63, 0x00, 0x2e, 0x00, 0x0a, - 0x00, 0x0a, 0x00, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x00, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x2e, 0x31, 0x32, 0x33, - 0x20, 0x6d, 0x6d, 0x2f, 0x64, 0x64, 0x2f, 0x79, - 0x79, 0x79, 0x79, 0x20, 0x20, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x78, 0x2e, 0x78, - 0x2e, 0x78, 0x2e, 0x78, 0x00, 0x53, 0x2f, 0x4e, - 0x20, 0x43, 0x50, 0x4d, 0x38, 0x30, 0x2d, 0x44, - 0x57, 0x47, 0x2d, 0x36, 0x35, 0x34, 0x33, 0x32, - 0x31, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, - 0x65, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, - 0x20, 0x47, 0x50, 0x4c, 0x33, 0x00, 0x43, 0x6f, - 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, - 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x31, 0x31, - 0x2d, 0x31, 0x32, 0x20, 0x44, 0x6f, 0x75, 0x67, - 0x6c, 0x61, 0x73, 0x20, 0x57, 0x2e, 0x20, 0x47, - 0x6f, 0x6f, 0x64, 0x61, 0x6c, 0x6c, 0x00, 0x11, - 0x80, 0xff, 0xcd, 0xbe, 0x26, 0x21, 0x88, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x85, 0x06, - 0xe5, 0xcd, 0xc3, 0x07, 0xd1, 0xd1, 0x21, 0xdc, - 0x07, 0xe5, 0x21, 0x07, 0x00, 0xe5, 0x21, 0x07, - 0x00, 0xe5, 0x21, 0x89, 0x06, 0xe5, 0xcd, 0xc3, - 0x07, 0xeb, 0x21, 0x08, 0x00, 0x39, 0xf9, 0x21, - 0x00, 0x00, 0xe5, 0x21, 0x00, 0x00, 0xe5, 0x21, - 0x00, 0x00, 0xe5, 0x21, 0x02, 0x00, 0xe5, 0x21, - 0x97, 0x06, 0xe5, 0xcd, 0xc3, 0x07, 0xeb, 0x21, - 0x0a, 0x00, 0x39, 0xf9, 0x21, 0xac, 0x06, 0xe5, - 0xcd, 0xc3, 0x07, 0xd1, 0xc9, 0x25, 0x73, 0x20, - 0x00, 0x25, 0x32, 0x64, 0x2f, 0x25, 0x32, 0x64, - 0x2f, 0x25, 0x34, 0x64, 0x20, 0x20, 0x00, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x25, - 0x64, 0x2e, 0x25, 0x64, 0x2e, 0x25, 0x64, 0x2e, - 0x25, 0x64, 0x20, 0x00, 0x43, 0x4f, 0x50, 0x52, - 0x20, 0x44, 0x6f, 0x75, 0x67, 0x6c, 0x61, 0x73, - 0x20, 0x47, 0x6f, 0x6f, 0x64, 0x61, 0x6c, 0x6c, - 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x64, 0x20, 0x77, 0x2f, 0x47, 0x50, 0x4c, 0x76, - 0x33, 0x0a, 0x00, 0x11, 0x80, 0xff, 0xcd, 0xbe, - 0x26, 0x2a, 0x36, 0x29, 0xe5, 0x21, 0x8a, 0x07, - 0xe5, 0xcd, 0xc3, 0x07, 0xd1, 0xd1, 0x21, 0x88, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x06, - 0x00, 0x39, 0xe5, 0xcd, 0xbc, 0x25, 0xd1, 0xd1, - 0x21, 0x04, 0x00, 0x39, 0xe5, 0xcd, 0x15, 0x26, - 0xd1, 0xe5, 0x21, 0x0c, 0x00, 0xd1, 0xeb, 0xcd, - 0xc7, 0x27, 0xca, 0x1e, 0x07, 0x21, 0x8e, 0x07, - 0xe5, 0x21, 0x06, 0x00, 0x39, 0xe5, 0xcd, 0xd8, - 0x25, 0xd1, 0xd1, 0xc3, 0xf8, 0x06, 0x21, 0x04, - 0x00, 0x39, 0xe5, 0x21, 0x90, 0x07, 0xe5, 0xcd, - 0xc3, 0x07, 0xd1, 0xd1, 0x21, 0xdc, 0x07, 0xe5, - 0x21, 0x07, 0x00, 0xe5, 0x21, 0x07, 0x00, 0xe5, - 0x21, 0x94, 0x07, 0xe5, 0xcd, 0xc3, 0x07, 0xeb, - 0x21, 0x08, 0x00, 0x39, 0xf9, 0x21, 0x00, 0x00, - 0xe5, 0x21, 0x00, 0x00, 0xe5, 0x21, 0x00, 0x00, - 0xe5, 0x21, 0x02, 0x00, 0xe5, 0x21, 0xa2, 0x07, - 0xe5, 0xcd, 0xc3, 0x07, 0xeb, 0x21, 0x0a, 0x00, - 0x39, 0xf9, 0x2a, 0x3a, 0x29, 0xe5, 0x21, 0xb7, - 0x07, 0xe5, 0xcd, 0xc3, 0x07, 0xd1, 0xd1, 0x2a, - 0x3c, 0x29, 0xe5, 0x21, 0xbb, 0x07, 0xe5, 0xcd, - 0xc3, 0x07, 0xd1, 0xd1, 0x2a, 0x36, 0x29, 0xe5, - 0x21, 0xbf, 0x07, 0xe5, 0xcd, 0xc3, 0x07, 0xd1, - 0xd1, 0xc9, 0x25, 0x73, 0x0a, 0x00, 0x20, 0x00, - 0x25, 0x73, 0x20, 0x00, 0x25, 0x32, 0x64, 0x2f, - 0x25, 0x32, 0x64, 0x2f, 0x25, 0x34, 0x64, 0x20, - 0x20, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x20, 0x25, 0x64, 0x2e, 0x25, 0x64, 0x2e, - 0x25, 0x64, 0x2e, 0x25, 0x64, 0x0a, 0x00, 0x25, - 0x73, 0x0a, 0x00, 0x25, 0x73, 0x0a, 0x00, 0x25, - 0x73, 0x0a, 0x00, 0x11, 0x00, 0x00, 0xcd, 0xbe, - 0x26, 0x21, 0x0a, 0x00, 0x39, 0xe5, 0x21, 0x0a, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x59, - 0x0f, 0xe5, 0xcd, 0x79, 0x08, 0xd1, 0xd1, 0xd1, - 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, - 0x08, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0x22, - 0x64, 0x2b, 0x21, 0x0c, 0x00, 0x39, 0xe5, 0x21, - 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x0a, 0x08, 0xe5, 0xcd, 0x79, 0x08, 0xd1, 0xd1, - 0xd1, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x2a, 0x64, 0x2b, 0xe5, 0x21, 0x0a, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x71, 0x0f, 0xd1, - 0xd1, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x21, 0x08, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, - 0x22, 0x66, 0x2b, 0x21, 0x0c, 0x00, 0x39, 0xe5, - 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, - 0x21, 0x58, 0x08, 0xe5, 0xcd, 0x79, 0x08, 0xd1, - 0xd1, 0xd1, 0x44, 0x4d, 0x21, 0x00, 0x00, 0xe5, - 0x2a, 0x66, 0x2b, 0xd1, 0x73, 0x60, 0x69, 0xc9, - 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x08, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x2a, 0x66, - 0x2b, 0x23, 0x22, 0x66, 0x2b, 0x2b, 0xd1, 0x73, - 0x16, 0x00, 0x21, 0xff, 0x00, 0xcd, 0x64, 0x27, - 0xc9, 0x11, 0x38, 0xff, 0xcd, 0xbe, 0x26, 0x21, - 0xd0, 0x00, 0x39, 0x4e, 0x23, 0x46, 0x21, 0x00, - 0x00, 0x22, 0x6c, 0x2b, 0x21, 0xd4, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xeb, 0x22, 0x6a, 0x2b, 0x21, - 0xd2, 0x00, 0x39, 0xe5, 0x7e, 0x23, 0x66, 0x6f, - 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0xeb, 0x2b, - 0x5e, 0x16, 0x00, 0xeb, 0x22, 0x68, 0x2b, 0x7c, - 0xb5, 0xca, 0x88, 0x0c, 0x2a, 0x68, 0x2b, 0x11, - 0x25, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0x67, 0x0c, - 0x21, 0x00, 0x00, 0xeb, 0x21, 0x12, 0x00, 0x39, - 0x73, 0x21, 0x01, 0x00, 0x22, 0x6e, 0x2b, 0x21, - 0x20, 0x00, 0x22, 0x70, 0x2b, 0x21, 0x10, 0x27, - 0x22, 0x72, 0x2b, 0x21, 0xd2, 0x00, 0x39, 0xe5, - 0x7e, 0x23, 0x66, 0x6f, 0x23, 0xeb, 0xe1, 0x73, - 0x23, 0x72, 0xeb, 0x2b, 0x5e, 0x16, 0x00, 0xeb, - 0x22, 0x68, 0x2b, 0x11, 0x2d, 0x00, 0xcd, 0x8c, - 0x27, 0xca, 0x1a, 0x09, 0x21, 0x00, 0x00, 0x22, - 0x6e, 0x2b, 0x21, 0xd2, 0x00, 0x39, 0xe5, 0x7e, - 0x23, 0x66, 0x6f, 0x23, 0xeb, 0xe1, 0x73, 0x23, - 0x72, 0xeb, 0x2b, 0x5e, 0x16, 0x00, 0xeb, 0x22, - 0x68, 0x2b, 0x2a, 0x68, 0x2b, 0x11, 0x30, 0x00, - 0xcd, 0x8c, 0x27, 0xca, 0x44, 0x09, 0x21, 0x30, - 0x00, 0x22, 0x70, 0x2b, 0x21, 0xd2, 0x00, 0x39, - 0xe5, 0x7e, 0x23, 0x66, 0x6f, 0x23, 0xeb, 0xe1, - 0x73, 0x23, 0x72, 0xeb, 0x2b, 0x5e, 0x16, 0x00, - 0xeb, 0x22, 0x68, 0x2b, 0x2a, 0x68, 0x2b, 0x11, - 0x2a, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0x7c, 0x09, - 0x2a, 0x6a, 0x2b, 0x23, 0x23, 0x22, 0x6a, 0x2b, - 0x2b, 0x2b, 0x5e, 0x23, 0x56, 0xeb, 0x22, 0x74, - 0x2b, 0x21, 0xd2, 0x00, 0x39, 0xe5, 0x7e, 0x23, - 0x66, 0x6f, 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, - 0xeb, 0x2b, 0x5e, 0x16, 0x00, 0xeb, 0x22, 0x68, - 0x2b, 0xc3, 0xc9, 0x09, 0x21, 0x00, 0x00, 0x22, - 0x74, 0x2b, 0xc3, 0x9d, 0x09, 0x21, 0xd2, 0x00, - 0x39, 0xe5, 0x7e, 0x23, 0x66, 0x6f, 0x23, 0xeb, - 0xe1, 0x73, 0x23, 0x72, 0xeb, 0x2b, 0x5e, 0x16, - 0x00, 0xeb, 0x22, 0x68, 0x2b, 0x2a, 0x68, 0x2b, - 0x11, 0xdc, 0x2a, 0x19, 0x23, 0x5e, 0x16, 0x00, - 0x21, 0x04, 0x00, 0xcd, 0x64, 0x27, 0xca, 0xc9, - 0x09, 0x2a, 0x74, 0x2b, 0x11, 0x0a, 0x00, 0xcd, - 0x0d, 0x27, 0xeb, 0x2a, 0x68, 0x2b, 0x19, 0x11, - 0xd0, 0xff, 0x19, 0x22, 0x74, 0x2b, 0xc3, 0x85, - 0x09, 0x2a, 0x68, 0x2b, 0x11, 0x2e, 0x00, 0xcd, - 0x8c, 0x27, 0xca, 0x6f, 0x0a, 0x21, 0xd2, 0x00, - 0x39, 0xe5, 0x7e, 0x23, 0x66, 0x6f, 0x23, 0xeb, - 0xe1, 0x73, 0x23, 0x72, 0xeb, 0x2b, 0x5e, 0x16, - 0x00, 0xeb, 0x22, 0x68, 0x2b, 0x11, 0x2a, 0x00, - 0xcd, 0x8c, 0x27, 0xca, 0x22, 0x0a, 0x2a, 0x6a, - 0x2b, 0x23, 0x23, 0x22, 0x6a, 0x2b, 0x2b, 0x2b, - 0x5e, 0x23, 0x56, 0xeb, 0x22, 0x72, 0x2b, 0x21, - 0xd2, 0x00, 0x39, 0xe5, 0x7e, 0x23, 0x66, 0x6f, - 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0xeb, 0x2b, - 0x5e, 0x16, 0x00, 0xeb, 0x22, 0x68, 0x2b, 0xc3, - 0x6f, 0x0a, 0x21, 0x00, 0x00, 0x22, 0x72, 0x2b, - 0xc3, 0x43, 0x0a, 0x21, 0xd2, 0x00, 0x39, 0xe5, - 0x7e, 0x23, 0x66, 0x6f, 0x23, 0xeb, 0xe1, 0x73, - 0x23, 0x72, 0xeb, 0x2b, 0x5e, 0x16, 0x00, 0xeb, - 0x22, 0x68, 0x2b, 0x2a, 0x68, 0x2b, 0x11, 0xdc, - 0x2a, 0x19, 0x23, 0x5e, 0x16, 0x00, 0x21, 0x04, - 0x00, 0xcd, 0x64, 0x27, 0xca, 0x6f, 0x0a, 0x2a, - 0x72, 0x2b, 0x11, 0x0a, 0x00, 0xcd, 0x0d, 0x27, - 0xeb, 0x2a, 0x68, 0x2b, 0x19, 0x11, 0xd0, 0xff, - 0x19, 0x22, 0x72, 0x2b, 0xc3, 0x2b, 0x0a, 0x21, - 0x02, 0x00, 0x22, 0x76, 0x2b, 0x2a, 0x68, 0x2b, - 0x11, 0x6c, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0xa2, - 0x0a, 0x21, 0xd2, 0x00, 0x39, 0xe5, 0x7e, 0x23, - 0x66, 0x6f, 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, - 0xeb, 0x2b, 0x5e, 0x16, 0x00, 0xeb, 0x22, 0x68, - 0x2b, 0x21, 0x04, 0x00, 0x22, 0x76, 0x2b, 0xc3, - 0xc6, 0x0a, 0x2a, 0x68, 0x2b, 0x11, 0x68, 0x00, - 0xcd, 0x8c, 0x27, 0xca, 0xc6, 0x0a, 0x21, 0xd2, - 0x00, 0x39, 0xe5, 0x7e, 0x23, 0x66, 0x6f, 0x23, - 0xeb, 0xe1, 0x73, 0x23, 0x72, 0xeb, 0x2b, 0x5e, - 0x16, 0x00, 0xeb, 0x22, 0x68, 0x2b, 0x2a, 0x68, - 0x2b, 0xc3, 0x56, 0x0b, 0x21, 0x08, 0x00, 0x22, - 0x78, 0x2b, 0xc3, 0xed, 0x0a, 0x21, 0x0a, 0x00, - 0x22, 0x78, 0x2b, 0xc3, 0xed, 0x0a, 0x21, 0x10, - 0x00, 0x22, 0x78, 0x2b, 0xc3, 0xed, 0x0a, 0x21, - 0xf6, 0xff, 0x22, 0x78, 0x2b, 0x2a, 0x76, 0x2b, - 0xe5, 0x21, 0x14, 0x00, 0x39, 0xe5, 0x2a, 0x78, - 0x2b, 0xe5, 0x2a, 0x6a, 0x2b, 0xe5, 0xcd, 0x8c, - 0x0c, 0xeb, 0x21, 0x08, 0x00, 0x39, 0xf9, 0xeb, - 0x22, 0x7a, 0x2b, 0x2a, 0x76, 0x2b, 0xeb, 0x2a, - 0x6a, 0x2b, 0x19, 0x22, 0x6a, 0x2b, 0xc3, 0x75, - 0x0b, 0x2a, 0x6a, 0x2b, 0x23, 0x23, 0x22, 0x6a, - 0x2b, 0x2b, 0x2b, 0x5e, 0x23, 0x56, 0xeb, 0x22, - 0x7a, 0x2b, 0xe5, 0xcd, 0x15, 0x26, 0xd1, 0x22, - 0x76, 0x2b, 0xc3, 0x83, 0x0b, 0x2a, 0x6a, 0x2b, - 0x23, 0x23, 0x22, 0x6a, 0x2b, 0x2b, 0x2b, 0x5e, - 0x23, 0x56, 0xeb, 0x22, 0x68, 0x2b, 0x2a, 0x68, - 0x2b, 0xe5, 0x21, 0x13, 0x00, 0x39, 0x22, 0x7a, - 0x2b, 0xd1, 0x73, 0xc3, 0x75, 0x0b, 0xcd, 0xf3, - 0x27, 0x06, 0x00, 0x63, 0x00, 0x35, 0x0b, 0x64, - 0x00, 0xe7, 0x0a, 0x6f, 0x00, 0xcc, 0x0a, 0x73, - 0x00, 0x19, 0x0b, 0x75, 0x00, 0xd5, 0x0a, 0x78, - 0x00, 0xde, 0x0a, 0x46, 0x0b, 0x21, 0x12, 0x00, - 0x39, 0xeb, 0x2a, 0x7a, 0x2b, 0xcd, 0xea, 0x27, - 0x22, 0x76, 0x2b, 0x2a, 0x76, 0x2b, 0xeb, 0x2a, - 0x72, 0x2b, 0xcd, 0xc7, 0x27, 0xca, 0x96, 0x0b, - 0x2a, 0x72, 0x2b, 0x22, 0x76, 0x2b, 0x2a, 0x6e, - 0x2b, 0x7c, 0xb5, 0xca, 0xd4, 0x0b, 0xc3, 0xa8, - 0x0b, 0x2a, 0x6c, 0x2b, 0x23, 0x22, 0x6c, 0x2b, - 0x2a, 0x74, 0x2b, 0x2b, 0x22, 0x74, 0x2b, 0x23, - 0xeb, 0x2a, 0x76, 0x2b, 0xcd, 0xc7, 0x27, 0xca, - 0xd4, 0x0b, 0x2a, 0x70, 0x2b, 0xe5, 0x60, 0x69, - 0xcd, 0x9c, 0x26, 0xd1, 0x11, 0xff, 0xff, 0xcd, - 0x8c, 0x27, 0xca, 0xd1, 0x0b, 0x21, 0xff, 0xff, - 0xc9, 0xc3, 0xa1, 0x0b, 0x21, 0x00, 0x00, 0x22, - 0x78, 0x2b, 0xc3, 0xe4, 0x0b, 0x2a, 0x78, 0x2b, - 0x23, 0x22, 0x78, 0x2b, 0x2a, 0x7a, 0x2b, 0x7e, - 0xb7, 0xca, 0x1b, 0x0c, 0x2a, 0x78, 0x2b, 0xeb, - 0x2a, 0x72, 0x2b, 0xcd, 0xc6, 0x27, 0xca, 0x1b, - 0x0c, 0x2a, 0x7a, 0x2b, 0x23, 0x22, 0x7a, 0x2b, - 0x2b, 0x5e, 0x16, 0x00, 0xd5, 0x60, 0x69, 0xcd, - 0x9c, 0x26, 0xd1, 0x11, 0xff, 0xff, 0xcd, 0x8c, - 0x27, 0xca, 0x18, 0x0c, 0x21, 0xff, 0xff, 0xc9, - 0xc3, 0xdd, 0x0b, 0x2a, 0x78, 0x2b, 0xeb, 0x2a, - 0x6c, 0x2b, 0x19, 0x22, 0x6c, 0x2b, 0x2a, 0x6e, - 0x2b, 0x7c, 0xb5, 0xc2, 0x64, 0x0c, 0xc3, 0x38, - 0x0c, 0x2a, 0x6c, 0x2b, 0x23, 0x22, 0x6c, 0x2b, - 0x2a, 0x74, 0x2b, 0x2b, 0x22, 0x74, 0x2b, 0x23, - 0xeb, 0x2a, 0x76, 0x2b, 0xcd, 0xc7, 0x27, 0xca, - 0x64, 0x0c, 0x21, 0x20, 0x00, 0xe5, 0x60, 0x69, - 0xcd, 0x9c, 0x26, 0xd1, 0x11, 0xff, 0xff, 0xcd, - 0x8c, 0x27, 0xca, 0x61, 0x0c, 0x21, 0xff, 0xff, - 0xc9, 0xc3, 0x31, 0x0c, 0xc3, 0x85, 0x0c, 0x2a, - 0x68, 0x2b, 0xe5, 0x60, 0x69, 0xcd, 0x9c, 0x26, - 0xd1, 0x11, 0xff, 0xff, 0xcd, 0x8c, 0x27, 0xca, - 0x7e, 0x0c, 0x21, 0xff, 0xff, 0xc9, 0x2a, 0x6c, - 0x2b, 0x23, 0x22, 0x6c, 0x2b, 0xc3, 0x97, 0x08, - 0x2a, 0x6c, 0x2b, 0xc9, 0xc5, 0x21, 0x00, 0x00, - 0x22, 0x42, 0x29, 0x22, 0x44, 0x29, 0x21, 0x0a, - 0x00, 0x39, 0x7e, 0x32, 0x40, 0x29, 0x47, 0x2b, - 0x56, 0x2b, 0x5e, 0x2b, 0xeb, 0x36, 0x00, 0x22, - 0x3e, 0x29, 0xeb, 0x2b, 0x4e, 0x2b, 0x56, 0x2b, - 0x5e, 0x21, 0x42, 0x29, 0x1a, 0x77, 0x13, 0x23, - 0x05, 0xc2, 0xb4, 0x0c, 0x79, 0xb7, 0xf2, 0xe4, - 0x0c, 0x2f, 0x3c, 0x4f, 0x2a, 0x40, 0x29, 0x11, - 0x41, 0x29, 0x19, 0x7e, 0xb7, 0xf5, 0xf2, 0xe5, - 0x0c, 0x3a, 0x40, 0x29, 0x47, 0x21, 0x42, 0x29, - 0x3e, 0x00, 0x9e, 0x77, 0x23, 0x05, 0xc2, 0xd8, - 0x0c, 0xc3, 0xe5, 0x0c, 0xf5, 0x21, 0x45, 0x29, - 0x16, 0x00, 0x3e, 0x04, 0xf5, 0x5e, 0xeb, 0x06, - 0x08, 0x29, 0x7c, 0x91, 0xda, 0xf9, 0x0c, 0x67, - 0x2c, 0x05, 0xc2, 0xf1, 0x0c, 0xeb, 0x73, 0x2b, - 0xf1, 0x3d, 0xc2, 0xec, 0x0c, 0x5a, 0x16, 0x00, - 0x21, 0x30, 0x0d, 0x19, 0x7e, 0x2a, 0x3e, 0x29, - 0x2b, 0x22, 0x3e, 0x29, 0x77, 0x21, 0x42, 0x29, - 0x06, 0x04, 0xaf, 0xbe, 0xc2, 0xe5, 0x0c, 0x23, - 0x05, 0xc2, 0x1b, 0x0d, 0x2a, 0x3e, 0x29, 0xf1, - 0xf2, 0x2e, 0x0d, 0x2b, 0x36, 0x2d, 0xc1, 0xc9, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0xcd, 0x2b, - 0x12, 0x44, 0x4d, 0x7c, 0xb5, 0xc2, 0x54, 0x0d, - 0x21, 0x00, 0x00, 0xc9, 0xc5, 0x21, 0x0c, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x0c, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x6c, 0x0d, - 0xd1, 0xd1, 0xd1, 0xc9, 0x11, 0x00, 0x00, 0xcd, - 0xbe, 0x26, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0xd5, 0xcd, 0x3a, 0x10, 0xd1, 0x21, 0x46, - 0x29, 0x44, 0x4d, 0xc3, 0x8e, 0x0d, 0x60, 0x69, - 0x11, 0x05, 0x00, 0x19, 0x44, 0x4d, 0x78, 0xb1, - 0xc2, 0x9d, 0x0d, 0x21, 0xfa, 0xff, 0x22, 0xc8, - 0x2e, 0x21, 0x00, 0x00, 0xc9, 0x21, 0x0a, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xc5, 0xcd, 0x84, - 0x25, 0xd1, 0xd1, 0xca, 0xb1, 0x0d, 0xc3, 0x86, - 0x0d, 0x21, 0x03, 0x00, 0x09, 0x5e, 0x23, 0x56, - 0xd5, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xd5, 0xcd, 0xeb, 0x15, 0xd1, 0xd1, 0x22, 0x7c, - 0x2b, 0x11, 0xff, 0xff, 0xcd, 0x8c, 0x27, 0xca, - 0xd6, 0x0d, 0x21, 0x00, 0x00, 0xc9, 0x2a, 0x7c, - 0x2b, 0xe5, 0x21, 0x0e, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0x21, 0x07, 0x00, 0x19, 0xd1, 0x73, 0x21, - 0x01, 0x00, 0xe5, 0x21, 0x0e, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0x21, 0x06, 0x00, 0x19, 0xd1, 0x73, - 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, - 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, - 0x08, 0x00, 0x39, 0x4e, 0x23, 0x46, 0x21, 0x00, - 0x00, 0x22, 0x7e, 0x2b, 0xc3, 0x1e, 0x0e, 0x2a, - 0x7e, 0x2b, 0x23, 0x22, 0x7e, 0x2b, 0x2a, 0x7e, - 0x2b, 0xeb, 0x21, 0x0c, 0x00, 0x39, 0x7e, 0x23, - 0x66, 0x6f, 0xcd, 0xc6, 0x27, 0xca, 0x7b, 0x0e, - 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, - 0x22, 0x82, 0x2b, 0xc3, 0x45, 0x0e, 0x2a, 0x82, - 0x2b, 0x2b, 0x22, 0x82, 0x2b, 0x2a, 0x82, 0x2b, - 0x7c, 0xb5, 0xca, 0x78, 0x0e, 0x21, 0x0e, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x7f, 0x0e, - 0xd1, 0x22, 0x80, 0x2b, 0x11, 0xff, 0xff, 0xcd, - 0x8c, 0x27, 0xca, 0x69, 0x0e, 0x2a, 0x7e, 0x2b, - 0xc9, 0x2a, 0x80, 0x2b, 0xe5, 0x60, 0x69, 0x23, - 0x44, 0x4d, 0x2b, 0xd1, 0x73, 0xc3, 0x3e, 0x0e, - 0xc3, 0x17, 0x0e, 0x2a, 0x7e, 0x2b, 0xc9, 0x11, - 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x08, 0x00, - 0x39, 0x4e, 0x23, 0x46, 0x21, 0x02, 0x00, 0x09, - 0x5e, 0x23, 0x56, 0xd5, 0x60, 0x69, 0x5e, 0x23, - 0x56, 0xe1, 0xcd, 0x1a, 0x28, 0xca, 0x40, 0x0f, - 0x21, 0x06, 0x00, 0x09, 0x5e, 0x16, 0x00, 0x21, - 0x18, 0x00, 0xcd, 0x64, 0x27, 0xca, 0xb4, 0x0e, - 0x21, 0xff, 0xff, 0xc9, 0x21, 0xfb, 0xff, 0xe5, - 0x60, 0x69, 0x11, 0x06, 0x00, 0x19, 0xd1, 0xe5, - 0x6e, 0xcd, 0x64, 0x27, 0xeb, 0xe1, 0x73, 0x60, - 0x69, 0x11, 0x04, 0x00, 0x19, 0x7e, 0x23, 0xb6, - 0xc2, 0xd8, 0x0e, 0xc5, 0xcd, 0x74, 0x12, 0xd1, - 0x21, 0x09, 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, - 0x21, 0x04, 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, - 0x21, 0x07, 0x00, 0x09, 0x5e, 0x16, 0x00, 0xd5, - 0xcd, 0x93, 0x19, 0xd1, 0xd1, 0xd1, 0x22, 0x84, - 0x2b, 0x11, 0x00, 0x00, 0xeb, 0xcd, 0xac, 0x27, - 0xca, 0x28, 0x0f, 0x2a, 0x84, 0x2b, 0x7c, 0xb5, - 0xc2, 0x11, 0x0f, 0x21, 0x08, 0x00, 0xc3, 0x14, - 0x0f, 0x21, 0x10, 0x00, 0xe5, 0x60, 0x69, 0x11, - 0x06, 0x00, 0x19, 0xd1, 0xe5, 0x6e, 0xcd, 0x74, - 0x27, 0xeb, 0xe1, 0x73, 0x21, 0xff, 0xff, 0xc9, - 0x21, 0x04, 0x00, 0x09, 0x5e, 0x23, 0x56, 0x60, - 0x69, 0x73, 0x23, 0x72, 0x2a, 0x84, 0x2b, 0x19, - 0xeb, 0x21, 0x02, 0x00, 0x09, 0x73, 0x23, 0x72, - 0x60, 0x69, 0xe5, 0x7e, 0x23, 0x66, 0x6f, 0x23, - 0xeb, 0xe1, 0x73, 0x23, 0x72, 0xeb, 0x2b, 0x5e, - 0x16, 0x00, 0x21, 0xff, 0x00, 0xcd, 0x64, 0x27, - 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, - 0x7e, 0x29, 0xe5, 0x21, 0x0a, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0xd5, 0xcd, 0x71, 0x0f, 0xd1, 0xd1, - 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, - 0x08, 0x00, 0x39, 0x4e, 0x23, 0x46, 0x60, 0x69, - 0x11, 0x0a, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0xa7, - 0x0f, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xd5, 0x21, 0x0d, 0x00, 0xe5, 0xcd, 0xb6, 0x0f, - 0xd1, 0xd1, 0x11, 0xff, 0xff, 0xcd, 0x8c, 0x27, - 0xca, 0xa7, 0x0f, 0x21, 0xff, 0xff, 0xc9, 0x21, - 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xc5, - 0xcd, 0xb6, 0x0f, 0xd1, 0xd1, 0xc9, 0x11, 0x00, - 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x0a, 0x00, 0x39, - 0x4e, 0x23, 0x46, 0x21, 0x02, 0x00, 0x09, 0x5e, - 0x23, 0x56, 0xd5, 0x60, 0x69, 0x5e, 0x23, 0x56, - 0xe1, 0xcd, 0x1a, 0x28, 0xca, 0xec, 0x0f, 0x21, - 0x08, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0xff, - 0x00, 0xcd, 0x64, 0x27, 0xe5, 0xc5, 0xcd, 0xb4, - 0x10, 0xd1, 0xd1, 0xc9, 0x21, 0x08, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xd5, 0x60, 0x69, 0xe5, 0x7e, - 0x23, 0x66, 0x6f, 0x23, 0xeb, 0xe1, 0x73, 0x23, - 0x72, 0xeb, 0x2b, 0xd1, 0x73, 0x16, 0x00, 0x21, - 0xff, 0x00, 0xcd, 0x64, 0x27, 0xc9, 0x11, 0x00, - 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x73, 0x29, 0x44, - 0x4d, 0x60, 0x69, 0x11, 0xec, 0x29, 0xeb, 0xcd, - 0x28, 0x28, 0xca, 0x39, 0x10, 0x60, 0x69, 0x11, - 0x0b, 0x00, 0x19, 0x44, 0x4d, 0x11, 0xf5, 0xff, - 0x19, 0xe5, 0xcd, 0x3a, 0x10, 0xd1, 0xc3, 0x19, - 0x10, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x21, 0x08, 0x00, 0x39, 0x4e, 0x23, 0x46, 0x21, - 0x00, 0x00, 0x22, 0x86, 0x2b, 0x60, 0x69, 0x11, - 0x06, 0x00, 0x19, 0x7e, 0xb7, 0xca, 0xa7, 0x10, - 0x21, 0x06, 0x00, 0x09, 0x5e, 0x16, 0x00, 0x21, - 0x04, 0x00, 0xcd, 0x64, 0x27, 0xca, 0x75, 0x10, - 0x21, 0xff, 0xff, 0xe5, 0xc5, 0xcd, 0xb4, 0x10, - 0xd1, 0xd1, 0x22, 0x86, 0x2b, 0x21, 0x07, 0x00, - 0x09, 0x5e, 0x16, 0x00, 0xd5, 0xcd, 0x68, 0x17, - 0xd1, 0xeb, 0x2a, 0x86, 0x2b, 0xcd, 0x74, 0x27, - 0x22, 0x86, 0x2b, 0x21, 0x06, 0x00, 0x09, 0x5e, - 0x16, 0x00, 0x21, 0x02, 0x00, 0xcd, 0x64, 0x27, - 0xca, 0xa7, 0x10, 0x21, 0x04, 0x00, 0x09, 0x5e, - 0x23, 0x56, 0xd5, 0xcd, 0x65, 0x23, 0xd1, 0x21, - 0x00, 0x00, 0xeb, 0x21, 0x06, 0x00, 0x09, 0x73, - 0x2a, 0x86, 0x2b, 0xc9, 0x11, 0x00, 0x00, 0xcd, - 0xbe, 0x26, 0x21, 0x08, 0x00, 0x39, 0x4e, 0x23, - 0x46, 0x21, 0x0e, 0x10, 0x22, 0x6e, 0x2a, 0x21, - 0x06, 0x00, 0x09, 0x5e, 0x16, 0x00, 0x21, 0x10, - 0x00, 0xcd, 0x64, 0x27, 0xca, 0xdb, 0x10, 0x21, - 0xff, 0xff, 0xc9, 0x21, 0x06, 0x00, 0x09, 0x5e, - 0x16, 0x00, 0x21, 0x04, 0x00, 0xcd, 0x64, 0x27, - 0xca, 0x4c, 0x11, 0x21, 0x04, 0x00, 0x09, 0x5e, - 0x23, 0x56, 0xd5, 0x60, 0x69, 0x5e, 0x23, 0x56, - 0xe1, 0xcd, 0xea, 0x27, 0x22, 0x88, 0x2b, 0x2a, - 0x88, 0x2b, 0xe5, 0x21, 0x04, 0x00, 0x09, 0x5e, - 0x23, 0x56, 0xd5, 0x21, 0x07, 0x00, 0x09, 0x5e, - 0x16, 0x00, 0xd5, 0xcd, 0x88, 0x1c, 0xd1, 0xd1, - 0xd1, 0xeb, 0x2a, 0x88, 0x2b, 0xcd, 0x9b, 0x27, - 0xca, 0x4c, 0x11, 0x21, 0x10, 0x00, 0xe5, 0x60, - 0x69, 0x11, 0x06, 0x00, 0x19, 0xd1, 0xe5, 0x6e, - 0x26, 0x00, 0xcd, 0x74, 0x27, 0xeb, 0xe1, 0x73, - 0x21, 0x00, 0x00, 0xeb, 0x60, 0x69, 0x73, 0x23, - 0x72, 0x21, 0x02, 0x00, 0x09, 0x73, 0x23, 0x72, - 0x21, 0xff, 0xff, 0xc9, 0x21, 0x0a, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0x21, 0xff, 0xff, 0xcd, 0x8c, - 0x27, 0xca, 0x85, 0x11, 0x21, 0xfb, 0xff, 0xe5, - 0x60, 0x69, 0x11, 0x06, 0x00, 0x19, 0xd1, 0xe5, - 0x6e, 0x26, 0x00, 0xcd, 0x64, 0x27, 0xeb, 0xe1, - 0x73, 0x21, 0x00, 0x00, 0xeb, 0x60, 0x69, 0x73, - 0x23, 0x72, 0x21, 0x02, 0x00, 0x09, 0x73, 0x23, - 0x72, 0x21, 0x00, 0x00, 0xc9, 0x60, 0x69, 0x11, - 0x04, 0x00, 0x19, 0x7e, 0x23, 0xb6, 0xc2, 0x96, - 0x11, 0xc5, 0xcd, 0x74, 0x12, 0xd1, 0x21, 0x09, - 0x00, 0x09, 0x5e, 0x23, 0x56, 0x21, 0x01, 0x00, - 0xcd, 0x8c, 0x27, 0xca, 0xcf, 0x11, 0x21, 0x01, - 0x00, 0xe5, 0x21, 0x0c, 0x00, 0x39, 0xe5, 0x21, - 0x07, 0x00, 0x09, 0x5e, 0x16, 0x00, 0xd5, 0xcd, - 0x88, 0x1c, 0xd1, 0xd1, 0xd1, 0x11, 0x01, 0x00, - 0xcd, 0x9b, 0x27, 0xc2, 0x23, 0x11, 0x21, 0x0a, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0xc9, 0x21, - 0x04, 0x00, 0x09, 0x5e, 0x23, 0x56, 0x60, 0x69, - 0x73, 0x23, 0x72, 0x21, 0x09, 0x00, 0x09, 0x5e, - 0x23, 0x56, 0xd5, 0x21, 0x04, 0x00, 0x09, 0x5e, - 0x23, 0x56, 0xe1, 0x19, 0xeb, 0x21, 0x02, 0x00, - 0x09, 0x73, 0x23, 0x72, 0x21, 0x04, 0x00, 0xe5, - 0x60, 0x69, 0x11, 0x06, 0x00, 0x19, 0xd1, 0xe5, - 0x6e, 0x26, 0x00, 0xcd, 0x74, 0x27, 0xeb, 0xe1, - 0x73, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xd5, 0x60, 0x69, 0xe5, 0x7e, 0x23, 0x66, 0x6f, - 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0xeb, 0x2b, - 0xd1, 0x73, 0x16, 0x00, 0x21, 0xff, 0x00, 0xcd, - 0x64, 0x27, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, - 0x26, 0x21, 0x73, 0x29, 0x44, 0x4d, 0x60, 0x69, - 0x11, 0x06, 0x00, 0x19, 0x7e, 0xb7, 0xca, 0x5a, - 0x12, 0x60, 0x69, 0x11, 0x0b, 0x00, 0x19, 0x44, - 0x4d, 0x11, 0xec, 0x29, 0xeb, 0xcd, 0x1a, 0x28, - 0xca, 0x57, 0x12, 0x21, 0x00, 0x00, 0xc9, 0xc3, - 0x36, 0x12, 0x21, 0x00, 0x00, 0xeb, 0x60, 0x69, - 0x73, 0x23, 0x72, 0x21, 0x02, 0x00, 0x09, 0x73, - 0x23, 0x72, 0x21, 0x04, 0x00, 0x09, 0x73, 0x23, - 0x72, 0x60, 0x69, 0xc9, 0x11, 0x00, 0x00, 0xcd, - 0xbe, 0x26, 0x21, 0x08, 0x00, 0x39, 0x4e, 0x23, - 0x46, 0x21, 0x07, 0x00, 0x09, 0x5e, 0x16, 0x00, - 0xd5, 0xcd, 0x93, 0x20, 0xd1, 0xca, 0xaa, 0x12, - 0x21, 0x01, 0x00, 0xeb, 0x21, 0x09, 0x00, 0x09, - 0x73, 0x23, 0x72, 0x60, 0x69, 0x11, 0x08, 0x00, - 0x19, 0xeb, 0x21, 0x04, 0x00, 0x09, 0x73, 0x23, - 0x72, 0xc9, 0x21, 0x00, 0x04, 0xe5, 0xcd, 0xc0, - 0x21, 0xd1, 0x22, 0x8a, 0x2b, 0x7c, 0xb5, 0xca, - 0x90, 0x12, 0x21, 0x00, 0x04, 0xeb, 0x21, 0x09, - 0x00, 0x09, 0x73, 0x23, 0x72, 0x21, 0x02, 0x00, - 0xe5, 0x60, 0x69, 0x11, 0x06, 0x00, 0x19, 0xd1, - 0xe5, 0x6e, 0xcd, 0x74, 0x27, 0xeb, 0xe1, 0x73, - 0x2a, 0x8a, 0x2b, 0xeb, 0x21, 0x04, 0x00, 0x09, - 0x73, 0x23, 0x72, 0xc9, 0x21, 0x64, 0x2b, 0x01, - 0x6a, 0x03, 0x1e, 0x00, 0x73, 0x23, 0x0b, 0x79, - 0xb0, 0xc2, 0xec, 0x12, 0x2a, 0x06, 0x00, 0xf9, - 0x11, 0x00, 0xf8, 0x19, 0x22, 0xca, 0x2e, 0x2a, - 0xf4, 0x29, 0x22, 0xcc, 0x2e, 0xcd, 0x19, 0x13, - 0x0e, 0x11, 0x11, 0xf6, 0x29, 0xcd, 0x05, 0x00, - 0x01, 0x00, 0x00, 0xcd, 0x05, 0x00, 0xc3, 0x08, - 0x13, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, - 0x7f, 0x00, 0xe5, 0x21, 0xd4, 0x2b, 0xe5, 0x21, - 0x81, 0x00, 0xe5, 0xcd, 0x4a, 0x26, 0xd1, 0xd1, - 0xd1, 0x21, 0x00, 0x00, 0xe5, 0x3a, 0x80, 0x00, - 0x6f, 0x26, 0x00, 0x11, 0x7f, 0x00, 0xcd, 0x64, - 0x27, 0x11, 0xd4, 0x2b, 0x19, 0xd1, 0x73, 0x21, - 0xfd, 0x14, 0x22, 0x98, 0x2b, 0x21, 0xd4, 0x2b, - 0x44, 0x4d, 0x21, 0x01, 0x00, 0x22, 0x54, 0x2c, - 0x2a, 0x54, 0x2c, 0x11, 0x1e, 0x00, 0xeb, 0xcd, - 0xc6, 0x27, 0xca, 0xe7, 0x14, 0x60, 0x69, 0x5e, - 0x16, 0x00, 0x21, 0x20, 0x00, 0xcd, 0x8c, 0x27, - 0xc2, 0x81, 0x13, 0x60, 0x69, 0x5e, 0x16, 0x00, - 0x21, 0x09, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0x89, - 0x13, 0x60, 0x69, 0x23, 0x44, 0x4d, 0xc3, 0x65, - 0x13, 0x60, 0x69, 0x7e, 0xb7, 0xca, 0xe7, 0x14, - 0x60, 0x69, 0x5e, 0x16, 0x00, 0x21, 0x3e, 0x00, - 0xcd, 0x8c, 0x27, 0xca, 0xa7, 0x13, 0x21, 0x01, - 0x00, 0x22, 0x58, 0x2c, 0xc3, 0xbb, 0x13, 0x60, - 0x69, 0x5e, 0x16, 0x00, 0x21, 0x3c, 0x00, 0xcd, - 0x8c, 0x27, 0xca, 0x98, 0x14, 0x21, 0x00, 0x00, - 0x22, 0x58, 0x2c, 0x60, 0x69, 0x23, 0x44, 0x4d, - 0x5e, 0x16, 0x00, 0x21, 0x20, 0x00, 0xcd, 0x8c, - 0x27, 0xc2, 0xda, 0x13, 0x60, 0x69, 0x5e, 0x16, - 0x00, 0x21, 0x09, 0x00, 0xcd, 0x8c, 0x27, 0xca, - 0xdd, 0x13, 0xc3, 0xbb, 0x13, 0x60, 0x69, 0x22, - 0x56, 0x2c, 0x60, 0x69, 0x23, 0x44, 0x4d, 0x7e, - 0xb7, 0xca, 0x1a, 0x14, 0x60, 0x69, 0x5e, 0x16, - 0x00, 0x21, 0x20, 0x00, 0xcd, 0x8c, 0x27, 0xc2, - 0x08, 0x14, 0x60, 0x69, 0x5e, 0x16, 0x00, 0x21, - 0x09, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0x17, 0x14, - 0x21, 0x00, 0x00, 0xe5, 0x60, 0x69, 0x23, 0x44, - 0x4d, 0x2b, 0xd1, 0x73, 0xc3, 0x1a, 0x14, 0xc3, - 0xe2, 0x13, 0x2a, 0x58, 0x2c, 0xe5, 0xcd, 0x68, - 0x17, 0xd1, 0x2a, 0x58, 0x2c, 0x7c, 0xb5, 0xca, - 0x3d, 0x14, 0x21, 0xb6, 0x01, 0xe5, 0x2a, 0x56, - 0x2c, 0xe5, 0xcd, 0xca, 0x15, 0xd1, 0xd1, 0x22, - 0x58, 0x2c, 0xc3, 0x4d, 0x14, 0x21, 0x00, 0x00, - 0xe5, 0x2a, 0x56, 0x2c, 0xe5, 0xcd, 0xeb, 0x15, - 0xd1, 0xd1, 0x22, 0x58, 0x2c, 0x2a, 0x58, 0x2c, - 0x11, 0xff, 0xff, 0xcd, 0x8c, 0x27, 0xca, 0x95, - 0x14, 0x21, 0xfe, 0x14, 0xe5, 0x21, 0x80, 0x00, - 0xe5, 0xcd, 0xbc, 0x25, 0xd1, 0xd1, 0x2a, 0x56, - 0x2c, 0xe5, 0x21, 0x80, 0x00, 0xe5, 0xcd, 0xd8, - 0x25, 0xd1, 0xd1, 0x21, 0x20, 0x15, 0xe5, 0x21, - 0x80, 0x00, 0xe5, 0xcd, 0xd8, 0x25, 0xd1, 0xd1, - 0x21, 0x80, 0x00, 0xe5, 0x21, 0x09, 0x00, 0xe5, - 0xcd, 0x19, 0x24, 0xd1, 0xd1, 0x21, 0x0a, 0x00, - 0xe5, 0xcd, 0x22, 0x15, 0xd1, 0xc3, 0xe4, 0x14, - 0x60, 0x69, 0xe5, 0x2a, 0x54, 0x2c, 0x23, 0x22, - 0x54, 0x2c, 0x2b, 0x29, 0x11, 0x98, 0x2b, 0x19, - 0xd1, 0x73, 0x23, 0x72, 0x60, 0x69, 0x23, 0x44, - 0x4d, 0x7e, 0xb7, 0xca, 0xe4, 0x14, 0x60, 0x69, - 0x5e, 0x16, 0x00, 0x21, 0x20, 0x00, 0xcd, 0x8c, - 0x27, 0xc2, 0xd2, 0x14, 0x60, 0x69, 0x5e, 0x16, - 0x00, 0x21, 0x09, 0x00, 0xcd, 0x8c, 0x27, 0xca, - 0xe1, 0x14, 0x21, 0x00, 0x00, 0xe5, 0x60, 0x69, - 0x23, 0x44, 0x4d, 0x2b, 0xd1, 0x73, 0xc3, 0xe4, - 0x14, 0xc3, 0xac, 0x14, 0xc3, 0x58, 0x13, 0x21, - 0x98, 0x2b, 0xe5, 0x2a, 0x54, 0x2c, 0xe5, 0xcd, - 0x82, 0x02, 0xd1, 0xd1, 0x21, 0x00, 0x00, 0xe5, - 0xcd, 0x22, 0x15, 0xd1, 0xc9, 0x00, 0x43, 0x61, - 0x6e, 0x27, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x6e, - 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x66, 0x6f, - 0x72, 0x20, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x00, - 0x24, 0x00, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x2a, 0x6e, 0x2a, 0xcd, 0x9c, 0x26, 0x21, 0x00, - 0x00, 0x44, 0x4d, 0x60, 0x69, 0x11, 0x0b, 0x00, - 0xeb, 0xcd, 0xc6, 0x27, 0xca, 0x4d, 0x15, 0x60, - 0x69, 0x23, 0x44, 0x4d, 0x2b, 0xe5, 0xcd, 0x68, - 0x17, 0xd1, 0xc3, 0x33, 0x15, 0x21, 0x08, 0x00, - 0x39, 0x7e, 0x23, 0xb6, 0xca, 0x70, 0x15, 0x21, - 0x18, 0x00, 0xe5, 0xcd, 0x19, 0x24, 0xd1, 0x11, - 0x01, 0x00, 0xcd, 0x64, 0x27, 0xca, 0x70, 0x15, - 0x21, 0x74, 0x15, 0xe5, 0xcd, 0x08, 0x21, 0xd1, - 0xcd, 0x08, 0x13, 0xc9, 0x41, 0x3a, 0x24, 0x24, - 0x24, 0x2e, 0x53, 0x55, 0x42, 0x00, 0x11, 0x00, - 0x00, 0xcd, 0xbe, 0x26, 0x21, 0xfd, 0xff, 0x22, - 0xc8, 0x2e, 0x21, 0xff, 0xff, 0xc9, 0x11, 0x00, - 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x00, 0x00, 0xc9, - 0x63, 0x6f, 0x6e, 0x3a, 0x00, 0x43, 0x4f, 0x4e, - 0x3a, 0x00, 0x6c, 0x73, 0x74, 0x3a, 0x00, 0x4c, - 0x53, 0x54, 0x3a, 0x00, 0x70, 0x72, 0x6e, 0x3a, - 0x00, 0x50, 0x52, 0x4e, 0x3a, 0x00, 0x70, 0x75, - 0x6e, 0x3a, 0x00, 0x50, 0x55, 0x4e, 0x3a, 0x00, - 0x72, 0x64, 0x72, 0x3a, 0x00, 0x52, 0x44, 0x52, - 0x3a, 0x00, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, - 0x21, 0x01, 0x03, 0xe5, 0x21, 0x0c, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0xeb, 0x15, 0xd1, - 0xd1, 0xd1, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, - 0x26, 0x21, 0x16, 0x2a, 0x22, 0x5a, 0x2c, 0x21, - 0x00, 0x00, 0x22, 0x5e, 0x2c, 0xc3, 0x11, 0x16, - 0x2a, 0x5a, 0x2c, 0x11, 0x08, 0x00, 0x19, 0x22, - 0x5a, 0x2c, 0x2a, 0x5e, 0x2c, 0x23, 0x22, 0x5e, - 0x2c, 0x2a, 0x5e, 0x2c, 0x11, 0x0b, 0x00, 0xeb, - 0xcd, 0xc6, 0x27, 0xca, 0x34, 0x16, 0x2a, 0x5a, - 0x2c, 0x11, 0x04, 0x00, 0x19, 0x5e, 0x23, 0x56, - 0x21, 0x7e, 0x15, 0xcd, 0x8c, 0x27, 0xc2, 0x3e, - 0x16, 0xc3, 0x00, 0x16, 0x21, 0xf8, 0xff, 0x22, - 0xc8, 0x2e, 0x21, 0xff, 0xff, 0xc9, 0x21, 0x88, - 0x2a, 0x44, 0x4d, 0xc3, 0x4e, 0x16, 0x60, 0x69, - 0x11, 0x06, 0x00, 0x19, 0x44, 0x4d, 0x60, 0x69, - 0x7e, 0x23, 0xb6, 0xca, 0x6f, 0x16, 0x21, 0x08, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x60, 0x69, - 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x84, 0x25, 0xd1, - 0xd1, 0xca, 0x6f, 0x16, 0xc3, 0x46, 0x16, 0x21, - 0x02, 0x00, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0x22, - 0x5c, 0x2c, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0x21, 0x03, 0x00, 0xcd, 0x64, 0x27, 0x23, - 0x22, 0x60, 0x2c, 0x2a, 0x60, 0x2c, 0x11, 0x01, - 0x00, 0xcd, 0x64, 0x27, 0xca, 0xb0, 0x16, 0x2a, - 0x5c, 0x2c, 0x5e, 0xd5, 0x2a, 0x5a, 0x2c, 0xd1, - 0x73, 0x7b, 0xb3, 0xc2, 0xb0, 0x16, 0x21, 0xf6, - 0xff, 0x22, 0xc8, 0x2e, 0x21, 0xff, 0xff, 0xc9, - 0x2a, 0x60, 0x2c, 0x11, 0x02, 0x00, 0xcd, 0x64, - 0x27, 0xca, 0xd7, 0x16, 0x2a, 0x5c, 0x2c, 0x23, - 0x5e, 0xd5, 0x2a, 0x5a, 0x2c, 0x23, 0xd1, 0x73, - 0x7b, 0xb3, 0xc2, 0xd7, 0x16, 0x21, 0xf6, 0xff, - 0x22, 0xc8, 0x2e, 0x21, 0xff, 0xff, 0xc9, 0x21, - 0x04, 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, 0x2a, - 0x5a, 0x2c, 0x11, 0x06, 0x00, 0x19, 0xd1, 0x73, - 0x23, 0x72, 0x2a, 0x5c, 0x2c, 0x23, 0x23, 0x5e, - 0xd5, 0x2a, 0x5a, 0x2c, 0x23, 0x23, 0xd1, 0x73, - 0x2a, 0x5c, 0x2c, 0x23, 0x23, 0x23, 0x5e, 0xd5, - 0x2a, 0x5a, 0x2c, 0x23, 0x23, 0x23, 0xd1, 0x73, - 0x21, 0x8e, 0x15, 0xe5, 0x2a, 0x5a, 0x2c, 0x11, - 0x04, 0x00, 0x19, 0xd1, 0x73, 0x23, 0x72, 0xc5, - 0x2a, 0x5a, 0x2c, 0xe5, 0x21, 0x10, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x10, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xd5, 0x21, 0x10, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xd5, 0x2a, 0x5c, 0x2c, 0x11, - 0x04, 0x00, 0x19, 0x5e, 0x23, 0x56, 0xeb, 0xcd, - 0x9c, 0x26, 0xeb, 0x21, 0x0a, 0x00, 0x39, 0xf9, - 0x21, 0x00, 0x00, 0xcd, 0xc6, 0x27, 0xca, 0x64, - 0x17, 0x21, 0x7e, 0x15, 0xe5, 0x2a, 0x5a, 0x2c, - 0x11, 0x04, 0x00, 0x19, 0xd1, 0x73, 0x23, 0x72, - 0x21, 0xff, 0xff, 0xc9, 0x2a, 0x5e, 0x2c, 0xc9, - 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x08, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x00, 0x00, - 0xcd, 0xc6, 0x27, 0xc2, 0x8e, 0x17, 0x21, 0x08, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x0b, 0x00, - 0xcd, 0xc7, 0x27, 0xca, 0x98, 0x17, 0x21, 0xfd, - 0xff, 0x22, 0xc8, 0x2e, 0x21, 0xff, 0xff, 0xc9, - 0x21, 0x08, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, - 0x29, 0x29, 0x29, 0x11, 0x16, 0x2a, 0x19, 0x44, - 0x4d, 0x21, 0x06, 0x00, 0x09, 0x5e, 0x23, 0x56, - 0xd5, 0x21, 0x04, 0x00, 0x09, 0x5e, 0x23, 0x56, - 0xeb, 0xcd, 0x9c, 0x26, 0xd1, 0xeb, 0x21, 0x08, - 0x00, 0x39, 0x73, 0x23, 0x72, 0x21, 0x00, 0x00, - 0xeb, 0x21, 0x03, 0x00, 0x09, 0x73, 0x21, 0x02, - 0x00, 0x09, 0x73, 0x21, 0x01, 0x00, 0x09, 0x73, - 0x60, 0x69, 0x73, 0x21, 0x7e, 0x15, 0xeb, 0x21, - 0x04, 0x00, 0x09, 0x73, 0x23, 0x72, 0x21, 0x08, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0xc9, 0x11, - 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x62, 0x2c, - 0x44, 0x4d, 0xc3, 0x05, 0x18, 0x60, 0x69, 0x11, - 0x27, 0x00, 0x19, 0x44, 0x4d, 0x60, 0x69, 0x11, - 0x9a, 0x2d, 0xeb, 0xcd, 0x28, 0x28, 0xca, 0x1f, - 0x18, 0x60, 0x69, 0x11, 0x25, 0x00, 0x19, 0x7e, - 0xb7, 0xca, 0x29, 0x18, 0xc3, 0xfd, 0x17, 0x21, - 0xf9, 0xff, 0x22, 0xc8, 0x2e, 0x21, 0xff, 0xff, - 0xc9, 0xc5, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0xd5, 0xcd, 0x2d, 0x24, 0xd1, 0xd1, 0x22, - 0x9a, 0x2d, 0x11, 0xff, 0xff, 0xcd, 0x8c, 0x27, - 0xca, 0x4d, 0x18, 0x21, 0xfa, 0xff, 0x22, 0xc8, - 0x2e, 0x21, 0xff, 0xff, 0xc9, 0x2a, 0x9a, 0x2d, - 0x11, 0xff, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0x5f, - 0x18, 0xcd, 0x50, 0x25, 0x22, 0x9a, 0x2d, 0x2a, - 0x9a, 0x2d, 0xe5, 0xcd, 0x5f, 0x25, 0xd1, 0x21, - 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x00, - 0x02, 0xcd, 0x64, 0x27, 0xca, 0x81, 0x18, 0xc5, - 0x21, 0x13, 0x00, 0xe5, 0xcd, 0x19, 0x24, 0xd1, - 0xd1, 0xc5, 0x21, 0x0f, 0x00, 0xe5, 0xcd, 0x19, - 0x24, 0xd1, 0xd1, 0x11, 0xff, 0x00, 0xcd, 0x8c, - 0x27, 0xca, 0xc7, 0x18, 0x21, 0x0a, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0x21, 0x00, 0x03, 0xcd, 0x64, - 0x27, 0xca, 0xb7, 0x18, 0xc5, 0x21, 0x16, 0x00, - 0xe5, 0xcd, 0x19, 0x24, 0xd1, 0xd1, 0x11, 0xff, - 0x00, 0xcd, 0x8c, 0x27, 0xca, 0xc4, 0x18, 0x21, - 0xff, 0xff, 0x22, 0xc8, 0x2e, 0xcd, 0x78, 0x25, - 0x21, 0xff, 0xff, 0xc9, 0xc3, 0xea, 0x18, 0x21, - 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x21, 0x00, - 0x05, 0xcd, 0x64, 0x27, 0x11, 0x00, 0x05, 0xcd, - 0x8c, 0x27, 0xca, 0xea, 0x18, 0x21, 0xfb, 0xff, - 0x22, 0xc8, 0x2e, 0xcd, 0x78, 0x25, 0x21, 0xff, - 0xff, 0xc9, 0x21, 0x00, 0x00, 0xeb, 0x21, 0x21, - 0x00, 0x09, 0x73, 0x23, 0x72, 0x21, 0x23, 0x00, - 0x09, 0x73, 0x21, 0x24, 0x00, 0x09, 0x73, 0x2a, - 0x9a, 0x2d, 0xeb, 0x21, 0x26, 0x00, 0x09, 0x73, - 0x60, 0x69, 0xe5, 0x21, 0x10, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0x21, 0x06, 0x00, 0x19, 0xd1, 0x73, - 0x23, 0x72, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0x21, 0x03, 0x00, 0xcd, 0x64, 0x27, 0x23, - 0xeb, 0x21, 0x25, 0x00, 0x09, 0x73, 0x21, 0x5d, - 0x19, 0xe5, 0x21, 0x10, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0x21, 0x04, 0x00, 0x19, 0xd1, 0x73, 0x23, - 0x72, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0x21, 0x00, 0x08, 0xcd, 0x64, 0x27, 0xca, 0x56, - 0x19, 0xc5, 0xcd, 0x37, 0x1f, 0xd1, 0xcd, 0x78, - 0x25, 0x21, 0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, - 0xcd, 0xbe, 0x26, 0x21, 0x08, 0x00, 0x39, 0x4e, - 0x23, 0x46, 0xcd, 0xed, 0x1f, 0x21, 0x26, 0x00, - 0x09, 0x5e, 0x16, 0x00, 0xd5, 0xcd, 0x5f, 0x25, - 0xd1, 0xc5, 0x21, 0x10, 0x00, 0xe5, 0xcd, 0x19, - 0x24, 0xd1, 0xd1, 0xcd, 0x78, 0x25, 0x21, 0x00, - 0x00, 0xeb, 0x21, 0x25, 0x00, 0x09, 0x73, 0x21, - 0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, - 0x26, 0x21, 0x08, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xeb, 0x29, 0x29, 0x29, 0x11, 0x16, 0x2a, 0x19, - 0x44, 0x4d, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0xd5, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0xd5, 0x21, 0x06, 0x00, 0x09, 0x5e, 0x23, - 0x56, 0xd5, 0x60, 0x69, 0x5e, 0x16, 0x00, 0xeb, - 0x29, 0x11, 0xca, 0x2a, 0x19, 0x5e, 0x23, 0x56, - 0xeb, 0xcd, 0x9c, 0x26, 0xd1, 0xd1, 0xd1, 0xc9, - 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x00, - 0x00, 0x44, 0x4d, 0x21, 0x08, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0xeb, 0x22, 0x9c, 0x2d, 0x2a, 0x9c, - 0x2d, 0x11, 0x26, 0x00, 0x19, 0x5e, 0x16, 0x00, - 0xd5, 0xcd, 0x5f, 0x25, 0xd1, 0x2a, 0x9c, 0x2d, - 0x11, 0x24, 0x00, 0x19, 0x7e, 0xb7, 0xca, 0x53, - 0x1a, 0x2a, 0x9c, 0x2d, 0x11, 0x24, 0x00, 0x19, - 0x5e, 0x16, 0x00, 0xd5, 0x21, 0x80, 0x00, 0xd1, - 0xeb, 0xcd, 0xea, 0x27, 0x44, 0x4d, 0xeb, 0x21, - 0x0c, 0x00, 0x39, 0x7e, 0x23, 0x66, 0x6f, 0xcd, - 0x29, 0x28, 0xca, 0x36, 0x1a, 0x21, 0x0c, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0x42, 0x4b, 0xc5, 0x21, - 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x2a, - 0x9c, 0x2d, 0xe5, 0xcd, 0xfe, 0x1a, 0xd1, 0xd1, - 0xd1, 0xca, 0x53, 0x1a, 0xcd, 0x78, 0x25, 0x21, - 0x00, 0x00, 0xc9, 0x21, 0x0c, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0x60, 0x69, 0xcd, 0xea, 0x27, 0x11, - 0x07, 0x00, 0xeb, 0xcd, 0x4f, 0x27, 0x22, 0x9e, - 0x2d, 0x7c, 0xb5, 0xca, 0xa7, 0x1a, 0x2a, 0x9e, - 0x2d, 0xe5, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0x60, 0x69, 0x19, 0xe5, 0x2a, 0x9c, 0x2d, - 0xe5, 0xcd, 0xad, 0x20, 0xd1, 0xd1, 0xd1, 0x22, - 0xa0, 0x2d, 0x7c, 0xb5, 0xca, 0xa7, 0x1a, 0xcd, - 0x78, 0x25, 0x2a, 0x9e, 0x2d, 0xeb, 0x2a, 0xa0, - 0x2d, 0xcd, 0xea, 0x27, 0x11, 0x07, 0x00, 0xeb, - 0xcd, 0x3f, 0x27, 0x50, 0x59, 0x19, 0xc9, 0x2a, - 0x9e, 0x2d, 0x11, 0x07, 0x00, 0xeb, 0xcd, 0x3f, - 0x27, 0x50, 0x59, 0x19, 0x44, 0x4d, 0x60, 0x69, - 0xeb, 0x21, 0x0c, 0x00, 0x39, 0x7e, 0x23, 0x66, - 0x6f, 0xcd, 0x28, 0x28, 0xca, 0xf2, 0x1a, 0x21, - 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x60, 0x69, - 0xcd, 0xea, 0x27, 0xe5, 0x21, 0x0c, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0x60, 0x69, 0x19, 0xe5, 0x2a, - 0x9c, 0x2d, 0xe5, 0xcd, 0xfe, 0x1a, 0xd1, 0xd1, - 0xd1, 0xca, 0xf2, 0x1a, 0xcd, 0x78, 0x25, 0x60, - 0x69, 0xc9, 0xcd, 0x78, 0x25, 0x21, 0x0c, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xeb, 0xc9, 0x11, 0x00, - 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x08, 0x00, 0x39, - 0x4e, 0x23, 0x46, 0xc5, 0xcd, 0xfa, 0x1f, 0xd1, - 0xca, 0x17, 0x1b, 0x21, 0xff, 0xff, 0xc9, 0x21, - 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x24, 0x00, 0x09, 0x5e, 0x16, 0x00, 0x21, 0x80, - 0x00, 0x19, 0xe5, 0xcd, 0x4a, 0x26, 0xd1, 0xd1, - 0xd1, 0x21, 0x24, 0x00, 0x09, 0x5e, 0x16, 0x00, - 0x21, 0x0c, 0x00, 0x39, 0x7e, 0x23, 0x66, 0x6f, - 0x19, 0x11, 0x7f, 0x00, 0xcd, 0x64, 0x27, 0xeb, - 0x21, 0x24, 0x00, 0x09, 0x73, 0x7b, 0xb3, 0xc2, - 0x6b, 0x1b, 0x60, 0x69, 0x11, 0x21, 0x00, 0x19, - 0xe5, 0x7e, 0x23, 0x66, 0x6f, 0x23, 0xeb, 0xe1, - 0x73, 0x23, 0x72, 0x21, 0x00, 0x00, 0xc9, 0x11, - 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x3a, 0xa3, 0x2d, - 0xb7, 0xc2, 0xdf, 0x1b, 0x21, 0xff, 0x00, 0x7d, - 0x32, 0xa2, 0x2d, 0x21, 0x00, 0x00, 0x7d, 0x32, - 0xa4, 0x2d, 0x7d, 0x32, 0xa3, 0x2d, 0x21, 0xa2, - 0x2d, 0xe5, 0x21, 0x0a, 0x00, 0xe5, 0xcd, 0x19, - 0x24, 0xd1, 0xd1, 0x21, 0x0a, 0x00, 0xe5, 0x21, - 0x02, 0x00, 0xe5, 0xcd, 0x19, 0x24, 0xd1, 0xd1, - 0x3a, 0xa4, 0x2d, 0x6f, 0x26, 0x00, 0x11, 0x1a, - 0x00, 0xcd, 0x8c, 0x27, 0xca, 0xc2, 0x1b, 0x21, - 0x00, 0x00, 0x7d, 0x32, 0xa3, 0x2d, 0x21, 0x00, - 0x00, 0xc9, 0x3a, 0xd2, 0x2a, 0x6f, 0xe5, 0x3a, - 0xa3, 0x2d, 0x6f, 0x23, 0x7d, 0x32, 0xa3, 0x2d, - 0x26, 0x00, 0x11, 0xa2, 0x2d, 0x19, 0x23, 0xd1, - 0x73, 0x21, 0x02, 0x00, 0x22, 0xa4, 0x2e, 0x3a, - 0xa3, 0x2d, 0x6f, 0x26, 0x00, 0x44, 0x4d, 0xeb, - 0x21, 0x0c, 0x00, 0x39, 0x7e, 0x23, 0x66, 0x6f, - 0xcd, 0xc7, 0x27, 0xca, 0xff, 0x1b, 0x21, 0x0c, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0x42, 0x4b, 0xc5, - 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, - 0x2a, 0xa4, 0x2e, 0x11, 0xa2, 0x2d, 0x19, 0xe5, - 0xcd, 0x4a, 0x26, 0xd1, 0xd1, 0xd1, 0x60, 0x69, - 0xeb, 0x2a, 0xa4, 0x2e, 0x19, 0x22, 0xa4, 0x2e, - 0x60, 0x69, 0xeb, 0x3a, 0xa3, 0x2d, 0x6f, 0xeb, - 0xcd, 0xea, 0x27, 0x7d, 0x32, 0xa3, 0x2d, 0x60, - 0x69, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x21, 0x0a, 0x00, 0x39, 0x4e, 0x23, 0x46, 0x21, - 0x00, 0x00, 0x22, 0xa6, 0x2e, 0xc3, 0x4f, 0x1c, - 0x2a, 0xa6, 0x2e, 0x23, 0x22, 0xa6, 0x2e, 0x2a, - 0xa6, 0x2e, 0xeb, 0x21, 0x0c, 0x00, 0x39, 0x7e, - 0x23, 0x66, 0x6f, 0xcd, 0xc6, 0x27, 0xca, 0x84, - 0x1c, 0x21, 0x08, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xd5, 0xcd, 0x19, 0x24, 0xd1, 0xe5, 0x60, 0x69, - 0x23, 0x44, 0x4d, 0x2b, 0xd1, 0x73, 0x16, 0x00, - 0x21, 0x1a, 0x00, 0xcd, 0x8c, 0x27, 0xc2, 0x84, - 0x1c, 0xc3, 0x48, 0x1c, 0x2a, 0xa6, 0x2e, 0xc9, - 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x08, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0x29, 0x29, - 0x29, 0x11, 0x16, 0x2a, 0x19, 0x44, 0x4d, 0x21, - 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x06, 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, 0x21, - 0x01, 0x00, 0x09, 0x5e, 0x16, 0x00, 0xeb, 0x29, - 0x11, 0xd3, 0x2a, 0x19, 0x5e, 0x23, 0x56, 0xeb, - 0xcd, 0x9c, 0x26, 0xd1, 0xd1, 0xd1, 0xc9, 0x11, - 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x00, 0x00, - 0x44, 0x4d, 0x21, 0x08, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0xeb, 0x22, 0xa8, 0x2e, 0x2a, 0xa8, 0x2e, - 0x11, 0x26, 0x00, 0x19, 0x5e, 0x16, 0x00, 0xd5, - 0xcd, 0x5f, 0x25, 0xd1, 0x2a, 0xa8, 0x2e, 0x11, - 0x24, 0x00, 0x19, 0x7e, 0xb7, 0xca, 0x4a, 0x1d, - 0x2a, 0xa8, 0x2e, 0x11, 0x24, 0x00, 0x19, 0x5e, - 0x16, 0x00, 0xd5, 0x21, 0x80, 0x00, 0xd1, 0xeb, - 0xcd, 0xea, 0x27, 0x44, 0x4d, 0xeb, 0x21, 0x0c, - 0x00, 0x39, 0x7e, 0x23, 0x66, 0x6f, 0xcd, 0x29, - 0x28, 0xca, 0x2d, 0x1d, 0x21, 0x0c, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0x42, 0x4b, 0xc5, 0x21, 0x0c, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0x2a, 0xa8, - 0x2e, 0xe5, 0xcd, 0x02, 0x1e, 0xd1, 0xd1, 0xd1, - 0xca, 0x4a, 0x1d, 0xcd, 0x78, 0x25, 0x21, 0xff, - 0xff, 0xc9, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0x60, 0x69, 0xcd, 0xea, 0x27, 0x11, 0x07, - 0x00, 0xeb, 0xcd, 0x4f, 0x27, 0x22, 0xaa, 0x2e, - 0x7c, 0xb5, 0xca, 0xab, 0x1d, 0x2a, 0xaa, 0x2e, - 0xe5, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0x60, 0x69, 0x19, 0xe5, 0x2a, 0xa8, 0x2e, 0xe5, - 0xcd, 0xb5, 0x20, 0xd1, 0xd1, 0xd1, 0x22, 0xac, - 0x2e, 0x7c, 0xb5, 0xca, 0xab, 0x1d, 0xcd, 0x78, - 0x25, 0x2a, 0xaa, 0x2e, 0xeb, 0x2a, 0xac, 0x2e, - 0xcd, 0xea, 0x27, 0x11, 0x07, 0x00, 0xeb, 0xcd, - 0x3f, 0x27, 0x50, 0x59, 0x19, 0x44, 0x4d, 0x7c, - 0xb5, 0xc2, 0xa8, 0x1d, 0x21, 0xff, 0xff, 0xc9, - 0x60, 0x69, 0xc9, 0x2a, 0xaa, 0x2e, 0x11, 0x07, - 0x00, 0xeb, 0xcd, 0x3f, 0x27, 0x50, 0x59, 0x19, - 0x44, 0x4d, 0x60, 0x69, 0xeb, 0x21, 0x0c, 0x00, - 0x39, 0x7e, 0x23, 0x66, 0x6f, 0xcd, 0x28, 0x28, - 0xca, 0xf6, 0x1d, 0x21, 0x0c, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0x60, 0x69, 0xcd, 0xea, 0x27, 0xe5, - 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x60, - 0x69, 0x19, 0xe5, 0x2a, 0xa8, 0x2e, 0xe5, 0xcd, - 0x02, 0x1e, 0xd1, 0xd1, 0xd1, 0xca, 0xf6, 0x1d, - 0xcd, 0x78, 0x25, 0x60, 0x69, 0xc9, 0xcd, 0x78, - 0x25, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xeb, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x21, 0x08, 0x00, 0x39, 0x4e, 0x23, 0x46, 0xc5, - 0xcd, 0xfa, 0x1f, 0xd1, 0x11, 0x00, 0x00, 0xeb, - 0xcd, 0xc6, 0x27, 0xca, 0x22, 0x1e, 0x21, 0xff, - 0xff, 0xc9, 0x21, 0x0c, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0xd5, 0x21, 0x24, 0x00, 0x09, 0x5e, 0x16, - 0x00, 0x21, 0x80, 0x00, 0x19, 0xe5, 0x21, 0x0e, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x4a, - 0x26, 0xd1, 0xd1, 0xd1, 0xc5, 0x21, 0x22, 0x00, - 0xe5, 0xcd, 0x19, 0x24, 0xd1, 0xd1, 0x22, 0xc8, - 0x2e, 0x7c, 0xb5, 0xca, 0x5a, 0x1e, 0x21, 0xff, - 0xff, 0xc9, 0x21, 0x24, 0x00, 0x09, 0x5e, 0x16, - 0x00, 0x21, 0x0c, 0x00, 0x39, 0x7e, 0x23, 0x66, - 0x6f, 0x19, 0x11, 0x7f, 0x00, 0xcd, 0x64, 0x27, - 0xeb, 0x21, 0x24, 0x00, 0x09, 0x73, 0x7b, 0xb3, - 0xc2, 0x8c, 0x1e, 0x60, 0x69, 0x11, 0x21, 0x00, - 0x19, 0xe5, 0x7e, 0x23, 0x66, 0x6f, 0x23, 0xeb, - 0xe1, 0x73, 0x23, 0x72, 0x21, 0x00, 0x00, 0xc9, - 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x0a, - 0x00, 0x39, 0x4e, 0x23, 0x46, 0x21, 0x0c, 0x00, - 0x39, 0x5e, 0x23, 0x56, 0xeb, 0x22, 0xae, 0x2e, - 0x2a, 0xae, 0x2e, 0x2b, 0x22, 0xae, 0x2e, 0x23, - 0x7c, 0xb5, 0xca, 0xe6, 0x1e, 0x60, 0x69, 0x5e, - 0x16, 0x00, 0x21, 0x0a, 0x00, 0xcd, 0x8c, 0x27, - 0xca, 0xd0, 0x1e, 0x21, 0x0d, 0x00, 0xe5, 0x21, - 0x02, 0x00, 0xe5, 0xcd, 0x19, 0x24, 0xd1, 0xd1, - 0x60, 0x69, 0x23, 0x44, 0x4d, 0x2b, 0x5e, 0x16, - 0x00, 0xd5, 0x21, 0x02, 0x00, 0xe5, 0xcd, 0x19, - 0x24, 0xd1, 0xd1, 0xc3, 0xa8, 0x1e, 0x21, 0x0c, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0xc9, 0x11, - 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x0a, 0x00, - 0x39, 0x4e, 0x23, 0x46, 0x21, 0x0c, 0x00, 0x39, - 0x5e, 0x23, 0x56, 0xeb, 0x22, 0xb0, 0x2e, 0x2a, - 0xb0, 0x2e, 0x2b, 0x22, 0xb0, 0x2e, 0x23, 0x7c, - 0xb5, 0xca, 0x2e, 0x1f, 0x60, 0x69, 0x23, 0x44, - 0x4d, 0x2b, 0x5e, 0x16, 0x00, 0xd5, 0x21, 0x0a, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xd5, 0xcd, 0x19, - 0x24, 0xd1, 0xd1, 0xc3, 0x07, 0x1f, 0x21, 0x0c, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0xc9, 0x11, - 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x08, 0x00, - 0x39, 0x4e, 0x23, 0x46, 0xc5, 0x21, 0x23, 0x00, - 0xe5, 0xcd, 0x19, 0x24, 0xd1, 0xd1, 0x60, 0x69, - 0x11, 0x21, 0x00, 0x19, 0x7e, 0x23, 0xb6, 0xc2, - 0x67, 0x1f, 0x21, 0x00, 0x00, 0xeb, 0x21, 0x24, - 0x00, 0x09, 0x73, 0x21, 0x00, 0x00, 0xc9, 0x60, - 0x69, 0x11, 0x21, 0x00, 0x19, 0xe5, 0x7e, 0x23, - 0x66, 0x6f, 0x2b, 0xeb, 0xe1, 0x73, 0x23, 0x72, - 0xc5, 0xcd, 0xfa, 0x1f, 0xd1, 0xca, 0x84, 0x1f, - 0x21, 0xff, 0xff, 0xc9, 0x21, 0x00, 0x01, 0x22, - 0xb2, 0x2e, 0x2a, 0xb2, 0x2e, 0x11, 0x80, 0x00, - 0xeb, 0xcd, 0x29, 0x28, 0xca, 0xb7, 0x1f, 0x2a, - 0xb2, 0x2e, 0x2b, 0x22, 0xb2, 0x2e, 0x5e, 0x16, - 0x00, 0x21, 0x1a, 0x00, 0xcd, 0x9b, 0x27, 0xca, - 0xb4, 0x1f, 0x2a, 0xb2, 0x2e, 0x23, 0x22, 0xb2, - 0x2e, 0xc3, 0xb7, 0x1f, 0xc3, 0x8a, 0x1f, 0x2a, - 0xb2, 0x2e, 0x11, 0x80, 0xff, 0x19, 0xeb, 0x21, - 0x24, 0x00, 0x09, 0x73, 0x16, 0x00, 0x21, 0x80, - 0x00, 0xcd, 0x8c, 0x27, 0xca, 0xe9, 0x1f, 0x60, - 0x69, 0x11, 0x21, 0x00, 0x19, 0xe5, 0x7e, 0x23, - 0x66, 0x6f, 0x23, 0xeb, 0xe1, 0x73, 0x23, 0x72, - 0x21, 0x00, 0x00, 0xeb, 0x21, 0x24, 0x00, 0x09, - 0x73, 0x21, 0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, - 0xcd, 0xbe, 0x26, 0x21, 0x00, 0x00, 0x22, 0xb4, - 0x2e, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, - 0x21, 0x08, 0x00, 0x39, 0x4e, 0x23, 0x46, 0x21, - 0x80, 0x00, 0xe5, 0x21, 0x1a, 0x00, 0xe5, 0xcd, - 0x19, 0x24, 0xd1, 0xd1, 0x2a, 0xb4, 0x2e, 0x50, - 0x59, 0xcd, 0x9b, 0x27, 0xc2, 0x2f, 0x20, 0x21, - 0x21, 0x00, 0x09, 0x5e, 0x23, 0x56, 0x2a, 0xb6, - 0x2e, 0xcd, 0x9b, 0x27, 0xca, 0x8f, 0x20, 0xc5, - 0x21, 0x21, 0x00, 0xe5, 0xcd, 0x19, 0x24, 0xd1, - 0xd1, 0x22, 0xc8, 0x2e, 0x11, 0x01, 0x00, 0xcd, - 0x8c, 0x27, 0xc2, 0x51, 0x20, 0x2a, 0xc8, 0x2e, - 0x11, 0x04, 0x00, 0xcd, 0x8c, 0x27, 0xca, 0x73, - 0x20, 0x21, 0x00, 0x00, 0x22, 0xc8, 0x2e, 0x21, - 0x1a, 0x00, 0xe5, 0x21, 0x80, 0x00, 0xe5, 0x21, - 0x80, 0x00, 0xe5, 0xcd, 0x2e, 0x26, 0xd1, 0xd1, - 0xd1, 0x21, 0x00, 0x00, 0x22, 0xb4, 0x2e, 0x21, - 0x01, 0x00, 0xc9, 0x2a, 0xc8, 0x2e, 0x7c, 0xb5, - 0xca, 0x7f, 0x20, 0x21, 0xff, 0xff, 0xc9, 0x60, - 0x69, 0x22, 0xb4, 0x2e, 0x21, 0x21, 0x00, 0x09, - 0x5e, 0x23, 0x56, 0xeb, 0x22, 0xb6, 0x2e, 0x21, - 0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, - 0x26, 0x21, 0x08, 0x00, 0x39, 0x5e, 0x23, 0x56, - 0xeb, 0x29, 0x29, 0x29, 0x11, 0x18, 0x2a, 0x19, - 0x5e, 0x16, 0x00, 0xeb, 0xc9, 0xcd, 0xdc, 0x26, - 0x0e, 0x21, 0xc3, 0xba, 0x20, 0xcd, 0xdc, 0x26, - 0x0e, 0x22, 0xc5, 0x2a, 0x5f, 0x2b, 0xeb, 0x21, - 0x80, 0x00, 0x19, 0x22, 0x5f, 0x2b, 0x0e, 0x1a, - 0xcd, 0x05, 0x00, 0xc1, 0xc5, 0x2a, 0x5d, 0x2b, - 0xeb, 0xcd, 0x05, 0x00, 0xb7, 0xc2, 0xf3, 0x20, - 0x2a, 0x5d, 0x2b, 0x11, 0x21, 0x00, 0x19, 0x34, - 0xc2, 0xe5, 0x20, 0x23, 0x34, 0x2a, 0x61, 0x2b, - 0x2b, 0x22, 0x61, 0x2b, 0x7d, 0xb4, 0xc2, 0xbb, - 0x20, 0xc1, 0xc9, 0xfe, 0x01, 0xca, 0x03, 0x21, - 0xfe, 0x04, 0xca, 0x03, 0x21, 0x6f, 0x26, 0x00, - 0x22, 0xc8, 0x2e, 0xc1, 0x2a, 0x61, 0x2b, 0xc9, - 0x11, 0xd8, 0xff, 0xcd, 0xbe, 0x26, 0x21, 0x04, - 0x00, 0x39, 0xe5, 0x21, 0x32, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0xd5, 0xcd, 0x2d, 0x24, 0xd1, 0xd1, - 0x44, 0x4d, 0xc5, 0xcd, 0x5f, 0x25, 0xd1, 0x21, - 0x04, 0x00, 0x39, 0xe5, 0x21, 0x13, 0x00, 0xe5, - 0xcd, 0x19, 0x24, 0xd1, 0xd1, 0x44, 0x4d, 0xcd, - 0x78, 0x25, 0x60, 0x69, 0x11, 0xff, 0x00, 0xcd, - 0x8c, 0x27, 0xca, 0x4f, 0x21, 0x21, 0xff, 0xff, - 0x22, 0xc8, 0x2e, 0x21, 0xff, 0xff, 0xc9, 0x21, - 0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, 0xcd, 0xbe, - 0x26, 0x21, 0x08, 0x00, 0x39, 0x4e, 0x23, 0x46, - 0x21, 0xfc, 0xff, 0x09, 0x5e, 0x23, 0x56, 0xeb, - 0x2b, 0x29, 0x29, 0x22, 0xc0, 0x2e, 0xc5, 0xcd, - 0x65, 0x23, 0xd1, 0x21, 0x0a, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0xd5, 0xcd, 0xc0, 0x21, 0xd1, 0x22, - 0xbe, 0x2e, 0x7c, 0xb5, 0xca, 0xbc, 0x21, 0x2a, - 0xbe, 0x2e, 0x50, 0x59, 0xcd, 0x9b, 0x27, 0xca, - 0xbc, 0x21, 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, - 0x56, 0x2a, 0xc0, 0x2e, 0xcd, 0x29, 0x28, 0xca, - 0xa8, 0x21, 0x2a, 0xc0, 0x2e, 0xc3, 0xb0, 0x21, - 0x21, 0x0a, 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, - 0xe5, 0x2a, 0xbe, 0x2e, 0xe5, 0xc5, 0xcd, 0x4a, - 0x26, 0xd1, 0xd1, 0xd1, 0x2a, 0xbe, 0x2e, 0xc9, - 0x11, 0x00, 0x00, 0xcd, 0xbe, 0x26, 0x21, 0x08, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0xeb, 0x23, 0x23, - 0x23, 0x11, 0x02, 0x00, 0xeb, 0xcd, 0x4f, 0x27, - 0x23, 0x22, 0xc4, 0x2e, 0x2a, 0xbc, 0x2e, 0x22, - 0xc2, 0x2e, 0x7c, 0xb5, 0xc2, 0xf3, 0x21, 0x21, - 0xb8, 0x2e, 0x22, 0xc2, 0x2e, 0x22, 0xba, 0x2e, - 0x22, 0xbc, 0x2e, 0x2a, 0xc2, 0x2e, 0x23, 0x23, - 0x5e, 0x23, 0x56, 0x42, 0x4b, 0xc3, 0x0e, 0x22, - 0x60, 0x69, 0x22, 0xc2, 0x2e, 0x21, 0x02, 0x00, - 0x09, 0x5e, 0x23, 0x56, 0x42, 0x4b, 0x21, 0x02, - 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, 0x60, 0x69, - 0xd1, 0xcd, 0x9b, 0x27, 0xca, 0x8d, 0x22, 0x21, - 0x02, 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, 0x60, - 0x69, 0x5e, 0x23, 0x56, 0xeb, 0x29, 0x29, 0x50, - 0x59, 0x19, 0xd1, 0xcd, 0x8c, 0x27, 0xca, 0x8d, - 0x22, 0x21, 0x02, 0x00, 0x09, 0x5e, 0x23, 0x56, - 0xd5, 0x2a, 0xbc, 0x2e, 0xd1, 0xcd, 0x8c, 0x27, - 0xca, 0x5c, 0x22, 0x21, 0x02, 0x00, 0x09, 0x5e, - 0x23, 0x56, 0xeb, 0x23, 0x23, 0x5e, 0x23, 0x56, - 0xeb, 0x22, 0xbc, 0x2e, 0x21, 0x02, 0x00, 0x09, - 0x5e, 0x23, 0x56, 0xeb, 0x5e, 0x23, 0x56, 0xd5, - 0x60, 0x69, 0xd1, 0xe5, 0x7e, 0x23, 0x66, 0x6f, - 0x19, 0xeb, 0xe1, 0x73, 0x23, 0x72, 0x21, 0x02, - 0x00, 0x09, 0x5e, 0x23, 0x56, 0xeb, 0x23, 0x23, - 0x5e, 0x23, 0x56, 0x21, 0x02, 0x00, 0x09, 0x73, - 0x23, 0x72, 0xc3, 0x0e, 0x22, 0x60, 0x69, 0x5e, - 0x23, 0x56, 0x2a, 0xc4, 0x2e, 0xcd, 0x1a, 0x28, - 0xca, 0x1a, 0x23, 0x60, 0x69, 0x5e, 0x23, 0x56, - 0x2a, 0xc4, 0x2e, 0xcd, 0x8c, 0x27, 0xca, 0xbd, - 0x22, 0x21, 0x02, 0x00, 0x09, 0x5e, 0x23, 0x56, - 0xd5, 0x2a, 0xc2, 0x2e, 0x23, 0x23, 0xd1, 0x73, - 0x23, 0x72, 0xc3, 0x02, 0x23, 0x2a, 0xc4, 0x2e, - 0x29, 0x29, 0x50, 0x59, 0x19, 0x22, 0xbc, 0x2e, - 0x2a, 0xbc, 0x2e, 0xe5, 0x2a, 0xc2, 0x2e, 0x23, - 0x23, 0xd1, 0x73, 0x23, 0x72, 0x21, 0x02, 0x00, - 0x09, 0x5e, 0x23, 0x56, 0xd5, 0x2a, 0xbc, 0x2e, - 0x23, 0x23, 0xd1, 0x73, 0x23, 0x72, 0x60, 0x69, - 0x5e, 0x23, 0x56, 0x2a, 0xc4, 0x2e, 0xcd, 0xea, - 0x27, 0xe5, 0x2a, 0xbc, 0x2e, 0xd1, 0x73, 0x23, - 0x72, 0x2a, 0xc4, 0x2e, 0xeb, 0x60, 0x69, 0x73, - 0x23, 0x72, 0x2a, 0xc2, 0x2e, 0x22, 0xbc, 0x2e, - 0x21, 0x00, 0x00, 0xeb, 0x21, 0x02, 0x00, 0x09, - 0x73, 0x23, 0x72, 0x60, 0x69, 0x11, 0x04, 0x00, - 0x19, 0xc9, 0x60, 0x69, 0xeb, 0x2a, 0xbc, 0x2e, - 0xcd, 0x8c, 0x27, 0xca, 0x61, 0x23, 0x21, 0x00, - 0x04, 0xe5, 0xcd, 0x16, 0x25, 0xd1, 0x44, 0x4d, - 0x11, 0xff, 0xff, 0xcd, 0x8c, 0x27, 0xca, 0x3d, - 0x23, 0x21, 0x00, 0x00, 0xc9, 0x21, 0x00, 0x01, - 0xeb, 0x60, 0x69, 0x73, 0x23, 0x72, 0x21, 0x00, - 0x00, 0xeb, 0x21, 0x02, 0x00, 0x09, 0x73, 0x23, - 0x72, 0x60, 0x69, 0x11, 0x04, 0x00, 0x19, 0xe5, - 0xcd, 0x65, 0x23, 0xd1, 0x2a, 0xbc, 0x2e, 0x44, - 0x4d, 0xc3, 0x00, 0x22, 0xc9, 0x11, 0x00, 0x00, - 0xcd, 0xbe, 0x26, 0x21, 0x08, 0x00, 0x39, 0x5e, - 0x23, 0x56, 0x21, 0xfc, 0xff, 0x19, 0x22, 0xc6, - 0x2e, 0x2a, 0xc6, 0x2e, 0x23, 0x23, 0x7e, 0x23, - 0xb6, 0xca, 0x88, 0x23, 0x21, 0xff, 0xff, 0xc9, - 0x2a, 0xbc, 0x2e, 0x44, 0x4d, 0xc3, 0x99, 0x23, - 0x21, 0x02, 0x00, 0x09, 0x5e, 0x23, 0x56, 0x42, - 0x4b, 0x60, 0x69, 0xeb, 0x2a, 0xc6, 0x2e, 0xcd, - 0x29, 0x28, 0xc2, 0xb8, 0x23, 0x21, 0x02, 0x00, - 0x09, 0x5e, 0x23, 0x56, 0xd5, 0x2a, 0xc6, 0x2e, - 0xd1, 0xeb, 0xcd, 0x29, 0x28, 0xca, 0xec, 0x23, - 0x21, 0x02, 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, - 0x60, 0x69, 0xd1, 0xeb, 0xcd, 0x1a, 0x28, 0xca, - 0xe9, 0x23, 0x2a, 0xc6, 0x2e, 0x50, 0x59, 0xeb, - 0xcd, 0x29, 0x28, 0xc2, 0xec, 0x23, 0x21, 0x02, - 0x00, 0x09, 0x5e, 0x23, 0x56, 0xd5, 0x2a, 0xc6, - 0x2e, 0xd1, 0xeb, 0xcd, 0x28, 0x28, 0xc2, 0xec, - 0x23, 0xc3, 0x90, 0x23, 0x21, 0x02, 0x00, 0x09, - 0x5e, 0x23, 0x56, 0xd5, 0x2a, 0xc6, 0x2e, 0x23, - 0x23, 0xd1, 0x73, 0x23, 0x72, 0x2a, 0xc6, 0x2e, - 0xeb, 0x21, 0x02, 0x00, 0x09, 0x73, 0x23, 0x72, - 0x60, 0x69, 0x22, 0xbc, 0x2e, 0x21, 0x00, 0x00, - 0xc9, 0xcd, 0xdc, 0x26, 0xcd, 0x1c, 0x24, 0xeb, - 0xc9, 0xcd, 0xdc, 0x26, 0x2a, 0x5d, 0x2b, 0x44, - 0x4d, 0x2a, 0x5f, 0x2b, 0xeb, 0xcd, 0x05, 0x00, - 0xeb, 0x6f, 0xaf, 0x67, 0xc9, 0xc5, 0x21, 0x04, - 0x00, 0x39, 0x4e, 0x23, 0x46, 0x23, 0x5e, 0x23, - 0x56, 0x6b, 0x62, 0x36, 0x00, 0x23, 0x3e, 0x0b, - 0x36, 0x20, 0x23, 0x3d, 0xc2, 0x40, 0x24, 0x3e, - 0x04, 0x36, 0x00, 0x23, 0x3d, 0xc2, 0x49, 0x24, - 0xeb, 0x79, 0xb0, 0xca, 0xf1, 0x24, 0x0a, 0xfe, - 0x20, 0xca, 0x61, 0x24, 0xfe, 0x09, 0xc2, 0x65, - 0x24, 0x03, 0xc3, 0x56, 0x24, 0xc5, 0x16, 0x00, - 0x0a, 0xcd, 0x0a, 0x25, 0xda, 0x7e, 0x24, 0xd6, - 0x30, 0x5f, 0x7a, 0x87, 0x87, 0x87, 0x82, 0x82, - 0x83, 0x57, 0x03, 0xc3, 0x68, 0x24, 0xfe, 0x2f, - 0xc2, 0x88, 0x24, 0x03, 0xf1, 0xc3, 0x8b, 0x24, - 0xc1, 0x16, 0xff, 0x03, 0x0a, 0xfe, 0x3a, 0x0b, - 0x3e, 0x00, 0xc2, 0xb6, 0x24, 0x0a, 0xe6, 0x7f, - 0xfe, 0x41, 0xda, 0xf1, 0x24, 0xfe, 0x5b, 0xd2, - 0xa7, 0x24, 0xd6, 0x40, 0xc3, 0xb3, 0x24, 0xfe, - 0x61, 0xda, 0xf1, 0x24, 0xfe, 0x7b, 0xd2, 0xf1, - 0x24, 0xd6, 0x60, 0x77, 0x03, 0x03, 0x23, 0x1e, - 0x08, 0x1c, 0x0a, 0x03, 0xfe, 0x2e, 0xca, 0xd1, - 0x24, 0xb7, 0xca, 0xea, 0x24, 0x1d, 0xca, 0xb9, - 0x24, 0xcd, 0xf8, 0x24, 0x77, 0x23, 0xc3, 0xba, - 0x24, 0x1d, 0x7b, 0x85, 0x6f, 0x7c, 0xce, 0x00, - 0x67, 0x1e, 0x03, 0x0a, 0x03, 0xb7, 0xca, 0xea, - 0x24, 0xcd, 0xf8, 0x24, 0x77, 0x23, 0x1d, 0xc2, - 0xdb, 0x24, 0x26, 0x00, 0x6a, 0x7a, 0xb7, 0xc1, - 0xc9, 0x21, 0xff, 0xff, 0x7c, 0xb7, 0xc1, 0xc9, - 0xfe, 0x2a, 0xc2, 0x01, 0x25, 0x0b, 0x3e, 0x3f, - 0xc9, 0xfe, 0x61, 0xd8, 0xfe, 0x7b, 0xd0, 0xd6, - 0x20, 0xc9, 0xfe, 0x30, 0xd8, 0xfe, 0x3a, 0xd2, - 0x14, 0x25, 0xb7, 0xc9, 0x37, 0xc9, 0x21, 0x02, - 0x00, 0x39, 0x5e, 0x23, 0x56, 0x2a, 0xf4, 0x29, - 0x19, 0xda, 0x3a, 0x25, 0xeb, 0x2a, 0xca, 0x2e, - 0x7d, 0x93, 0x7c, 0x9a, 0xda, 0x3a, 0x25, 0x2a, - 0xf4, 0x29, 0xeb, 0x22, 0xf4, 0x29, 0xeb, 0x7c, - 0xb5, 0xc9, 0x21, 0xff, 0xff, 0xaf, 0x3d, 0xc9, - 0x21, 0x02, 0x00, 0x39, 0x7d, 0x96, 0x5f, 0x7c, - 0x23, 0x9e, 0x57, 0xeb, 0x22, 0xca, 0x2e, 0xc9, - 0xcd, 0xdc, 0x26, 0x0e, 0x20, 0x1e, 0xff, 0xcd, - 0x05, 0x00, 0x6f, 0x26, 0x00, 0xb7, 0xc9, 0xcd, - 0xdc, 0x26, 0x0e, 0x20, 0x1e, 0xff, 0xcd, 0x05, - 0x00, 0x32, 0xdb, 0x2a, 0x3a, 0x5d, 0x2b, 0xfe, - 0xff, 0xc8, 0x0e, 0x20, 0x5f, 0xc3, 0x05, 0x00, - 0xcd, 0xdc, 0x26, 0x0e, 0x20, 0x3a, 0xdb, 0x2a, - 0x5f, 0xc3, 0x05, 0x00, 0x21, 0x05, 0x00, 0x39, - 0xc5, 0x01, 0xff, 0x7f, 0xc3, 0x98, 0x25, 0x21, - 0x07, 0x00, 0x39, 0xc5, 0x46, 0x2b, 0x4e, 0x2b, - 0x56, 0x2b, 0x5e, 0x2b, 0x7e, 0x2b, 0x6e, 0x67, - 0xeb, 0x78, 0xb1, 0xca, 0xb6, 0x25, 0x1a, 0x96, - 0xc2, 0xb6, 0x25, 0x1a, 0xb7, 0xca, 0xb6, 0x25, - 0x13, 0x23, 0x0b, 0xc3, 0xa1, 0x25, 0xc1, 0x6f, - 0x9f, 0x67, 0xb5, 0xc9, 0x21, 0x05, 0x00, 0x39, - 0x56, 0x2b, 0x5e, 0x2b, 0x7e, 0x2b, 0x6e, 0x67, - 0xe5, 0x1a, 0x77, 0xb7, 0xca, 0xd4, 0x25, 0x13, - 0x23, 0xc3, 0xc9, 0x25, 0xe1, 0x7c, 0xb5, 0xc9, - 0x21, 0x05, 0x00, 0x39, 0xc5, 0x01, 0xff, 0x7f, - 0xc3, 0xec, 0x25, 0x21, 0x07, 0x00, 0x39, 0xc5, - 0x46, 0x2b, 0x4e, 0x2b, 0x56, 0x2b, 0x5e, 0x2b, - 0x7e, 0x2b, 0x6e, 0x67, 0xe5, 0xaf, 0xbe, 0xca, - 0xfe, 0x25, 0x23, 0xc3, 0xf6, 0x25, 0x78, 0xb1, - 0xca, 0x0f, 0x26, 0x1a, 0x77, 0xb7, 0xca, 0x0f, - 0x26, 0x13, 0x23, 0x0b, 0xc3, 0xfe, 0x25, 0x77, - 0xe1, 0xc1, 0x7c, 0xb5, 0xc9, 0x21, 0x02, 0x00, - 0x39, 0x7e, 0x23, 0x66, 0x6f, 0x11, 0x00, 0x00, - 0xaf, 0xbe, 0xca, 0x2a, 0x26, 0x13, 0x23, 0xc3, - 0x21, 0x26, 0xeb, 0x7d, 0xb4, 0xc9, 0xc5, 0x21, - 0x04, 0x00, 0x39, 0x5e, 0x23, 0x56, 0x23, 0x4e, - 0x23, 0x46, 0x23, 0x6e, 0xeb, 0x78, 0xb1, 0xca, - 0x48, 0x26, 0x73, 0x23, 0x0b, 0xc3, 0x3d, 0x26, - 0xc1, 0xc9, 0xc5, 0x21, 0x09, 0x00, 0x39, 0x46, - 0x2b, 0x4e, 0x2b, 0x56, 0x2b, 0x5e, 0x2b, 0x7e, - 0x2b, 0x6e, 0x67, 0xba, 0xda, 0x86, 0x26, 0xc2, - 0x6a, 0x26, 0x7d, 0xbb, 0xda, 0x86, 0x26, 0xca, - 0x9a, 0x26, 0x09, 0xeb, 0x09, 0xaf, 0xc6, 0x03, - 0xea, 0x7a, 0x26, 0xeb, 0x1b, 0x2b, 0xed, 0xb8, - 0xc1, 0xc9, 0x1b, 0x2b, 0x1a, 0x77, 0x0b, 0x78, - 0xb1, 0xc2, 0x7a, 0x26, 0xc1, 0xc9, 0xaf, 0xc6, - 0x03, 0xea, 0x90, 0x26, 0xed, 0xb0, 0xc1, 0xc9, - 0x7e, 0x12, 0x13, 0x23, 0x0b, 0x78, 0xb1, 0xc2, - 0x90, 0x26, 0xc1, 0xc9, 0xe9, 0xe1, 0xc5, 0x44, - 0x4d, 0x21, 0x00, 0x00, 0x39, 0xeb, 0x39, 0xf9, - 0xd5, 0xdd, 0xe5, 0xfd, 0xe5, 0x60, 0x69, 0xcd, - 0x9c, 0x26, 0xfd, 0xe1, 0xdd, 0xe1, 0xeb, 0xe1, - 0xf9, 0xc1, 0xeb, 0x7c, 0xb5, 0xc9, 0xe1, 0xc5, - 0x44, 0x4d, 0x21, 0x00, 0x00, 0x39, 0xeb, 0x39, - 0xf9, 0xd5, 0x21, 0xb6, 0x26, 0xe5, 0x60, 0x69, - 0xe9, 0x7e, 0x12, 0x23, 0x13, 0x0b, 0x78, 0xb1, - 0xc2, 0xd1, 0x26, 0xc9, 0xd1, 0x21, 0x02, 0x00, - 0x39, 0xaf, 0xc6, 0x03, 0xea, 0xeb, 0x26, 0xdd, - 0xe5, 0xfd, 0xe5, 0xc5, 0xd5, 0x11, 0x5d, 0x2b, - 0x06, 0x06, 0x7e, 0x12, 0x23, 0x13, 0x05, 0xc2, - 0xf2, 0x26, 0x21, 0xff, 0x26, 0xe3, 0xe9, 0xc1, - 0xaf, 0xc6, 0x03, 0xea, 0x0a, 0x27, 0xfd, 0xe1, - 0xdd, 0xe1, 0x7c, 0xb5, 0xc9, 0xc5, 0x44, 0x4d, - 0x21, 0x00, 0x00, 0x3e, 0x10, 0x29, 0xeb, 0x29, - 0xeb, 0xd2, 0x1d, 0x27, 0x09, 0x3d, 0xc2, 0x15, - 0x27, 0xc1, 0x7d, 0xb4, 0xc9, 0xeb, 0x7b, 0xe6, - 0x1f, 0x5f, 0xca, 0x4c, 0x27, 0x7c, 0xb4, 0xf2, - 0x57, 0x27, 0x7c, 0x37, 0x1f, 0x67, 0x7d, 0x1f, - 0x6f, 0x1d, 0xc2, 0x32, 0x27, 0xb4, 0xc9, 0xeb, - 0x7b, 0xe6, 0x1f, 0x5f, 0xca, 0x4c, 0x27, 0x29, - 0x1d, 0xc2, 0x47, 0x27, 0x7d, 0xb4, 0xc9, 0xeb, - 0x7b, 0xe6, 0x1f, 0x5f, 0xca, 0x4c, 0x27, 0x7c, - 0xb7, 0x1f, 0x67, 0x7d, 0x1f, 0x6f, 0x1d, 0xc2, - 0x57, 0x27, 0xb4, 0xc9, 0x7c, 0xa2, 0x67, 0x7d, - 0xa3, 0x6f, 0xb4, 0xc9, 0x7c, 0x2f, 0x67, 0x7d, - 0x2f, 0x6f, 0xb4, 0xc9, 0x7c, 0xb2, 0x67, 0x7d, - 0xb3, 0x6f, 0xb4, 0xc9, 0x7c, 0xaa, 0x67, 0x7d, - 0xab, 0x6f, 0xb4, 0xc9, 0x7c, 0xb5, 0xca, 0xa5, - 0x27, 0xc3, 0x96, 0x27, 0x7d, 0x93, 0xc2, 0x96, - 0x27, 0x7c, 0x92, 0xca, 0xa5, 0x27, 0x21, 0x00, - 0x00, 0xaf, 0xc9, 0x7d, 0x93, 0xc2, 0xa5, 0x27, - 0x7c, 0x92, 0xca, 0x96, 0x27, 0x21, 0x01, 0x00, - 0x7d, 0xb4, 0xc9, 0xeb, 0x7c, 0xaa, 0xfa, 0xbe, - 0x27, 0x7d, 0x93, 0x7c, 0x9a, 0x3f, 0x3e, 0x00, - 0xce, 0x00, 0x6f, 0x26, 0x00, 0xc9, 0x7a, 0x07, - 0xe6, 0x01, 0x6f, 0x26, 0x00, 0xc9, 0xeb, 0x7c, - 0xaa, 0xfa, 0xd8, 0x27, 0x7d, 0x93, 0x7c, 0x9a, - 0x3e, 0x00, 0xce, 0x00, 0x6f, 0x26, 0x00, 0xc9, - 0x7c, 0x07, 0xe6, 0x01, 0x6f, 0x26, 0x00, 0xc9, - 0x7d, 0x2f, 0x6f, 0x7c, 0x2f, 0x67, 0x23, 0x7d, - 0xb4, 0xc9, 0xeb, 0x7d, 0x93, 0x6f, 0x7c, 0x9a, - 0x67, 0xb5, 0xc9, 0xeb, 0xe1, 0xc5, 0x42, 0x4b, - 0x5e, 0x23, 0x56, 0x1b, 0x7a, 0xb7, 0xfa, 0x13, - 0x28, 0x23, 0x79, 0xbe, 0xca, 0x0d, 0x28, 0x23, - 0x23, 0x23, 0xc3, 0xfb, 0x27, 0x23, 0x78, 0xbe, - 0xc2, 0x08, 0x28, 0x23, 0x7e, 0x23, 0x66, 0x6f, - 0xc1, 0xe9, 0xeb, 0x7d, 0x93, 0x7c, 0x9a, 0x3e, - 0x00, 0x3f, 0xce, 0x00, 0x6f, 0x26, 0x00, 0xc9, - 0xeb, 0x7d, 0x93, 0x7c, 0x9a, 0x3e, 0x00, 0xce, - 0x00, 0x6f, 0x26, 0x00, 0xc9, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x05, - 0xb4, 0x05, 0xdd, 0x05, 0x06, 0x06, 0x42, 0xd6, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, - 0x00, 0x00, 0x00, 0x72, 0x2b, 0x00, 0x02, 0x00, - 0x77, 0x00, 0x00, 0x01, 0x03, 0x77, 0x2b, 0x00, - 0x02, 0x03, 0x61, 0x00, 0x00, 0x01, 0x09, 0x61, - 0x2b, 0x00, 0x02, 0x09, 0x78, 0x00, 0x00, 0x01, - 0x05, 0x78, 0x2b, 0x00, 0x02, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x86, 0x29, 0x01, 0x01, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x00, 0x01, 0x00, 0xe5, 0x31, 0xd2, 0x32, - 0xd2, 0x2e, 0x07, 0x03, 0x00, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xce, 0x36, 0x00, 0x3f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, - 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 0x01, 0x00, 0x8e, 0x15, 0x02, 0x00, 0x00, 0x02, - 0x01, 0x00, 0x8e, 0x15, 0x02, 0x00, 0x00, 0x02, - 0x01, 0x00, 0x8e, 0x15, 0x02, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x5d, 0x19, 0x62, 0x2c, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x15, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x15, 0x00, 0x00, 0x0e, 0x10, - 0x02, 0x02, 0x01, 0x00, 0x8e, 0x15, 0x00, 0x03, - 0x00, 0x00, 0x8e, 0x15, 0x03, 0x00, 0x00, 0x00, - 0x8e, 0x15, 0x01, 0x01, 0x00, 0x01, 0xef, 0x17, - 0x98, 0x15, 0x70, 0x2a, 0x02, 0x00, 0x9d, 0x15, - 0x70, 0x2a, 0x02, 0x00, 0xa2, 0x15, 0x76, 0x2a, - 0x05, 0x00, 0xa7, 0x15, 0x76, 0x2a, 0x05, 0x00, - 0xac, 0x15, 0x76, 0x2a, 0x05, 0x00, 0xb1, 0x15, - 0x76, 0x2a, 0x05, 0x00, 0xb6, 0x15, 0x76, 0x2a, - 0x04, 0x00, 0xbb, 0x15, 0x76, 0x2a, 0x04, 0x00, - 0xc0, 0x15, 0x7c, 0x2a, 0x03, 0x00, 0xc5, 0x15, - 0x7c, 0x2a, 0x03, 0x00, 0x00, 0x00, 0x82, 0x2a, - 0x00, 0x00, 0x7e, 0x15, 0xd8, 0x19, 0x6f, 0x1b, - 0x32, 0x1c, 0x0a, 0x7e, 0x15, 0xcf, 0x1c, 0xef, - 0x1e, 0xef, 0x1e, 0x00, 0x00, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x90, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x0c, 0x0c, 0x0c, - 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x09, 0x09, - 0x09, 0x09, 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x40, 0x40, 0x40, 0x40, 0x01, 0x40, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0a, 0x0a, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x40, 0x40, 0x40, 0x40, 0x20, 0xb6, 0x26, 0xeb, - 0xd5, 0x2e, 0x2a, 0x00, 0x94, 0x29, 0x00, 0x00, - 0x00, 0x00, 0x15, 0xd7, 0x06, 0x00, 0x01, 0x00, - 0x30, 0x00, 0x10, 0x27, 0x01, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x43, 0xd6, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0xd2, 0x2e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfd, 0x14, 0xd5, 0x2b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x53, 0x54, 0x44, - 0x4c, 0x49, 0x42, 0x2e, 0x48, 0x00, 0x4d, 0x01, - 0x00, 0x00, 0x34, 0x04, 0x00, 0x05, 0x00, 0x06, - 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4d, 0x59, 0x44, 0x55, - 0x4d, 0x50, 0x20, 0x20, 0x43, 0x4f, 0x4d, 0x00, - 0x00, 0x00, 0x3b, 0x0a, 0x00, 0x0b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x43, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x4c, 0x49, 0x42, 0x01, - 0x00, 0x00, 0x80, 0x10, 0x00, 0x11, 0x00, 0x12, - 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, - 0x00, 0x17, 0x00, 0x00, 0x43, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x4c, 0x49, 0x42, 0x02, - 0x00, 0x00, 0x15, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x2e, 0x2a, 0x82, 0x2a, 0x03, 0x00, - 0x02, 0x00, 0x00, 0x44, 0x55, 0x4d, 0x50, 0x43, - 0x4f, 0x4d, 0x20, 0x48, 0x20, 0x20, 0x04, 0x00, - 0x00, 0x28, 0x80, 0x02, 0x81, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x27, 0x28, 0x02, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x62, 0x2c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xd2, 0x32, 0xb8, 0x2e, 0x00, 0x00, - 0x00, 0x00, 0xb8, 0x2e, 0x01, 0x01, 0xce, 0x32, - 0x00, 0x00, 0x06, 0xd0, 0xce, 0x2e, 0x01, 0x01, - 0x00, 0x00, 0x30, 0x30, 0x2c, 0x20, 0x30, 0x78, - 0x30, 0x30, 0x2c, 0x20, 0x0d, 0x0a, 0x09, 0x30, - 0x78, 0x30, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x30, - 0x30, 0x2c, 0x20, 0x30, 0x78, 0x62, 0x38, 0x2c, - 0x20, 0x30, 0x78, 0x32, 0x65, 0x2c, 0x20, 0x30, - 0x78, 0x30, 0x31, 0x2c, 0x20, 0x30, 0x78, 0x30, - 0x31, 0x2c, 0x20, 0x30, 0x78, 0x63, 0x65, 0x2c, - 0x20, 0x30, 0x78, 0x33, 0x32, 0x2c, 0x20, 0x0d, - 0x0a, 0x09, 0x30, 0x78, 0x30, 0x30, 0x2c, 0x20, - 0x30, 0x78, 0x30, 0x30, 0x2c, 0x20, 0x30, 0x78, - 0x30, 0x36, 0x2c, 0x20, 0x30, 0x78, 0x64, 0x30, - 0x2c, 0x20, 0x30, 0x78, 0x63, 0x65, 0x2c, 0x20, - 0x30, 0x78, 0x32, 0x65, 0x2c, 0x20, 0x30, 0x78, - 0x30, 0x31, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x31, - 0x2c, 0x20, 0x0d, 0x0a, 0x09, 0x30, 0x78, 0x30, - 0x30, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x30, 0x2c, - 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, - 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x32, - 0x63, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x30, 0x2c, - 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, - 0x78, 0x37, 0x38, 0x2c, 0x20, 0x0d, 0x0a, 0x09, - 0x30, 0x20, 0x30, 0x78, 0x32, 0x30, 0x2c, 0x20, - 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, - 0x37, 0x38, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x32, - 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, - 0x30, 0x78, 0x32, 0x63, 0x2c, 0x20, 0x30, 0x78, - 0x32, 0x30, 0x2c, 0x20, 0x0d, 0x0a, 0x09, 0x30, - 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x37, - 0x38, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x33, 0x2c, - 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, - 0x78, 0x32, 0x63, 0x2c, 0x20, 0x30, 0x78, 0x32, - 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, - 0x20, 0x30, 0x78, 0x37, 0x38, 0x2c, 0x20, 0x0d, - 0x0a, 0x09, 0x30, 0x78, 0x33, 0x37, 0x2c, 0x20, - 0x30, 0x78, 0x33, 0x38, 0x2c, 0x20, 0x30, 0x78, - 0x32, 0x63, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x30, - 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, - 0x30, 0x78, 0x37, 0x38, 0x2c, 0x20, 0x30, 0x78, - 0x33, 0x33, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x32, - 0x2c, 0x20, 0x0d, 0x0a, 0x09, 0x30, 0x78, 0x32, - 0x63, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x30, 0x2c, - 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, - 0x78, 0x37, 0x38, 0x2c, 0x20, 0x30, 0x78, 0x33, - 0x33, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, - 0x20, 0x30, 0x78, 0x32, 0x63, 0x2c, 0x20, 0x30, - 0x20, 0x0d, 0x0a, 0x09, 0x30, 0x78, 0x32, 0x30, - 0x2c, 0x20, 0x30, 0x78, 0x30, 0x64, 0x2c, 0x20, - 0x30, 0x78, 0x30, 0x61, 0x2c, 0x20, 0x30, 0x78, - 0x30, 0x39, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, - 0x2c, 0x20, 0x30, 0x78, 0x37, 0x38, 0x2c, 0x20, - 0x30, 0x78, 0x33, 0x32, 0x2c, 0x20, 0x30, 0x78, - 0x33, 0x30, 0x2c, 0x20, 0x0d, 0x0a, 0x09, 0x30, - 0x78, 0x32, 0x63, 0x2c, 0x20, 0x30, 0x78, 0x32, - 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, - 0x20, 0x30, 0x78, 0x37, 0x38, 0x2c, 0x20, 0x30, - 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x36, - 0x34, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x63, 0x2c, - 0x20, 0x30, 0x78, 0x32, 0x30, 0x2c, 0x20, 0x0d, - 0x0a, 0x09, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, - 0x30, 0x78, 0x37, 0x38, 0x2c, 0x20, 0x30, 0x78, - 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x31, - 0x2c, 0x20, 0x30, 0x78, 0x32, 0x63, 0x2c, 0x20, - 0x30, 0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78, - 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x37, 0x38, - 0x2c, 0x20, 0x0d, 0x0a, 0x09, 0x30, 0x78, 0x33, - 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x39, 0x2c, - 0x20, 0x30, 0x78, 0x32, 0x63, 0x2c, 0x20, 0x30, - 0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, - 0x30, 0x2c, 0x20, 0x30, 0x78, 0x37, 0x38, 0x33, - 0x38, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x33, 0x2c, - -}; - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/DUMPMAC.ASM b/branches/s100/Apps/crossdev/DUMPMAC.ASM deleted file mode 100644 index 103e7c82..00000000 --- a/branches/s100/Apps/crossdev/DUMPMAC.ASM +++ /dev/null @@ -1,108 +0,0 @@ -; dumpmac.asm 2/1/2012 dwg - dump macro, declaration and implementation - - maclib portab - maclib globals - maclib hardware - maclib z80 - maclib cpmbdos - maclib printers - - cseg - -; e=char on entry - public x$pr$vis -x$pr$vis: - enter - lxi h,x$visibool - mvi d,0 - dad d - mov a,m - cpi 0 - jz do$dot - mvi c,2 - call BDOS - jmp x$pr$fini -do$dot: - conout '.' -x$pr$fini: - leave - ret - - public x$dump -x$dump: shld x$dump$tmp - call pr$h$word - conout ':' - conout ' ' - mvi b,16 -x$d$lp1: - mov a,m - inx h - xchg - mov l,a - call pr$h$byte - conout ' ' - xchg - dcr b - jnz x$d$lp1 - conout ' ' - conout ' ' - mvi b,16 - lhld x$dump$tmp -x$d$lp2: - mov a,m - inx h - mov e,a - call x$pr$vis - dcr b - jnz x$d$lp2 - conout CR - conout LF - lhld x$dump$tmp - ret - - -; display a number of lines of sixteen bytes in hex with leading address -; and ascii - public x$dump$multi -x$dump$multi: - push h ; save display address in case x$dump changes it - call x$dump ; call actual dump routine for 16 bytes - pop h ; restore display address - lxi d,16 ; get ready to increment it by 16 bytes - dad d ; here we go, HL = new load address - dcr c ; decrement line counter - jnz x$dump$multi ; do more as necessary - ret - - - dseg - -x$dump$tmp ds 2 - - public x$visibool -x$visibool: -; 0 1 2 3 4 5 6 7 8 9 A B C D E F -; - - - - - - - - - - - - - - - - -vb$00 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$10 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$20 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ; "#$%&'()*+,-./ -vb$30 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;0123456789:;<=>? -vb$40 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;@ABCDEFGHIJKLMNO -vb$50 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;PQRSTUVWXYZ[\]^_ -vb$60 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;`abcdefghijklmno -vb$70 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 ;pqrstuvwxyz{|}~ -vb$80 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$90 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$a0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$b0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$c0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$d0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$e0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -vb$f0 db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - -; eof - dumpmac.asm - - - - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/EDITOR.ASM b/branches/s100/Apps/crossdev/EDITOR.ASM deleted file mode 100644 index 89cab224..00000000 --- a/branches/s100/Apps/crossdev/EDITOR.ASM +++ /dev/null @@ -1,367 +0,0 @@ - extrn .begin,.chl,.swt - extrn csave,cret,.move - PUBLIC vdaini_ -vdaini_: lxi d,.2 - call csave - LXI H,8-.2 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,16384 - CALL .or - SHLD hregbc_ - LXI H,10-.2 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - SHLD hregde_ - LXI H,12-.2 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - SHLD hreghl_ - CALL diagnose_ - LDA hrega_ - MOV L,A - MVI H,0 - RET -.2 EQU 0 - PUBLIC bitlook_ -bitlook_: lxi d,.3 - call csave - LXI H,-32768 - XCHG - LXI H,2-.3 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,0 - XCHG - LXI H,0-.3 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .5 -.4: - LXI H,0-.3 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.5: - LXI H,0-.3 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,256 - CALL .lt - JZ .6 - LXI H,0-.3 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,.1+0 - PUSH H - CALL printf_ - POP D - POP D - LXI H,0 - XCHG - LXI H,-2-.3 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .8 -.7: - LXI H,-2-.3 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.8: - LXI H,-2-.3 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,8 - CALL .lt - JZ .9 - LXI H,2-.3 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D - XCHG - DCX H - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+16 - PUSH H - CALL printf_ - POP D - POP D - JMP .7 -.9: - LXI H,.1+24 - PUSH H - CALL printf_ - POP D - JMP .4 -.6: - RET -.3 EQU -6 -.1: - DB 97,115,99,105,105,32,61,32,48,120,37,48,50,120,32 - DB 0,48,120,37,48,50,120,32,0,10,0 - PUBLIC vdaqry_ -vdaqry_: lxi d,.11 - call csave - LXI H,8-.11 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,16640 - CALL .or - SHLD hregbc_ - LXI H,10-.11 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - SHLD hreghl_ - CALL diagnose_ - LDA hrega_ - MOV L,A - MVI H,0 - RET -.11 EQU 0 - PUBLIC flip_ -flip_: lxi d,.12 - call csave - LXI H,-32768 - PUSH H - LXI H,64 - PUSH H - CALL vdaqry_ - POP D - POP D - XCHG - LXI H,-3-.12 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,-32768 - XCHG - LXI H,2-.12 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,0 - XCHG - LXI H,-1-.12 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .14 -.13: - LXI H,-1-.12 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D -.14: - LXI H,-1-.12 - DAD SP - MOV E,M - INX H - MOV D,M - LXI H,2048 - CALL .lt - JZ .15 - LXI H,2-.12 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - MOV E,M - LXI H,1-.12 - DAD SP - MOV M,E - LXI H,1-.12 - DAD SP - MOV E,M - MVI D,0 - LXI H,255 - CALL .xr - XCHG - LXI H,1-.12 - DAD SP - MOV M,E - LXI H,1-.12 - DAD SP - MOV E,M - PUSH D - LXI H,4-.12 - DAD SP - MOV E,M - INX H - MOV D,M - XCHG - POP D - MOV M,E - LXI H,2-.12 - DAD SP - PUSH H - MOV A,M - INX H - MOV H,M - MOV L,A - INX H - XCHG - POP H - MOV M,E - INX H - MOV M,D - JMP .13 -.15: - LXI H,-32768 - PUSH H - LXI H,0 - PUSH H - LXI H,64 - PUSH H - CALL vdaini_ - POP D - POP D - POP D - RET -.12 EQU -7 - PUBLIC main_ -main_: lxi d,.16 - call csave - LXI H,1 - XCHG - LXI H,2-.16 - DAD SP - MOV M,E - INX H - MOV M,D -.17: - LXI H,1 - XCHG - LXI H,2-.16 - DAD SP - MOV A,M - INX H - MOV H,M - MOV L,A - CALL .eq - JZ .18 - LXI H,1 - SHLD dregbc_ - CALL bdoscall_ - LDA drega_ - MOV L,A - MVI H,0 - JMP .19 -.21: - CALL flip_ - JMP .20 -.22: - LXI H,0 - XCHG - LXI H,2-.16 - DAD SP - MOV M,E - INX H - MOV M,D - JMP .20 -.23: - LXI H,7 - PUSH H - LXI H,.10+0 - PUSH H - CALL printf_ - POP D - POP D - JMP .20 -.19: - CALL .swt - DW 2 - DW 3,.22 - DW 102,.21 - DW .23 -.20: - JMP .17 -.18: - CALL flip_ - RET -.16 EQU -2 -.10: - DB 37,99,0 - extrn printf_ - extrn bdoscall_ - extrn dregbc_ - extrn drega_ - extrn diagnose_ - extrn hreghl_ - extrn hregde_ - extrn hregbc_ - extrn hrega_ - extrn .or - extrn .xr - extrn .eq - extrn .lt - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/EDITOR.C b/branches/s100/Apps/crossdev/EDITOR.C deleted file mode 100644 index 7f3d0d15..00000000 --- a/branches/s100/Apps/crossdev/EDITOR.C +++ /dev/null @@ -1,103 +0,0 @@ -/* editor.c 11/18/2012 dwg - */ - - -#include "std.h" -#include "applvers.h" -#include "diagnose.h" -#include "cpmbdos.h" -#include "cpmbios.h" -#include "bdoscall.h" - - -#define VDA_N8 4 -#define VDAINI 0x40 -#define VDAQRY 0x41 -#define VDARES 0x42 -#define VDASCS 0x43 - - -int vdaini(devunit,vidmode,bitmapp) - unsigned int devunit; - unsigned int vidmode; - unsigned int bitmapp; -{ - hregbc = (VDAINI << 8) | devunit; - hregde = vidmode; - hreghl = bitmapp; - diagnose(); - return hrega; -} - - -bitlook() -{ - unsigned char *p; - int ascii,row; - - p = 0x8000; - for(ascii=0;ascii<256;ascii++) { - printf("ascii = 0x%02x ",ascii); - for(row=0l;row<8;row++) { - printf("0x%02x ",*p++); - } - printf("\n"); - } -} - - -int vdaqry(devunit,bitmapp) - unsigned int devunit; - unsigned int bitmapp; -{ - hregbc = (VDAQRY << 8) | devunit; - hreghl = bitmapp; - diagnose(); - return hrega; -} - - -flip() -{ - unsigned char * p; - unsigned char byte; - int offs; - int retcode; - - retcode = vdaqry(VDA_N8 << 4,0x8000); - - p = 0x8000; - for(offs=0;offs<256*8;offs++) { - byte = *p; - byte = byte ^ 255; - *p = byte; - p++; - } - -/* bitlook(); */ - - vdaini(VDA_N8 << 4, 0, 0x8000); -} - - -int main(argc,argv) - int argc; - char *argv[]; -{ - int bRunning; - - bRunning = 1; - while(1 == bRunning) { - - crtlc ( - dregbc = 1; - bdoscall(); - switch(drega) { - case 'f': flip(); break; - case 3: bRunning = 0; break; - default: printf("%c",7); break; - } - } - - flip(); -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/EDITOR.EXE b/branches/s100/Apps/crossdev/EDITOR.EXE deleted file mode 100644 index ee7637fe..00000000 Binary files a/branches/s100/Apps/crossdev/EDITOR.EXE and /dev/null differ diff --git a/branches/s100/Apps/crossdev/EDITOR.SUB b/branches/s100/Apps/crossdev/EDITOR.SUB deleted file mode 100644 index 9b86c7f7..00000000 --- a/branches/s100/Apps/crossdev/EDITOR.SUB +++ /dev/null @@ -1,6 +0,0 @@ -cc editor -as editor -as bdoscall -as diagnose -ln editor.o bdoscall.o diagnose.o -lc - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/EXTRACT.SUB b/branches/s100/Apps/crossdev/EXTRACT.SUB deleted file mode 100644 index f069ac44..00000000 --- a/branches/s100/Apps/crossdev/EXTRACT.SUB +++ /dev/null @@ -1 +0,0 @@ -nulu submits.lbr -e $1.sub -x \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FAST.SUB b/branches/s100/Apps/crossdev/FAST.SUB deleted file mode 100644 index bc12d4ed..00000000 --- a/branches/s100/Apps/crossdev/FAST.SUB +++ /dev/null @@ -1,4 +0,0 @@ -cc remote -as remote -ln remote.o bdoscall.o ctermcap.o n8chars.o tms9918.o diagnose.o -lc - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FCNTL.H b/branches/s100/Apps/crossdev/FCNTL.H deleted file mode 100644 index 7918b125..00000000 --- a/branches/s100/Apps/crossdev/FCNTL.H +++ /dev/null @@ -1,8 +0,0 @@ -#define O_RDONLY 0 -#define O_WRONLY 1 -#define O_RDWR 2 -#define O_CREAT 0x0100 -#define O_TRUNC 0x0200 -#define O_EXCL 0x0400 -#define O_APPEND 0x0800 - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FFGETLU.LIB b/branches/s100/Apps/crossdev/FFGETLU.LIB deleted file mode 100644 index 24dad41d..00000000 --- a/branches/s100/Apps/crossdev/FFGETLU.LIB +++ /dev/null @@ -1,12 +0,0 @@ -; ffsetlu.lib 1/24/2012 dwg - -ffgetlu macro - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK - lxi d,16+2 - dad d - mov a,m - endm -; eof - ffsetlu - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FFHASLU.LIB b/branches/s100/Apps/crossdev/FFHASLU.LIB deleted file mode 100644 index e9e84b31..00000000 --- a/branches/s100/Apps/crossdev/FFHASLU.LIB +++ /dev/null @@ -1,25 +0,0 @@ -; ffhaslu.lib 1/22/2012 dwg - macro to detect drive with logical unit support - -ffhaslu macro - local ret$false,fini - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK - lxi d,16 ; offset to end of DPH - dad d ; calc offset of 1st signature byte - mov a,m ; pick up first sig byte which s/b 'L' - cpi 'L' - jnz ret$false ; if it wasn't, indicate to caller no LU - inx h ; bump ptr to 2nd signature byte - mov a,m ; pick up second sig byte which s/b 'U' - cpi 'U' - jnz ret$false ; if it wasn't, indicate to caller no LU - mvi a,TRUE ; otherwise indicate presence of LU support - jmp fini ; finish up macro -ret$false: - mvi a,FALSE ; prepare negative response for caller -fini: - endm - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FFNUMLU.LIB b/branches/s100/Apps/crossdev/FFNUMLU.LIB deleted file mode 100644 index 1f1048a5..00000000 --- a/branches/s100/Apps/crossdev/FFNUMLU.LIB +++ /dev/null @@ -1,13 +0,0 @@ -; ffnumlu.lib 1/22/2012 dwg - macro to get number of logical units - -ffnumlu macro - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK - lxi d,16+2+2 ; offset to end of DPH - dad d ; calc offset of 1st signature byte - mov a,m - endm - -; eof - ffnumlu.lib diff --git a/branches/s100/Apps/crossdev/FFSETLU.LIB b/branches/s100/Apps/crossdev/FFSETLU.LIB deleted file mode 100644 index fe1db586..00000000 --- a/branches/s100/Apps/crossdev/FFSETLU.LIB +++ /dev/null @@ -1,22 +0,0 @@ -; ffsetlu.lib 2/12/2012 dwg - review for use in superfmt -; ffsetlu.lib 1/24/2012 dwg - - -; enter with desired LU in A reg -ffsetlu macro - enter - push psw - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK ; uses c parameter (drive) - lxi d,16+2 - dad d - pop psw - mov m,a ; put slice into CURRENT - mvi c,13 - call BDOS - leave - endm - -; eof - ffsetlu - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FINDFILE.ASM b/branches/s100/Apps/crossdev/FINDFILE.ASM deleted file mode 100644 index d8ceb21a..00000000 --- a/branches/s100/Apps/crossdev/FINDFILE.ASM +++ /dev/null @@ -1,1088 +0,0 @@ -; findfile.asm 7/21/2012 dwg - added keystroke scan terminate -; findfile.asm 7/19/2012 dwg - for 2.0.0.0 B22 -; findfile.asm 2/20.2012 dwg - add RESET$DISK before exit for ZDOS -; findfile.asm 2/17/2012 dwg - review for release 1.5.1.0 -; findfile.asm 2/11/2012 dwg - make ident compliant -; findfile.asm 1/30/2012 dwg - use new do$start and do$end macros -; findfile.asm 1/22/2012 dwg - find a file on any slice - -; Copyright (C) 2011-2012 Douglas Goodall Licensed under GPL Ver 3. -; -; This file is part of NuBiosDWG and is free software: you can -; redistribute it and/or modify it under the terms of the GNU -; General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. -; This file is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; You should have received a copy of the GNU General Public License -; along with it. If not, see . - - maclib portab - maclib globals - maclib stdlib - maclib cpmbios - maclib cpmbdos - maclib bioshdr - maclib printers - maclib banner - maclib terminal - maclib applvers - maclib version -; maclib ffhaslu -; maclib ffnumlu -; maclib ffsetlu -; maclib ffgetlu -; maclib z80 -; maclib memory -; maclib cpmappl -; maclib identity - -; identity.lib 2/19/2012 dwg - add ify macro -; identity.lib 2/17/2012 dwg - Program Identity Declarations - - extrn x$ident - -ident macro file1fcb - lxi h,file1fcb - call x$ident - endm - -ify macro progname,bool - local done - local file - local fini - ident file - jmp fini - newfcb file,0,progname -fini: mvi a,bool - cpi TRUE - jnz done - conout CR - conout LF -done: - endm - - -identx macro file1fcb - local openok - local identend - - local ldrive,lcolon,lname,ldot,lext,lterm - - mvi c,FOPEN - lxi d,file1fcb - call BDOS - cpi 255 - jnz openok - - memcpy lname,file1fcb+1,8 - mvi a,',' - sta ldot - memcpy lext,file1fcb+9,3 - mvi a,'$' - sta lterm - print lname - printf ' -- File Not Found' - jmp identend -openok: - - mvi c,SETDMA - lxi d,buffer - call BDOS - - mvi c,READSEQ - lxi d,file1fcb - call BDOS - - mvi c,FCLOSE - lxi d,file1fcb - call BDOS - - lxi d,d$prog - mvi c,9 - call BDOS - - conout ',' - conout ' ' - lda p$rmj - mov l,a - mvi h,0 - call pr$d$word - conout '.' - lda p$rmn - mov l,a - call pr$d$word - conout '.' - lda p$rup - mov l,a - call pr$d$word - conout '.' - lda p$rtp - mov l,a - call pr$d$word - conout ',' - conout ' ' - - lda p$mon - mov l,a - call pr$d$word - conout '/' - lda p$day - mov l,a - call pr$d$word - conout '/' - lhld p$year - call pr$d$word - conout ',' - conout ' ' - - lxi d,d$prod - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$orig - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$ser - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$name - mvi c,9 - call BDOS - jmp identend - -ldrive ds 1 -lcolon ds 1 -lname ds 8 -ldot ds 1 -lext ds 3 -lterm ds 1 - -identend: - endm - -idata macro - jmp around$bandata -argv dw prog,dat,prod,orig,ser,myname,0 -prog db 'IDENT.COM $' - date - serial - product - originator - oriname -uuid db '777A67C2-4A92-42D4-80FE-C96FD6483BD2$' - db 'buffer-->' - public buffer,p$start,p$hexrf,p$sig - public p$rmj,p$rmn,p$rup,p$rtp - public p$mon,p$day,p$year -buffer ds 1 -p$start ds 2 -p$hexrf ds 16 -p$sig ds 2 -p$rmj ds 1 -p$rmn ds 1 -p$rup ds 1 -p$rtp ds 1 -p$mon ds 1 -p$day ds 1 -p$year ds 2 -p$argv ds 2 -p$e5 ds 1 -p$pr$st ds 2 -p$code1 ds 3 ; begin: lxi h,0 -p$code2 ds 1 ; dad sp -p$code3 ds 3 ; shld pre$stk -p$code4 ds 3 ; lxi sp,stack$top -p$code5 ds 1 ; nop -p$code6 ds 3 ; jmp around$bandata -p$prog ds 2 ; dw prog -p$dat ds 2 ; dw dat -p$prod ds 2 ; dw prod -p$orig ds 2 ; dw orig -p$ser ds 2 ; dw ser -p$nam ds 2 ; dw nam -p$term ds 2 ; dw 0 -d$prog ds 8+1+3+1 ; db '12345678.123$' -d$date ds 2+1+2+1+4+1 ; db ' 2/11/2012$' -d$ser ds 6+1 ; db '654321$' -d$prod ds 5+1 ; db 'CPM80$' -d$orig ds 3+1 ; db 'DWG$' -d$name ds 1+7+1+1+1+1+7+1 ; db ' Douglas W. Goodall$' -d$uuid ds 37 ; unique user identification -d$term2 ds 1 ; can be set to zero or dollar sign -p$len equ $-buffer -p$rsvd ds 128-p$len - db '<--buffer' -crlf db CR,LF,'$' -around$bandata: - - endm - -; eof - identity.lib - - - -; cpmappl.lib 2/10/2012 dwg - begin 1.6 development -; cpmappl.lib 2/04/2012 dwg - fix typo mov becomes mvi -; cpmappl.lib 2/ 2/2012 dwg - initial version - -; -; Copyright (C) 2011-2012 Douglas Goodall Licensed under GPL Ver 3. -; -; This file is part of NuBiosDWG and is free software: you can -; redistribute it and/or modify it under the terms of the GNU -; General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. -; This file is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; You should have received a copy of the GNU General Public License -; along with it. If not, see . -; - -do$start macro - -start: jmp begin - - public hexref -hexref db '0123456789ABCDEF' - - public id$sig,id$rmj,id$rmn,id$rup,id$rtp,id$mon,id$day,id$yr -id$sig db 'ID' -id$rmj db A$RMJ -id$rmn db A$RMN -id$rup db A$RUP -id$rtp db A$RTP -id$mon db A$MONTH -id$day db A$DAY -id$yr dw A$YEAR -id$argv dw argv - db 0e5h - - - public pre$stk -pre$stk ds 2 - - public begin -begin: lxi h,0 - dad sp - shld pre$stk - lxi sp,stack$top - nop - endm - - -;--------------------------------- - - -do$end macro - lhld pre$stk - sphl - - mvi c,13 - call BDOS - - ret - ds stack$size -stack$top: - - endm - -movfcb macro destn,source - lxi d,destn - lxi h,source - lxi b,LENFCB - ldir - endm - -copyfcb macro fcbname,source - local around - jmp around -fcbname ds 32 -around: - endm - - -; memory.lib 2/17/2012 dwg - review for release 1.5.1.0 -; memory.lib 2/11/2012 dwg - review for release 1.5 -; memory.lib 2/04/2012 dwg - adjust for new macros -; memory.lib 1/13/2012 dwg - POSIX memcpy and memset - - extrn x$memcpy - extrn x$memset - -memcpy macro dst,src,siz - lxi d,dst ; load 1st positional parameter into reg - lxi h,src ; load 2nd positional parameter into reg - lxi b,siz ; load 3rd positional parameter into reg - call x$memcpy ; call actual routine in see memory.asm - endm - -memset macro dst,data,siz - lxi h,dst ; load 1st positional parameter into reg - mvi a,data ; load 2nd positional parameter into reg - lxi b,siz ; load 3rd positional parameter into reg - call x$memset ; call actual routine in see memory.asm - endm - -; eof - memory.lib - - -; @CHK MACRO USED FOR CHECKING 8 BIT DISPLACMENTS -; -@CHK MACRO ?DD ;; USED FOR CHECKING RANGE OF 8-BIT DISP.S - IF (?DD GT 7FH) AND (?DD LT 0FF80H) - 'DISPLACEMENT RANGE ERROR - Z80 LIB' - ENDIF - ENDM -LDX MACRO ?R,?D - @CHK ?D - DB 0DDH,?R*8+46H,?D - ENDM -LDY MACRO ?R,?D - @CHK ?D - DB 0FDH,?R*8+46H,?D - ENDM -STX MACRO ?R,?D - @CHK ?D - DB 0DDH,70H+?R,?D - ENDM -STY MACRO ?R,?D - @CHK ?D - DB 0FDH,70H+?R,?D - ENDM -MVIX MACRO ?N,?D - @CHK ?D - DB 0DDH,36H,?D,?N - ENDM -MVIY MACRO ?N,?D - @CHK ?D - DB 0FDH,36H,?D,?N - ENDM -LDAI MACRO - DB 0EDH,57H - ENDM -LDAR MACRO - DB 0EDH,5FH - ENDM -STAI MACRO - DB 0EDH,47H - ENDM -STAR MACRO - DB 0EDH,4FH - ENDM - -LXIX MACRO ?NNNN - DB 0DDH,21H - DW ?NNNN - ENDM -LXIY MACRO ?NNNN - DB 0FDH,21H - DW ?NNNN - ENDM -LDED MACRO ?NNNN - DB 0EDH,5BH - DW ?NNNN - ENDM -LBCD MACRO ?NNNN - DB 0EDH,4BH - DW ?NNNN - ENDM -LSPD MACRO ?NNNN - DB 0EDH,07BH - DW ?NNNN - ENDM -LIXD MACRO ?NNNN - DB 0DDH,2AH - DW ?NNNN - ENDM -LIYD MACRO ?NNNN - DB 0FDH,2AH - DW ?NNNN - ENDM -SBCD MACRO ?NNNN - DB 0EDH,43H - DW ?NNNN - ENDM -SDED MACRO ?NNNN - DB 0EDH,53H - DW ?NNNN - ENDM -SSPD MACRO ?NNNN - DB 0EDH,73H - DW ?NNNN - ENDM -SIXD MACRO ?NNNN - DB 0DDH,22H - DW ?NNNN - ENDM -SIYD MACRO ?NNNN - DB 0FDH,22H - DW ?NNNN - ENDM -SPIX MACRO - DB 0DDH,0F9H - ENDM -SPIY MACRO - DB 0FDH,0F9H - ENDM -PUSHIX MACRO - DB 0DDH,0E5H - ENDM -PUSHIY MACRO - DB 0FDH,0E5H - ENDM -POPIX MACRO - DB 0DDH,0E1H - ENDM -POPIY MACRO - DB 0FDH,0E1H - ENDM -EXAF MACRO - DB 08H - ENDM -EXX MACRO - DB 0D9H - ENDM -XTIX MACRO - DB 0DDH,0E3H - ENDM -XTIY MACRO - DB 0FDH,0E3H - ENDM - -LDI MACRO - DB 0EDH,0A0H - ENDM -LDIR MACRO - DB 0EDH,0B0H - ENDM -LDD MACRO - DB 0EDH,0A8H - ENDM -LDDR MACRO - DB 0EDH,0B8H - ENDM -CCI MACRO - DB 0EDH,0A1H - ENDM -CCIR MACRO - DB 0EDH,0B1H - ENDM -CCD MACRO - DB 0EDH,0A9H - ENDM -CCDR MACRO - DB 0EDH,0B9H - ENDM - -ADDX MACRO ?D - @CHK ?D - DB 0DDH,86H,?D - ENDM -ADDY MACRO ?D - @CHK ?D - DB 0FDH,86H,?D - ENDM -ADCX MACRO ?D - @CHK ?D - DB 0DDH,8EH,?D - ENDM -ADCY MACRO ?D - @CHK ?D - DB 0FDH,8EH,?D - ENDM -SUBX MACRO ?D - @CHK ?D - DB 0DDH,96H,?D - ENDM -SUBY MACRO ?D - @CHK ?D - DB 0FDH,96H,?D - ENDM -SBCX MACRO ?D - @CHK ?D - DB 0DDH,9EH,?D - ENDM -SBCY MACRO ?D - @CHK ?D - DB 0FDH,9EH,?D - ENDM -ANDX MACRO ?D - @CHK ?D - DB 0DDH,0A6H,?D - ENDM -ANDY MACRO ?D - @CHK ?D - DB 0FDH,0A6H,?D - ENDM -XORX MACRO ?D - @CHK ?D - DB 0DDH,0AEH,?D - ENDM -XORY MACRO ?D - @CHK ?D - DB 0FDH,0AEH,?D - ENDM -ORX MACRO ?D - @CHK ?D - DB 0DDH,0B6H,?D - ENDM -ORY MACRO ?D - @CHK ?D - DB 0FDH,0B6H,?D - ENDM -CMPX MACRO ?D - @CHK ?D - DB 0DDH,0BEH,?D - ENDM -CMPY MACRO ?D - @CHK ?D - DB 0FDH,0BEH,?D - ENDM -INRX MACRO ?D - @CHK ?D - DB 0DDH,34H,?D - ENDM -INRY MACRO ?D - @CHK ?D - DB 0FDH,34H,?D - ENDM -DCRX MACRO ?D - @CHK ?D - DB 0DDH,035H,?D - ENDM -DCRY MACRO ?D - @CHK ?D - DB 0FDH,35H,?D - ENDM - -NEG MACRO - DB 0EDH,44H - ENDM -IM0 MACRO - DB 0EDH,46H - ENDM -IM1 MACRO - DB 0EDH,56H - ENDM -IM2 MACRO - DB 0EDH,5EH - ENDM - - -BC EQU 0 -DE EQU 2 -HL EQU 4 -IX EQU 4 -IY EQU 4 -DADC MACRO ?R - DB 0EDH,?R*8+4AH - ENDM -DSBC MACRO ?R - DB 0EDH,?R*8+42H - ENDM -DADX MACRO ?R - DB 0DDH,?R*8+09H - ENDM -DADY MACRO ?R - DB 0FDH,?R*8+09H - ENDM -INXIX MACRO - DB 0DDH,23H - ENDM -INXIY MACRO - DB 0FDH,23H - ENDM -DCXIX MACRO - DB 0DDH,2BH - ENDM -DCXIY MACRO - DB 0FDH,2BH - ENDM - -BIT MACRO ?N,?R - DB 0CBH,?N*8+?R+40H - ENDM -SETB MACRO ?N,?R - DB 0CBH,?N*8+?R+0C0H - ENDM -RES MACRO ?N,?R - DB 0CBH,?N*8+?R+80H - ENDM - -BITX MACRO ?N,?D - @CHK ?D - DB 0DDH,0CBH,?D,?N*8+46H - ENDM -BITY MACRO ?N,?D - @CHK ?D - DB 0FDH,0CBH,?D,?N*8+46H - ENDM -SETX MACRO ?N,?D - @CHK ?D - DB 0DDH,0CBH,?D,?N*8+0C6H - ENDM -SETY MACRO ?N,?D - @CHK ?D - DB 0FDH,0CBH,?D,?N*8+0C6H - ENDM -RESX MACRO ?N,?D - @CHK ?D - DB 0DDH,0CBH,?D,?N*8+86H - ENDM -RESY MACRO ?N,?D - @CHK ?D - DB 0FDH,0CBH,?D,?N*8+86H - ENDM - -JR MACRO ?N - DB 18H,?N-$-1 - ENDM -JRC MACRO ?N - DB 38H,?N-$-1 - ENDM -JRNC MACRO ?N - DB 30H,?N-$-1 - ENDM -JRZ MACRO ?N - DB 28H,?N-$-1 - ENDM -JRNZ MACRO ?N - DB 20H,?N-$-1 - ENDM -DJNZ MACRO ?N - DB 10H,?N-$-1 - ENDM - -PCIX MACRO - DB 0DDH,0E9H - ENDM -PCIY MACRO - DB 0FDH,0E9H - ENDM - -RETI MACRO - DB 0EDH,4DH - ENDM -RETN MACRO - DB 0EDH,45H - ENDM - -INP MACRO ?R - DB 0EDH,?R*8+40H - ENDM -OUTP MACRO ?R - DB 0EDH,?R*8+41H - ENDM -INI MACRO - DB 0EDH,0A2H - ENDM -INIR MACRO - DB 0EDH,0B2H - ENDM -IND MACRO - DB 0EDH,0AAH - ENDM -INDR MACRO - DB 0EDH,0BAH - ENDM -OUTI MACRO - DB 0EDH,0A3H - ENDM -OUTIR MACRO - DB 0EDH,0B3H - ENDM -OUTD MACRO - DB 0EDH,0ABH - ENDM -OUTDR MACRO - DB 0EDH,0BBH - ENDM - - -RLCR MACRO ?R - DB 0CBH, 00H + ?R - ENDM -RLCX MACRO ?D - @CHK ?D - DB 0DDH, 0CBH, ?D, 06H - ENDM -RLCY MACRO ?D - @CHK ?D - DB 0FDH, 0CBH, ?D, 06H - ENDM -RALR MACRO ?R - DB 0CBH, 10H+?R - ENDM -RALX MACRO ?D - @CHK ?D - DB 0DDH, 0CBH, ?D, 16H - ENDM -RALY MACRO ?D - @CHK ?D - DB 0FDH, 0CBH, ?D, 16H - ENDM -RRCR MACRO ?R - DB 0CBH, 08H + ?R - ENDM -RRCX MACRO ?D - @CHK ?D - DB 0DDH, 0CBH, ?D, 0EH - ENDM -RRCY MACRO ?D - @CHK ?D - DB 0FDH, 0CBH, ?D, 0EH - ENDM -RARR MACRO ?R - DB 0CBH, 18H + ?R - ENDM -RARX MACRO ?D - @CHK ?D - DB 0DDH, 0CBH, ?D, 1EH - ENDM -RARY MACRO ?D - @CHK ?D - DB 0FDH, 0CBH, ?D, 1EH - ENDM -SLAR MACRO ?R - DB 0CBH, 20H + ?R - ENDM -SLAX MACRO ?D - @CHK ?D - DB 0DDH, 0CBH, ?D, 26H - ENDM -SLAY MACRO ?D - @CHK ?D - DB 0FDH, 0CBH, ?D, 26H - ENDM -SRAR MACRO ?R - DB 0CBH, 28H+?R - ENDM -SRAX MACRO ?D - @CHK ?D - DB 0DDH, 0CBH, ?D, 2EH - ENDM -SRAY MACRO ?D - @CHK ?D - DB 0FDH, 0CBH, ?D, 2EH - ENDM -SRLR MACRO ?R - DB 0CBH, 38H + ?R - ENDM -SRLX MACRO ?D - @CHK ?D - DB 0DDH, 0CBH, ?D, 3EH - ENDM -SRLY MACRO ?D - @CHK ?D - DB 0FDH, 0CBH, ?D, 3EH - ENDM -RLD MACRO - DB 0EDH, 6FH - ENDM -RRD MACRO - DB 0EDH, 67H - ENDM - -; ffsetlu.lib 1/24/2012 dwg - -ffgetlu macro - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK - lxi d,16+2 - dad d - mov a,m - endm -; eof - ffsetlu - - -; ffsetlu.lib 2/12/2012 dwg - review for use in superfmt -; ffsetlu.lib 1/24/2012 dwg - - -; enter with desired LU in A reg -ffsetlu macro - enter - push psw - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK ; uses c parameter (drive) - lxi d,16+2 - dad d - pop psw - mov m,a ; put slice into CURRENT - mvi c,13 - call BDOS - leave - endm - -; eof - ffsetlu - - -; ffhaslu.lib 1/22/2012 dwg - macro to detect drive with logical unit support - -ffhaslu macro - local ret$false,fini - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK - lxi d,16 ; offset to end of DPH - dad d ; calc offset of 1st signature byte - mov a,m ; pick up first sig byte which s/b 'L' - cpi 'L' - jnz ret$false ; if it wasn't, indicate to caller no LU - inx h ; bump ptr to 2nd signature byte - mov a,m ; pick up second sig byte which s/b 'U' - cpi 'U' - jnz ret$false ; if it wasn't, indicate to caller no LU - mvi a,TRUE ; otherwise indicate presence of LU support - jmp fini ; finish up macro -ret$false: - mvi a,FALSE ; prepare negative response for caller -fini: - endm - - - -; ffnumlu.lib 1/22/2012 dwg - macro to get number of logical units - -ffnumlu macro - mvi c,RETCURR - call BDOS - mov c,a - call BISELDSK - lxi d,16+2+2 ; offset to end of DPH - dad d ; calc offset of 1st signature byte - mov a,m - endm - -; eof - ffnumlu.lib - - - -prfilnam macro fcb - local fnbuf,fnext,prfnfini - memcpy fnbuf,fcb+1,8 - memcpy fnext,fcb+9,3 - - lda fnext - ani 07fh - sta fnext - - lda fnext+1 - ani 07fh - sta fnext+1 - - lda fnext+2 - ani 07fh - sta fnext+2 - - mvi c,9 - lxi d,fnbuf - call BDOS - - jmp prfnfini - -fnbuf db 0,0,0,0,0,0,0,0 - db '.' -fnext db 0,0,0,' $' -prfnfini: - endm - - - do$start - - - jmp around$bandata -argv dw prog,dat,prod,orig,ser,myname,0 -prog db 'FINDFILE.COM$' - date - serial - product - originator - oriname -uuid db '107CDD27-2E4D-4340-A324-BEB13054E67B$' -around$bandata: - - - crtinit - crtclr - crtlc 1,1 - sbanner argv -; version wrnmsg,errmsg - - lda 80h - cpi 0 - jnz no$usage - print crlf - printf 'usage - findfile ' - jmp all$done -no$usage: - - - memcpy work$fcb,PRIFCB,32 - - printf 'Finding: ' - memcpy PRIFCB,work$fcb,16 - - mvi a,'$' - sta PRIFCB+9 - print PRIFCB+1 - conout '.' - memcpy PRIFCB,work$fcb,16 - mvi a,'$' - sta PRIFCB+12 - print PRIFCB+9 - print crlf - - ffhaslu - cpi TRUE - jz do$lu - memcpy PRIFCB,work$fcb,32 - mvi c,FOPEN - lxi d,PRIFCB - call BDOS - cpi 255 - jnz single$true - jmp all$done -single$true: - printf 'Found' - jmp all$done - -do$lu: - ffgetlu - sta entry$lu - ; - ffnumlu - sta lu$cnt - ; - mov l,a - mvi h,0 - call pr$d$word - printf ' Logical Units Detected' - print crlf - - mvi a,0 - sta lu$num -loop: - printf 'Scanning Logical Unit ' - lda lu$num - mov l,a - mvi h,0 - call pr$d$word - conout ' ' - - ; set the Logical Unit - lda lu$num - ffsetlu - - ; test for the target file - memcpy PRIFCB,work$fcb,32 - mvi c,FOPEN - lxi d,PRIFCB - call BDOS - sta retcode - - lda retcode - cpi 255 - jz not$yet - conout CR - prfilnam PRIFCB - printf ' ' - printf 'Found on Logical Unit ' - lda lu$num - mov l,a - mvi h,0 - call pr$d$word - conout ',' - conout '(' - lda drv$num - mov c,a - call BISELDSK - lxi b,0 - call BISETTRK - lxi b,11 - call BISETSEC - lxi b,buffer - call BISETDMA - call BIREAD - - mvi a,'$' - sta buffer+128-8-1 - print buffer+128-8-1-16 - conout ')' - - mvi c,FCLOSE - lxi d,PRIFCB - call BDOS - conout LF -not$yet: - conout CR - - ; Check for key hit interrupt scan - mvi c,11 ; get console status - caLL BDOS - cpi 0 - jz nyok ; jump if no key hit - jmp abort ; gracefully exit loop -nyok: - - - lda lu$num - inr a - sta lu$num - ; - lda lu$cnt - dcr a - sta lu$cnt - cpi 0 - jnz loop - - printf ' ' - -abort: conout cr - printf 'Scan Completed ' - -all$done: - lda entry$lu - ffsetlu - - mvi c,RESET$DRIVE ; call to logout drive - lxi d,0ffh - call BDOS - - do$end - - -wrnmsg db 'By the way, this program is newer than the BIOS$' - -errmsg db 'Sorry, this program requires a newer BIOS$' - -crlf db CR,LF -term db '$' - -drv$num ds 1 ; drive code of current drive -lu$cnt ds 1 ; number of slices on drive -lu$num ds 1 ; slice index -entry$lu ds 1 -retcode ds 1 - -work$fcb ds 64 -buffer ds 80h - - - end start diff --git a/branches/s100/Apps/crossdev/FINDFILE.BAT b/branches/s100/Apps/crossdev/FINDFILE.BAT deleted file mode 100644 index 7d480a47..00000000 --- a/branches/s100/Apps/crossdev/FINDFILE.BAT +++ /dev/null @@ -1,12 +0,0 @@ -rem findfile.sub 9/5/2012 dwg - make findfile.com from sources -if not exist findfile.rel z80mu rmac findfile -if not exist printers.rel z80mu rmac printers -if not exist terminal.rel z80mu rmac terminal -if not exist memory.rel z80mu rmac memory -if not exist banner.rel z80mu rmac banner -if not exist identity.rel z80mu rmac identity -if not exist hbios.rel z80mu rmac hbios -if not exist findfile.cpm z80mu link findfile,hbios,identity,banner,memory,printers,terminal -if not exist findfile.cpm copy findfile.com findfile.cpm -dir findfile.cpm - diff --git a/branches/s100/Apps/crossdev/FINDFILE.COM b/branches/s100/Apps/crossdev/FINDFILE.COM deleted file mode 100644 index 44f2a480..00000000 Binary files a/branches/s100/Apps/crossdev/FINDFILE.COM and /dev/null differ diff --git a/branches/s100/Apps/crossdev/FINDFILE.CPM b/branches/s100/Apps/crossdev/FINDFILE.CPM deleted file mode 100644 index 44f2a480..00000000 Binary files a/branches/s100/Apps/crossdev/FINDFILE.CPM and /dev/null differ diff --git a/branches/s100/Apps/crossdev/FINDFILE.SUB b/branches/s100/Apps/crossdev/FINDFILE.SUB deleted file mode 100644 index f5e8e754..00000000 --- a/branches/s100/Apps/crossdev/FINDFILE.SUB +++ /dev/null @@ -1,13 +0,0 @@ -e:rem findfile.sub 9/5/2012 dwg - make findfile.com from sources -era *.bak -era *.prn -rasm80 findfile -rasm80 printers -rasm80 terminal -rasm80 memory -rasm80 banner -rasm80 identity -rasm80 hbios -link80 findfile,hbios,identity,banner,memory,printers,terminal - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FINDFILE.SYM b/branches/s100/Apps/crossdev/FINDFILE.SYM deleted file mode 100644 index 1fb9e6ac..00000000 --- a/branches/s100/Apps/crossdev/FINDFILE.SYM +++ /dev/null @@ -1,10 +0,0 @@ -0103 HEXREF 0113 IDSIG 0115 IDRMJ 0116 IDRMN -0117 IDRUP 0118 IDRTP 0119 IDMON 011A IDDAY -011B IDYR 0120 PRESTK 0122 BEGIN 10A6 PRDWOR -107E PRHBYT 1093 PRHWOR 0C2B XBANNE 0ED6 XSBANN -1117 XCRTIN 11B1 XCRTLC 1122 XCRTCL 08EE XIDENT -105A XMEMCP 105B XMEMSE 08E2 XGETSC 1068 PRHNYB -10B2 PDEC 10D4 PDEC1 10D6 PDEC2 10F2 PDEC3 -146C PDEC4 146D PDEC5 1109 XPRDEC 1271 DR - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FLIP.C b/branches/s100/Apps/crossdev/FLIP.C deleted file mode 100644 index bb740907..00000000 --- a/branches/s100/Apps/crossdev/FLIP.C +++ /dev/null @@ -1,98 +0,0 @@ -/* flip.c 11/17/2012 dwg - reverse the contrast */ - -#include "std.h" -#include "applvers.h" -#include "diagnose.h" - -#define VDA_N8 4 -#define VDAINI 0x40 -#define VDAQRY 0x41 -#define VDARES 0x42 -#define VDASCS 0x43 - -int vdaini(devunit,vidmode,bitmapp) - unsigned int devunit; - unsigned int vidmode; - unsigned int bitmapp; -{ - hregbc = (VDAINI << 8) | devunit; - printf("hregbc = 0x%04x\n",hregbc); - hregde = vidmode; - printf("hregde = 0x%04x\n",hregde); - hreghl = bitmapp; - printf("hreghl = 0x%04x\n",hreghl); - diagnose(); - printf("VDAINI called, return code was 0x%02x\n",hrega); - return hrega; -} - -bitlook() -{ - unsigned char *p; - int ascii,row; - - p = 0x8000; - for(ascii=0;ascii<256;ascii++) { - printf("ascii = 0x%02x ",ascii); - for(row=0l;row<8;row++) { - printf("0x%02x ",*p++); - } - printf("\n"); - } -} - -int vdaqry(devunit,bitmapp) - unsigned int devunit; - unsigned int bitmapp; -{ - hregbc = (VDAQRY << 8) | devunit; - printf("hregbc = 0x%04x\n",hregbc); - hreghl = bitmapp; - - if(hreghl != 0x8000) printf("vdaqry says hl != 0x8000\n"); - - diagnose(); - printf("VDAQRY called, status was 0x%02x\n",hrega); - printf(" video mode was 0x%02x\n",hregbc & 255); - printf(" row count was 0x%02x(%d)\n", - (hregde >> 8),(hregde >> 8) ); - printf(" column count was 0x%02x(%d)\n", - hregde & 255, hregde & 255); - -/* if(0 != bitmapp) { - printf("vdaqry called with bitmap pointer\n"); - bitlook(); - } -*/ - - return hrega; -} - - -int main(argc,argv) - int argc; - char *argv[]; -{ - unsigned char * p; - unsigned char byte; - int offs; - int retcode; - - printf("flip.com(c) 11/15/2012 dwg - \n\n"); - - retcode = vdaqry(VDA_N8 << 4,0x8000); - - p = 0x8000; - for(offs=0;offs<256*8;offs++) { - byte = *p; - byte = byte ^ 255; - *p = byte; - p++; - } - -/* bitlook(); */ - - vdaini(VDA_N8 << 4, 0, 0x8000); -} - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FLIP.SUB b/branches/s100/Apps/crossdev/FLIP.SUB deleted file mode 100644 index ab25bd36..00000000 --- a/branches/s100/Apps/crossdev/FLIP.SUB +++ /dev/null @@ -1,5 +0,0 @@ -cc flip -as flip -as diagnose -ln flip.o diagnose.o -lc - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FORM.C b/branches/s100/Apps/crossdev/FORM.C deleted file mode 100644 index 8bae233c..00000000 --- a/branches/s100/Apps/crossdev/FORM.C +++ /dev/null @@ -1,107 +0,0 @@ -/* form.c 8/21/2012 dwg - */ - - -#define MAXDRIVE 8 -#include "cpm80.h" -#include "cpmbdos.h" -#include "bdoscall.h" -#include "cpmappl.h" -#include "applvers.h" -#include "cnfgdata.h" -#include "syscfg.h" - - -#define BDOS 5 /* memory address of BDOS invocation */ -#define HIGHSEG 0x0C000 /* memory address of system config */ -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - - -struct SYSCFG * pSYSCFG = HIGHSEG; - -#define FRMFLDS 2 -#define FRSTLIN 6 -#define VISCOL 3 -#define VISSIZ 6 -#define VALCOL (VISCOL+VISSIZ+4) -#define VALSIZ 32 - -struct FORM { - int visline; - int viscol; - int vissize; - char visible[VISSIZ+1]; - int valline; - int valcol; - char value[VALSIZ+1]; -} form[FRMFLDS] = { - { FRSTLIN, VISCOL, VISSIZ, "field1", FRSTLIN, VALCOL, "default1" }, - { FRSTLIN+1, VISCOL, VISSIZ, "field2", FRSTLIN+1, VALCOL, "default2" } -}; - - -int main(argc,argv) - int argc; - char *argv[]; -{ - int i,j; - char buffer[VALSIZ+2]; - - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the NBIOS function */ - pSYSCFG = HIGHSEG; - - crtinit(pSYSCFG->cnfgdata.termtype); - crtclr(); - crtlc(0,0); - - banner("FORM"); - - for(i=0;i -#include "ascii.h" - -main() -{ - printf("%c",ASCII_FF); -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/FORMFEED.SUB b/branches/s100/Apps/crossdev/FORMFEED.SUB deleted file mode 100644 index 67b4bbec..00000000 --- a/branches/s100/Apps/crossdev/FORMFEED.SUB +++ /dev/null @@ -1,4 +0,0 @@ -cc formfeed -as formfeed -ln formfeed.o -lc - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/GETCFG.ASM b/branches/s100/Apps/crossdev/GETCFG.ASM deleted file mode 100644 index 5d88ce09..00000000 --- a/branches/s100/Apps/crossdev/GETCFG.ASM +++ /dev/null @@ -1,219 +0,0 @@ - extrn .begin,.chl,.swt - extrn csave,cret,.move - DSEG - public pPriFcb_ -pPriFcb_: - DW 92 - CSEG - DSEG - public pSecFcb_ -pSecFcb_: - DW 108 - CSEG - DSEG - public pDefBuf_ -pDefBuf_: - DW 128 - CSEG - DSEG - public pBIOS_ -pBIOS_: - DW -6656 - CSEG - global pDPB_,2 - global pDPH_,2 - global pINFOLIS_,2 - global pCNFGDAT_,2 - DSEG - public pSYSCFG_ -pSYSCFG_: - DW -16384 - CSEG - PUBLIC main_ -main_: lxi d,.2 - call csave - LXI H,-4096 - SHLD hregbc_ - LXI H,-16384 - SHLD hregde_ - CALL diagnose_ - LHLD pSYSCFG_ - LXI D,68 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,.1+0 - PUSH H - CALL printf_ - POP D - POP D - LHLD pSYSCFG_ - LXI D,68 - DAD D - MOV E,M - MVI D,0 - PUSH D - CALL crtinit_ - POP D - CALL crtclr_ - LXI H,0 - PUSH H - LXI H,0 - PUSH H - CALL crtlc_ - POP D - POP D - LHLD pBIOS_ - LXI D,78 - DAD D - MOV E,M - MVI D,0 - PUSH D - LHLD pBIOS_ - LXI D,77 - DAD D - MOV E,M - MVI D,0 - PUSH D - LHLD pBIOS_ - LXI D,76 - DAD D - MOV E,M - MVI D,0 - PUSH D - LHLD pBIOS_ - LXI D,75 - DAD D - MOV E,M - MVI D,0 - PUSH D - LXI H,2012 - PUSH H - LXI H,23 - PUSH H - LXI H,7 - PUSH H - LXI H,.1+10 - PUSH H - CALL printf_ - XCHG - LXI H,16 - DAD SP - SPHL - LXI H,.1+93 - PUSH H - LXI H,.1+82 - PUSH H - CALL fopen_ - POP D - POP D - XCHG - LXI H,2-.2 - DAD SP - MOV M,E - INX H - MOV M,D - LXI H,2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - LXI H,256 - PUSH H - LXI H,1 - PUSH H - LXI H,-16384 - PUSH H - CALL fwrite_ - XCHG - LXI H,8 - DAD SP - SPHL - LXI H,2-.2 - DAD SP - MOV E,M - INX H - MOV D,M - PUSH D - CALL fclose_ - POP D - LXI H,0 - PUSH H - LXI H,0 - PUSH H - LXI H,0 - PUSH H - LXI H,-6596 - PUSH H - CALL asmif_ - XCHG - LXI H,8 - DAD SP - SPHL - LHLD xreghl_ - SHLD pINFOLIS_ - LXI H,0 - PUSH H - LXI H,0 - PUSH H - LXI H,25 - PUSH H - LXI H,5 - PUSH H - CALL asmif_ - XCHG - LXI H,8 - DAD SP - SPHL - LXI H,0 - PUSH H - LXI H,0 - PUSH H - LDA xrega_ - MOV L,A - MVI H,0 - PUSH H - LXI H,-6629 - PUSH H - CALL asmif_ - XCHG - LXI H,8 - DAD SP - SPHL - LHLD xreghl_ - SHLD pDPH_ - LHLD pDPH_ - LXI D,10 - DAD D - MOV E,M - INX H - MOV D,M - XCHG - SHLD pDPB_ - RET -.2 EQU -2 -.1: - DB 84,84,32,105,115,32,37,100,10,0,71,69,84,67,70 - DB 71,46,67,79,77,32,37,100,47,37,100,47,37,100,32 - DB 37,100,46,37,100,46,37,100,46,37,100,32,100,119,103 - DB 32,45,32,69,108,101,103,97,110,116,108,121,32,69,120 - DB 112,114,101,115,115,101,100,32,67,80,47,77,32,80,114 - DB 111,103,114,97,109,10,0,115,121,115,99,102,103,46,98 - DB 105,110,0,119,0 - extrn fclose_ - extrn fwrite_ - extrn printf_ - extrn asmif_ - extrn xreghl_ - extrn xrega_ - extrn diagnose_ - extrn hregde_ - extrn hregbc_ - extrn crtlc_ - extrn crtclr_ - extrn crtinit_ - extrn fopen_ - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/GETCFG.C b/branches/s100/Apps/crossdev/GETCFG.C deleted file mode 100644 index 72fa186d..00000000 --- a/branches/s100/Apps/crossdev/GETCFG.C +++ /dev/null @@ -1,333 +0,0 @@ -/* test.c 7/23/2012 dwg - */ - -#include "stdio.h" -#include "applvers.h" -#include "ctermcap.h" - -/* declarations for HBIOS access */ -extern char hrega; -extern unsigned int hregbc; -extern unsigned int hregde; -extern unsigned int hreghl; -extern diagnose(); - -/* declaration dir BIOS and BDOS and low level calls */ -extern char xrega; -extern unsigned int xregbc; -extern unsigned int xregde; -extern unsigned int xreghl; -extern asmif(); /* asmif(0x0E6**,bc,de,hl); */ - -#define BDOS 5 /* memory address of BDOS invocation */ -#define PRIFCB 0x5C /* memory address of primary FCB */ -#define SECFCB 0x6C /* memory address of secondary FCB */ -#define DEFBUF 0x80 /* memory address of default buffer */ -#define HIGHSEG 0x0C000 /* memory address of system config */ - -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - -#define TERMCPM 0 /* BDOS function for System Reset */ -#define CONIN 1 /* BDOS function for Console Input */ -#define CWRITE 2 /* BDOS function for Console Output */ -#define DIRCONIO 6 /* BDOS function for Direct Console I/O */ -#define PRINTSTR 9 /* BDOS function for Print String */ -#define RDCONBUF 10 /* BDOS function for Buffered Console Read */ -#define GETCONST 11 /* BDOS function for Get Console Status */ -#define RETVERNUM 12 /* BDOS function for Return Version Number */ -#define RESDISKSYS 13 /* BDOS function for Reset Disk System */ -#define SELECTDISK 14 /* BDOS function for Select Disk */ -#define FOPEN 15 /* BDOS function for File Open */ -#define FCLOSE 16 /* BDOS function for File Close */ -#define SEARCHFIRST 17 /* BDOS function for Search First */ -#define SEARCHNEXT 18 /* BDOS function for Search Next */ -#define FDELETE 19 /* BDOS function for File Delete */ -#define FREADSEQ 20 /* BDOS function for File Read Sequential */ -#define FWRITESEQ 21 /* BDOS function for File Write Sequential */ -#define FMAKEFILE 22 /* BDOS function for File Make */ -#define FRENAME 23 /* BDOS function for File Rename */ -#define RETLOGINVEC 24 /* BDOS function for Return Login Vector */ -#define RETCURRDISK 25 /* BDOS function for Return Current Disk */ -#define SETDMAADDR 26 /* BDOS function for Set DMA Address */ -#define GETALLOCVEC 27 /* BDOS function for Get Allocation Vector */ -#define WRPROTDISK 28 /* BDOS function for Write Protect Disk */ -#define GETROVECTOR 29 /* BDOS function for Get Read Only Vector */ -#define FSETATTRIB 30 /* BDOS function for File Set Attribute */ -#define GETDPBADDR 31 /* BDOS function for Get DPB Address */ -#define SETGETUSER 32 /* BDOS function for Set & Get User Number */ -#define FREADRANDOM 33 /* BDOS function for File Read Random */ -#define FWRITERAND 34 /* BDOS function for File Write Random */ -#define FCOMPSIZE 35 /* BDOS function for File Compare Size */ -#define SETRANDREC 36 /* BDOS function for Set Random Record # */ -#define RESETDRIVE 37 /* BDOS function for Reset Drive */ -#define WRRANDFILL 38 /* BDOS function for Write Random w/ Fill */ - -#define BDOSDEFDR 0 /* BDOS Default (current) Drive Number */ -#define BDOSDRA 1 /* BDOS Drive A: number */ -#define BDOSDRB 2 /* BDOS Drive B: number */ -#define BDOSDRC 3 /* BDOS Drive C: number */ -#define BDOSDRD 4 /* BDOS Drive D: number */ -#define BDOSDRE 5 /* BDOS Drive E: number */ -#define BDOSDRF 6 /* BDOS Drive F: number */ -#define BDOSDRG 7 /* BDOS Drive G: number */ -#define BDOSDRH 8 /* BDOS Drive H: number */ - -#define BIOSDRA 0 /* BIOS Drive A: number */ -#define BIOSDRB 1 /* BIOS Drive B: number */ -#define BIOSDRC 2 /* BIOS Drive C: number */ -#define BIOSDRD 3 /* BIOS Drive D: number */ -#define BIOSDRE 4 /* BIOS Drive E: number */ -#define BIOSDRF 5 /* BIOS Drive F: number */ -#define BIOSDRG 6 /* BIOS Drive G: number */ -#define BIOSDRH 7 /* BIOS Drive H: number */ - -struct FCB { - char drive; /* BDOS Drive Code */ - char filename[8]; /* space padded file name */ - char filetype[3]; /* space padded file extension */ - char filler[24]; /* remainder of FCB */ -}; - -struct FCB * pPriFcb = PRIFCB; /* pointer to Primary FCB structure */ - -struct FCB * pSecFcb = SECFCB; /* pointer to secondary FCB structure */ - -struct { - char length; /* length of commad tail */ - char tail[127]; /* command tail */ -} * pDefBuf = DEFBUF; - - -#define CURDRV 0x00004 -#define BIOSAD 0x0e600 /* base address of BIOS jumps */ - -/* addresses of BIOS jumps */ -#define pBOOT 0x0E600 -#define pWBOOT 0x0E603 -#define pCONST 0x0E606 -#define pCONIN 0x0E609 -#define pCONOUT 0x0E60C -#define pLIST 0x0E60F -#define pPUNCH 0x0E612 -#define pREADER 0x0E615 -#define pHOME 0x0E618 -#define pSELDSK 0x0E61B -#define pSETTRK 0x0E61E -#define pSETSEC 0x0E621 -#define pSETDMA 0x0E624 -#define pREAD 0x0E627 -#define pWRITE 0x0E62A -#define pLISTST 0x0E62D -#define pSECTRN 0x0E630 -#define pBNKSEL 0x0E633 -#define pGETLU 0x0E636 -#define pSETLU 0x0E639 -#define pGETINFO 0x0E63C - -struct JMP { - unsigned char opcode; /* JMP opcode */ - unsigned int address; /* JMP address */ -}; - -struct BIOS { - struct JMP boot; - struct JMP wboot; - struct JMP const; - struct JMP conin; - struct JMP conout; - struct JMP list; - struct JMP punch; - struct JMP reader; - struct JMP home; - struct JMP seldsk; - struct JMP settrk; - struct JMP setsec; - struct JMP setdma; - struct JMP read; - struct JMP write; - struct JMP listst; - struct JMP sectrn; - struct JMP bnksel; - struct JMP getlu; - struct JMP setlu; - struct JMP getinfo; - struct JMP rsvd1; - struct JMP rsvd2; - struct JMP rsvd3; - struct JMP rsvd4; - - char rmj; - char rmn; - char rup; - char rtp; - -} * pBIOS = 0xe600; - -/* pointer based Disk Parameter Block structure */ -struct DPB { - unsigned int spt; - unsigned char bsh; - unsigned char blm; - unsigned char exm; - unsigned int dsm; - unsigned int drm; - unsigned char al0; - unsigned int cks; - unsigned int off; -} * pDPB; - -/* pointer based Disk Parameter Header structure */ -struct DPH { - unsigned int xlt; - unsigned int rv1; - unsigned int rv2; - unsigned int rv3; - unsigned int dbf; - struct DPB * pDpb; - unsigned int csv; - unsigned int alv; - unsigned char sigl; - unsigned char sigu; - unsigned int current; - unsigned int number; -} * pDPH; - -/* pointer based Information List structure */ -struct INFOLIST { - int version; - void * banptr; - void * varloc; - void * tstloc; - void * dpbmap; - void * dphmap; - void * ciomap; -} * pINFOLIST; - -/* pointer based Configuration Data structure */ -struct CNFGDATA { - unsigned char rmj; - unsigned char rmn; - unsigned char rup; - unsigned char rtp; - unsigned char diskboot; - unsigned char devunit; - unsigned int bootlu; - unsigned char hour; - unsigned char minute; - unsigned char second; - unsigned char month; - unsigned char day; - unsigned char year; - unsigned char freq; - unsigned char platform; - unsigned char dioplat; - unsigned char vdumode; - unsigned int romsize; - unsigned int ramsize; - unsigned char clrramdk; - unsigned char dskyenable; - unsigned char uartenable; - unsigned char vduenable; - unsigned char fdenable; - unsigned char fdtrace; - unsigned char fdmedia; - unsigned char fdmediaalt; - unsigned char fdmauto; - unsigned char ideenable; - unsigned char idetrace; - unsigned char ide8bit; - unsigned int idecapacity; - unsigned char ppideenable; - unsigned char ppidetrace; - unsigned char ppide8bit; - unsigned int ppidecapacity; - unsigned char ppideslow; - unsigned char boottype; - unsigned char boottimeout; - unsigned char bootdefault; - unsigned int baudrate; - unsigned char ckdiv; - unsigned char memwait; - unsigned char iowait; - unsigned char cntlb0; - unsigned char cntlb1; - unsigned char sdenable; - unsigned char sdtrace; - unsigned int sdcapacity; - unsigned char sdcsio; - unsigned char sdcsiofast; - unsigned char defiobyte; - unsigned char termtype; - unsigned int revision; - unsigned char prpsdenable; - unsigned char prpsdtrace; - unsigned int prpsdcapacity; - unsigned char prpconenable; - unsigned int biossize; - unsigned char pppenable; - unsigned char pppsdenable; - unsigned char pppsdtrace; - unsigned int pppsdcapacity; - unsigned char pppconenable; - unsigned char prpenable; -} * pCNFGDATA; - - -struct JMP_TAG { - unsigned char opcode; - unsigned int address; -}; - - -/* pointer based System Configuration structure */ -struct SYSCFG { - struct JMP_TAG jmp; - void * cnfloc; - void * tstloc; - void * varloc; - struct CNFGDATA cnfgdata; - char filler[256-3-2-2-2-sizeof(struct CNFGDATA)]; -} * pSYSCFG = HIGHSEG; - - -main(argc,argv) - int argc; - char *argv[]; -{ - FILE * fd; - - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the NBIOS function */ - - printf("TT is %d\n",pSYSCFG->cnfgdata.termtype); - - crtinit(pSYSCFG->cnfgdata.termtype); - crtclr(); - crtlc(0,0); - - printf( - "GETCFG.COM %d/%d/%d %d.%d.%d.%d dwg - Elegantly Expressed CP/M Program\n", - A_MONTH,A_DAY,A_YEAR, - pBIOS->rmj,pBIOS->rmn,pBIOS->rup,pBIOS->rtp); - - fd = fopen("syscfg.bin","w"); - fwrite(HIGHSEG,1,256,fd); - fclose(fd); - - - - asmif(pGETINFO,0,0,0); /* get addr of the information list */ - pINFOLIST = xreghl; /* set base pointer of the structure */ - - asmif(BDOS,RETCURRDISK,0,0); /* get current drive into xrega */ - asmif(pSELDSK,xrega,0,0); /* get DPH of current drive */ - pDPH = xreghl; /* establish addressability to DPH */ - pDPB = pDPH->pDpb; /* establish addressability to DPB */ - -/* printf("spt is %d\n",pDPB->spt); */ /* demonstrate DPB access */ - - - -} - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/GLOBALS.H b/branches/s100/Apps/crossdev/GLOBALS.H deleted file mode 100644 index 58976394..00000000 --- a/branches/s100/Apps/crossdev/GLOBALS.H +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************/ -/* globals.h 9/4/2012 dwg - increase MAXDRIVE to 12 */ -/* globals.h 3/11/2012 dwg - add BIOS_ADDR */ -/* globals.h 3/11/2012 dwg - declarations common to all modules */ -/****************************************************************/ - -#define CR 0x0d -#define LF 0x0a -#define ESC 27 - -#define BIOSAD 0x0e600 -#define INFLSTV 1 - -#define MAXDRIVE 12 - -/*******************/ -/* eof - globals.h */ -/*******************/ \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/GLOBALS.LIB b/branches/s100/Apps/crossdev/GLOBALS.LIB deleted file mode 100644 index 152e55f4..00000000 --- a/branches/s100/Apps/crossdev/GLOBALS.LIB +++ /dev/null @@ -1,18 +0,0 @@ -; globals.lib 7/19/2012 dwg - update for 2.0.0.0 B22 -; globals.lib 1/18/2012 dwg - program globals - -ENGLISH equ TRUE -SPANISH equ FALSE - -MAX$LABEL equ 16 -STACK$SIZE equ 512 - -COLON equ ':' - -stack macro - ds STACK$SIZE -stack$top: - endm - -; eof - globals.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HARDWARE.LIB b/branches/s100/Apps/crossdev/HARDWARE.LIB deleted file mode 100644 index 3503e99e..00000000 --- a/branches/s100/Apps/crossdev/HARDWARE.LIB +++ /dev/null @@ -1,16 +0,0 @@ -; hardware.lib 1/18/2012 dwg - hardware declarations -HASZ80 equ TRUE - -; I/O address of Zeta RTC -zeta$rtc equ 70h -; write bit definitions -z$rtc$ce equ 10h -z$rtc$we equ 20h -z$rtc$clk equ 40h -z$rtc$inp equ 80h -; read bit definitions -z$rtc$out equ 01h -z$rtc$cfg equ 40h - -; eof - hardware.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HBIOS.ASM b/branches/s100/Apps/crossdev/HBIOS.ASM deleted file mode 100644 index 50d43a0f..00000000 --- a/branches/s100/Apps/crossdev/HBIOS.ASM +++ /dev/null @@ -1,18 +0,0 @@ -; hbios.asm 7/19/2012 dwg - - -CFGVERS equ 0 - - public xgetsc -xgetsc: - enter - mvi b,0F0h - mvi c,CFGVERS - lxi d,8000h - db 0cfh ; rst 8 - lxi h,8000h - leave - ret - - - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HBIOS.H b/branches/s100/Apps/crossdev/HBIOS.H deleted file mode 100644 index e56562c8..00000000 --- a/branches/s100/Apps/crossdev/HBIOS.H +++ /dev/null @@ -1,48 +0,0 @@ -/* hbios.h 7/4/2012 dgw - */ - -/* CIO */ - -/* Character Input (CIOIN) */ - -/* Character Output (CIOOUT) */ - -/* Character Input Status (CIOIST) */ - -/* Character Output Status (CIOOST) */ - -/* DIO */ - -/* Disk Read (DIORD) */ - -/* Disk Write (DIOWR) */ - -/* Disk Status (DIOST) */ - -/* Disk Media (DIOMED) */ - -/* Disk Idetify (DIOID) */ - -/* Disk Get Buffer Address (DIOGBA) */ - - - - -/* - extern char hrega; - extern unsigned int hregbc; - extern unsigned int hregde; - extern unsigned int hreghl; - extern diagnose(); -*/ - - - - - -/*****************/ -/* eof - hbios.h */ -/*****************/ - - - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HBIOS.LIB b/branches/s100/Apps/crossdev/HBIOS.LIB deleted file mode 100644 index 166327be..00000000 --- a/branches/s100/Apps/crossdev/HBIOS.LIB +++ /dev/null @@ -1,3 +0,0 @@ -; hbios.lib 7/19/2012 dwg - - extrn xgetsc - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HBIOS.SYM b/branches/s100/Apps/crossdev/HBIOS.SYM deleted file mode 100644 index 4285f164..00000000 --- a/branches/s100/Apps/crossdev/HBIOS.SYM +++ /dev/null @@ -1,2 +0,0 @@ -0000 CFGVERS 0000 ENTER 000B LEAVE 0000 XGETSC - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HELLO.C b/branches/s100/Apps/crossdev/HELLO.C deleted file mode 100644 index daff6af1..00000000 --- a/branches/s100/Apps/crossdev/HELLO.C +++ /dev/null @@ -1,333 +0,0 @@ -/* test.c 7/21/2012 dwg - */ - -#include "stdio.h" -#include "applvers.h" - -/* declarations for HBIOS access */ -extern char hrega; -extern unsigned int hregbc; -extern unsigned int hregde; -extern unsigned int hreghl; -extern diagnose(); - -/* declaration dir BIOS and BDOS and low level calls */ -extern char xrega; -extern unsigned int xregbc; -extern unsigned int xregde; -extern unsigned int xreghl; -extern asmif(); /* asmif(0x0E6**,bc,de,hl); */ - -#define BDOS 5 /* memory address of BDOS invocation */ -#define PRIFCB 0x5C /* memory address of primary FCB */ -#define SECFCB 0x6C /* memory address of secondary FCB */ -#define DEFBUF 0x80 /* memory address of default buffer */ -#define HIGHSEG 0x0C000 /* memory address of system config */ - -#define GETSYSCFG 0x0F000 /* HBIOS function for Get System Configuration */ - -#define TERMCPM 0 /* BDOS function for System Reset */ -#define CONIN 1 /* BDOS function for Console Input */ -#define CWRITE 2 /* BDOS function for Console Output */ -#define DIRCONIO 6 /* BDOS function for Direct Console I/O */ -#define PRINTSTR 9 /* BDOS function for Print String */ -#define RDCONBUF 10 /* BDOS function for Buffered Console Read */ -#define GETCONST 11 /* BDOS function for Get Console Status */ -#define RETVERNUM 12 /* BDOS function for Return Version Number */ -#define RESDISKSYS 13 /* BDOS function for Reset Disk System */ -#define SELECTDISK 14 /* BDOS function for Select Disk */ -#define FOPEN 15 /* BDOS function for File Open */ -#define FCLOSE 16 /* BDOS function for File Close */ -#define SEARCHFIRST 17 /* BDOS function for Search First */ -#define SEARCHNEXT 18 /* BDOS function for Search Next */ -#define FDELETE 19 /* BDOS function for File Delete */ -#define FREADSEQ 20 /* BDOS function for File Read Sequential */ -#define FWRITESEQ 21 /* BDOS function for File Write Sequential */ -#define FMAKEFILE 22 /* BDOS function for File Make */ -#define FRENAME 23 /* BDOS function for File Rename */ -#define RETLOGINVEC 24 /* BDOS function for Return Login Vector */ -#define RETCURRDISK 25 /* BDOS function for Return Current Disk */ -#define SETDMAADDR 26 /* BDOS function for Set DMA Address */ -#define GETALLOCVEC 27 /* BDOS function for Get Allocation Vector */ -#define WRPROTDISK 28 /* BDOS function for Write Protect Disk */ -#define GETROVECTOR 29 /* BDOS function for Get Read Only Vector */ -#define FSETATTRIB 30 /* BDOS function for File Set Attribute */ -#define GETDPBADDR 31 /* BDOS function for Get DPB Address */ -#define SETGETUSER 32 /* BDOS function for Set & Get User Number */ -#define FREADRANDOM 33 /* BDOS function for File Read Random */ -#define FWRITERAND 34 /* BDOS function for File Write Random */ -#define FCOMPSIZE 35 /* BDOS function for File Compare Size */ -#define SETRANDREC 36 /* BDOS function for Set Random Record # */ -#define RESETDRIVE 37 /* BDOS function for Reset Drive */ -#define WRRANDFILL 38 /* BDOS function for Write Random w/ Fill */ - -#define BDOSDEFDR 0 /* BDOS Default (current) Drive Number */ -#define BDOSDRA 1 /* BDOS Drive A: number */ -#define BDOSDRB 2 /* BDOS Drive B: number */ -#define BDOSDRC 3 /* BDOS Drive C: number */ -#define BDOSDRD 4 /* BDOS Drive D: number */ -#define BDOSDRE 5 /* BDOS Drive E: number */ -#define BDOSDRF 6 /* BDOS Drive F: number */ -#define BDOSDRG 7 /* BDOS Drive G: number */ -#define BDOSDRH 8 /* BDOS Drive H: number */ - -#define BIOSDRA 0 /* BIOS Drive A: number */ -#define BIOSDRB 1 /* BIOS Drive B: number */ -#define BIOSDRC 2 /* BIOS Drive C: number */ -#define BIOSDRD 3 /* BIOS Drive D: number */ -#define BIOSDRE 4 /* BIOS Drive E: number */ -#define BIOSDRF 5 /* BIOS Drive F: number */ -#define BIOSDRG 6 /* BIOS Drive G: number */ -#define BIOSDRH 7 /* BIOS Drive H: number */ - -struct FCB { - char drive; /* BDOS Drive Code */ - char filename[8]; /* space padded file name */ - char filetype[3]; /* space padded file extension */ - char filler[24]; /* remainder of FCB */ -}; - -struct FCB * pPriFcb = PRIFCB; /* pointer to Primary FCB structure */ - -struct FCB * pSecFcb = SECFCB; /* pointer to secondary FCB structure */ - -struct { - char length; /* length of commad tail */ - char tail[127]; /* command tail */ -} * pDefBuf = DEFBUF; - - -#define CURDRV 0x00004 -#define BIOSAD 0x0e600 /* base address of BIOS jumps */ - -/* addresses of BIOS jumps */ -#define pBOOT 0x0E600 -#define pWBOOT 0x0E603 -#define pCONST 0x0E606 -#define pCONIN 0x0E609 -#define pCONOUT 0x0E60C -#define pLIST 0x0E60F -#define pPUNCH 0x0E612 -#define pREADER 0x0E615 -#define pHOME 0x0E618 -#define pSELDSK 0x0E61B -#define pSETTRK 0x0E61E -#define pSETSEC 0x0E621 -#define pSETDMA 0x0E624 -#define pREAD 0x0E627 -#define pWRITE 0x0E62A -#define pLISTST 0x0E62D -#define pSECTRN 0x0E630 -#define pBNKSEL 0x0E633 -#define pGETLU 0x0E636 -#define pSETLU 0x0E639 -#define pGETINFO 0x0E63C - -struct JMP { - unsigned char opcode; /* JMP opcode */ - unsigned int address; /* JMP address */ -}; - -struct BIOS { - struct JMP boot; - struct JMP wboot; - struct JMP const; - struct JMP conin; - struct JMP conout; - struct JMP list; - struct JMP punch; - struct JMP reader; - struct JMP home; - struct JMP seldsk; - struct JMP settrk; - struct JMP setsec; - struct JMP setdma; - struct JMP read; - struct JMP write; - struct JMP listst; - struct JMP sectrn; - struct JMP bnksel; - struct JMP getlu; - struct JMP setlu; - struct JMP getinfo; - struct JMP rsvd1; - struct JMP rsvd2; - struct JMP rsvd3; - struct JMP rsvd4; - - char rmj; - char rmn; - char rup; - char rtp; - -} * pBIOS = 0xe600; - -/* pointer based Disk Parameter Block structure */ -struct DPB { - unsigned int spt; - unsigned char bsh; - unsigned char blm; - unsigned char exm; - unsigned int dsm; - unsigned int drm; - unsigned char al0; - unsigned int cks; - unsigned int off; -} * pDPB; - -/* pointer based Disk Parameter Header structure */ -struct DPH { - unsigned int xlt; - unsigned int rv1; - unsigned int rv2; - unsigned int rv3; - unsigned int dbf; - struct DPB * pDpb; - unsigned int csv; - unsigned int alv; - unsigned char sigl; - unsigned char sigu; - unsigned int current; - unsigned int number; -} * pDPH; - -/* pointer based Information List structure */ -struct INFOLIST { - int version; - void * banptr; - void * varloc; - void * tstloc; - void * dpbmap; - void * dphmap; - void * ciomap; -} * pINFOLIST; - -/* pointer based Configuration Data structure */ -struct CNFGDATA { - unsigned char rmj; - unsigned char rmn; - unsigned char rup; - unsigned char rtp; - unsigned char diskboot; - unsigned char devunit; - unsigned int bootlu; - unsigned char hour; - unsigned char minute; - unsigned char second; - unsigned char month; - unsigned char day; - unsigned char year; - unsigned char freq; - unsigned char platform; - unsigned char dioplat; - unsigned char vdumode; - unsigned int romsize; - unsigned int ramsize; - unsigned char clrramdk; - unsigned char dskyenable; - unsigned char uartenable; - unsigned char vduenable; - unsigned char fdenable; - unsigned char fdtrace; - unsigned char fdmedia; - unsigned char fdmediaalt; - unsigned char fdmauto; - unsigned char ideenable; - unsigned char idetrace; - unsigned char ide8bit; - unsigned int idecapacity; - unsigned char ppideenable; - unsigned char ppidetrace; - unsigned char ppide8bit; - unsigned int ppidecapacity; - unsigned char ppideslow; - unsigned char boottype; - unsigned char boottimeout; - unsigned char bootdefault; - unsigned int baudrate; - unsigned char ckdiv; - unsigned char memwait; - unsigned char iowait; - unsigned char cntlb0; - unsigned char cntlb1; - unsigned char sdenable; - unsigned char sdtrace; - unsigned int sdcapacity; - unsigned char sdcsio; - unsigned char sdcsiofast; - unsigned char defiobyte; - unsigned char termtype; - unsigned int revision; - unsigned char prpsdenable; - unsigned char prpsdtrace; - unsigned int prpsdcapacity; - unsigned char prpconenable; - unsigned int biossize; - unsigned char pppenable; - unsigned char pppsdenable; - unsigned char pppsdtrace; - unsigned int pppsdcapacity; - unsigned char pppconenable; - unsigned char prpenable; -} * pCNFGDATA; - - -struct JMP_TAG { - unsigned char opcode; - unsigned int address; -}; - - -/* pointer based System Configuration structure */ -struct SYSCFG { - struct JMP_TAG jmp; - void * cnfloc; - void * tstloc; - void * varloc; - struct CNFGDATA cnfgdata; - char filler[256-3-2-2-2-sizeof(struct CNFGDATA)]; -} * pSYSCFG = HIGHSEG; - - -main(argc,argv) - int argc; - char *argv[]; -{ - - - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the NBIOS function */ - pSYSCFG = HIGHSEG; - - crtinit(pSYSCFG->cnfgdata.termtype); - crtclr(); - crtlc(0,0); - -/* printf("TT is %d\n",pSYSCFG->cnfgdata.termtype); */ - - - printf( - "TEST.COM %d/%d/%d %d.%d.%d.%d dwg - Elegantly Expressed CP/M Program\n", - A_MONTH,A_DAY,A_YEAR, - pBIOS->rmj,pBIOS->rmn,pBIOS->rup,pBIOS->rtp); - - asmif(pGETINFO,0,0,0); /* get addr of the information list */ - pINFOLIST = xreghl; /* set base pointer of the structure */ - - asmif(BDOS,RETCURRDISK,0,0); /* get current drive into xrega */ - asmif(pSELDSK,xrega,0,0); /* get DPH of current drive */ - pDPH = xreghl; /* establish addressability to DPH */ - pDPB = pDPH->pDpb; /* establish addressability to DPB */ - -/* printf("spt is %d\n",pDPB->spt); */ /* demonstrate DPB access */ - - hregbc = GETSYSCFG; /* function = Get System Config */ - hregde = HIGHSEG; /* addr of dest (must be high) */ - diagnose(); /* invoke the NBIOS function */ - -/* printf("TT is %d\n",pSYSCFG->cnfgdata.termtype); */ - - -} - - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HELP.ASM b/branches/s100/Apps/crossdev/HELP.ASM deleted file mode 100644 index 00f63941..00000000 --- a/branches/s100/Apps/crossdev/HELP.ASM +++ /dev/null @@ -1,17 +0,0 @@ - extrn .begin,.chl,.swt - extrn csave,cret,.move - PUBLIC main_ -main_: lxi d,.2 - call csave - LXI H,.1+0 - PUSH H - CALL printf_ - POP D - LXI H,0 - RET -.2 EQU 0 -.1: - DB 72,101,108,112,32,87,111,114,108,100,33,33,10,0 - extrn printf_ - END - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/HELP.C b/branches/s100/Apps/crossdev/HELP.C deleted file mode 100644 index 0541cc1e..00000000 --- a/branches/s100/Apps/crossdev/HELP.C +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -int main(argc,argv) - int argc; - char * argv[]; -{ - printf("Help World!!\n"); - return 0; -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/IDENT.ASM b/branches/s100/Apps/crossdev/IDENT.ASM deleted file mode 100644 index 9840c850..00000000 --- a/branches/s100/Apps/crossdev/IDENT.ASM +++ /dev/null @@ -1,64 +0,0 @@ - title 'Ident - Display Program Identification' - -; ident.asm 2/21/2012 dwg - review for release 2.0.0.0 -; ident.asm 2/19.2012 dwg - review for release 1.5.1.0 -; ident.asm 2/19/2012 dwg - remove test* & analyse & ws-shim -; ident.asm 2/18/2012 dwg - drives,map and slice become map -; ident.asm 2/14/2012 dwg - superfmt becomes multifmt -; ident.asm 2/13/2012 dwg - add disk -; ident.asm 2/12/2012 dwg - add cleardir and superfmt -; ident.asm 2/11/2012 dwg - Display the Ident of a program file - -; Copyright (C) 2011-2012 Douglas Goodall Licensed under GPL Ver 3. -; -; This file is part of NuBiosDWG and is free software: you can -; redistribute it and/or modify it under the terms of the GNU -; General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. -; This file is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; You should have received a copy of the GNU General Public License -; along with it. If not, see . - - maclib portab - maclib globals - maclib cpmbdos - maclib cpmappl - maclib applvers - maclib banner - maclib printers - maclib dumpmac - maclib memory - maclib identity - - do$start - - idata - - sbanner argv - - ify 'ACCESS COM',TRUE -; ify 'ASSIGN COM',TRUE -; ify 'CPMNAME COM',TRUE -; ify 'ERASE COM',TRUE - ify 'FINDFILECOM',TRUE -; ify 'HEADER COM',TRUE - ify 'IDENT COM',TRUE - ify 'SETLABELCOM',TRUE -; ify 'MAP COM',TRUE -; ify 'METAVIEWCOM',TRUE -; ify 'MULTIFMTCOM',TRUE - ify 'NOACCESSCOM',TRUE -; ify 'PAUSE COM',TRUE -; ify 'REM COM',TRUE -; ify 'REQ1PARMCOM',TRUE -; ify 'STOP COM',TRUE -; ify 'TERMTYPECOM',TRUE -; ify 'WRITESYSCOM',FALSE - - do$end - - end - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/IDENTITY.ASM b/branches/s100/Apps/crossdev/IDENTITY.ASM deleted file mode 100644 index 858d7727..00000000 --- a/branches/s100/Apps/crossdev/IDENTITY.ASM +++ /dev/null @@ -1,196 +0,0 @@ -; identity.asm 2/17/2012 dwg - Program Identity Declarations - - maclib portab - maclib globals - maclib stdlib - maclib cpmbios - maclib cpmbdos - maclib memory - maclib printers - - public x$ident -x$ident: - shld lfcbptr ; save pointer to fcb - - mvi c,FOPEN - lhld lfcbptr - xchg - call BDOS - cpi 255 - jnz openok - -;;; memcpy lname,file1fcb+1,8 - mvi c,8 - lxi d,lname - lhld lfcbptr - inx h - call x$memcpy - - mvi a,',' - sta ldot - -;;; memcpy lext,file1fcb+9,3 - mvi c,3 - lhld lfcbptr - lxi d,9 - dad d - lxi d,lext - call x$memcpy - - - mvi a,'$' - sta lterm - print lname - printf ' -- File Not Found' - mvi a,FAILURE - jmp fini -openok: - - mvi c,SETDMA - lxi d,buffer - call BDOS - - mvi c,READSEQ - lhld lfcbptr - xchg - call BDOS - - - mvi c,SETDMA - lxi d,buffer+128 - call BDOS - - mvi c,READSEQ - lhld lfcbptr - xchg - call BDOS - - mvi c,FCLOSE - lhld lfcbptr - xchg - call BDOS - - lxi d,d$prog - mvi c,9 - call BDOS - - conout ',' - conout ' ' - lda p$rmj - mov l,a - mvi h,0 - call pr$d$word - conout '.' - lda p$rmn - mov l,a - call pr$d$word - conout '.' - lda p$rup - mov l,a - call pr$d$word - conout '.' - lda p$rtp - mov l,a - call pr$d$word - conout ',' - conout ' ' - - lda p$mon - mov l,a - call pr$d$word - conout '/' - lda p$day - mov l,a - call pr$d$word - conout '/' - lhld p$year - call pr$d$word - conout ',' - conout ' ' - - lxi d,d$prod - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$orig - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$ser - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lda d$term2 - cpi '$' - jnz do$name - conout ' ' - lxi d,d$uuid+19 - jmp do$any -do$name: - lxi d,d$name -do$any: - mvi c,9 - call BDOS - - mvi a,SUCCESS ; set return code -fini: - ret - -lfcbptr ds 2 -ldrive ds 1 -lcolon ds 1 -lname ds 8 -ldot ds 1 -lext ds 3 -lterm ds 1 - - db 'buffer-->' -buffer ds 1 -p$start ds 2 -p$hexrf ds 16 -p$sig ds 2 -p$rmj ds 1 -p$rmn ds 1 -p$rup ds 1 -p$rtp ds 1 -p$mon ds 1 -p$day ds 1 -p$year ds 2 -p$argv ds 2 -p$e5 ds 1 -p$pr$st ds 2 -p$code1 ds 3 ; begin: lxi h,0 -p$code2 ds 1 ; dad sp -p$code3 ds 3 ; shld pre$stk -p$code4 ds 3 ; lxi sp,stack$top -p$code5 ds 1 ; nop -p$code6 ds 3 ; jmp around$bandata -p$prog ds 2 ; dw prog -p$dat ds 2 ; dw dat -p$prod ds 2 ; dw prod -p$orig ds 2 ; dw orig -p$ser ds 2 ; dw ser -p$nam ds 2 ; dw nam -p$term ds 2 ; dw 0 -d$prog ds 8+1+3+1 ; db '12345678.123$' -d$date ds 2+1+2+1+4+1 ; db ' 2/11/2012$' -d$ser ds 6+1 ; db '654321$' -d$prod ds 5+1 ; db 'CPM80$' -d$orig ds 3+1 ; db 'DWG$' -d$name ds 1+7+1+1+1+1+7+1 ; db ' Douglas W. Goodall$' -d$uuid ds 36 ; unique user identification -d$term2 ds 1 ; can be set to zero or dollar sign -p$len equ $-buffer -p$rsvd ds 256-p$len - db '<--buffer' - dw p$len -crlf db CR,LF,'$' - -; eof - identity.asm - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/IDENTITY.LIB b/branches/s100/Apps/crossdev/IDENTITY.LIB deleted file mode 100644 index b66e6c3e..00000000 --- a/branches/s100/Apps/crossdev/IDENTITY.LIB +++ /dev/null @@ -1,191 +0,0 @@ -; identity.lib 2/19/2012 dwg - add ify macro -; identity.lib 2/17/2012 dwg - Program Identity Declarations - - extrn x$ident - -ident macro file1fcb - lxi h,file1fcb - call x$ident - endm - -ify macro progname,bool - local done - local file - local fini - ident file - jmp fini - newfcb file,0,progname -fini: mvi a,bool - cpi TRUE - jnz done - conout CR - conout LF -done: - endm - - -identx macro file1fcb - local openok - local identend - - local ldrive,lcolon,lname,ldot,lext,lterm - - mvi c,FOPEN - lxi d,file1fcb - call BDOS - cpi 255 - jnz openok - - memcpy lname,file1fcb+1,8 - mvi a,',' - sta ldot - memcpy lext,file1fcb+9,3 - mvi a,'$' - sta lterm - print lname - printf ' -- File Not Found' - jmp identend -openok: - - mvi c,SETDMA - lxi d,buffer - call BDOS - - mvi c,READSEQ - lxi d,file1fcb - call BDOS - - mvi c,FCLOSE - lxi d,file1fcb - call BDOS - - lxi d,d$prog - mvi c,9 - call BDOS - - conout ',' - conout ' ' - lda p$rmj - mov l,a - mvi h,0 - call pr$d$word - conout '.' - lda p$rmn - mov l,a - call pr$d$word - conout '.' - lda p$rup - mov l,a - call pr$d$word - conout '.' - lda p$rtp - mov l,a - call pr$d$word - conout ',' - conout ' ' - - lda p$mon - mov l,a - call pr$d$word - conout '/' - lda p$day - mov l,a - call pr$d$word - conout '/' - lhld p$year - call pr$d$word - conout ',' - conout ' ' - - lxi d,d$prod - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$orig - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$ser - mvi c,9 - call BDOS - conout ',' - conout ' ' - - lxi d,d$name - mvi c,9 - call BDOS - jmp identend - -ldrive ds 1 -lcolon ds 1 -lname ds 8 -ldot ds 1 -lext ds 3 -lterm ds 1 - -identend: - endm - -idata macro - jmp around$bandata -argv dw prog,dat,prod,orig,ser,myname,0 -prog db 'IDENT.COM $' - date - serial - product - originator - oriname -uuid db '777A67C2-4A92-42D4-80FE-C96FD6483BD2$' - db 'buffer-->' - public buffer,p$start,p$hexrf,p$sig - public p$rmj,p$rmn,p$rup,p$rtp - public p$mon,p$day,p$year -buffer ds 1 -p$start ds 2 -p$hexrf ds 16 -p$sig ds 2 -p$rmj ds 1 -p$rmn ds 1 -p$rup ds 1 -p$rtp ds 1 -p$mon ds 1 -p$day ds 1 -p$year ds 2 -p$argv ds 2 -p$e5 ds 1 -p$pr$st ds 2 -p$code1 ds 3 ; begin: lxi h,0 -p$code2 ds 1 ; dad sp -p$code3 ds 3 ; shld pre$stk -p$code4 ds 3 ; lxi sp,stack$top -p$code5 ds 1 ; nop -p$code6 ds 3 ; jmp around$bandata -p$prog ds 2 ; dw prog -p$dat ds 2 ; dw dat -p$prod ds 2 ; dw prod -p$orig ds 2 ; dw orig -p$ser ds 2 ; dw ser -p$nam ds 2 ; dw nam -p$term ds 2 ; dw 0 -d$prog ds 8+1+3+1 ; db '12345678.123$' -d$date ds 2+1+2+1+4+1 ; db ' 2/11/2012$' -d$ser ds 6+1 ; db '654321$' -d$prod ds 5+1 ; db 'CPM80$' -d$orig ds 3+1 ; db 'DWG$' -d$name ds 1+7+1+1+1+1+7+1 ; db ' Douglas W. Goodall$' -d$uuid ds 37 ; unique user identification -d$term2 ds 1 ; can be set to zero or dollar sign -p$len equ $-buffer -p$rsvd ds 128-p$len - db '<--buffer' -crlf db CR,LF,'$' -around$bandata: - - endm - -; eof - identity.lib - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/IDENTITY.SYM b/branches/s100/Apps/crossdev/IDENTITY.SYM deleted file mode 100644 index 5ecad124..00000000 --- a/branches/s100/Apps/crossdev/IDENTITY.SYM +++ /dev/null @@ -1,35 +0,0 @@ -0009 AL0OFS 000A AL1OFS 000E ALVOFS 0005 BDOS E600 BIBOOT -E609 BICONIN E60C BICONOUT E606 BICONST 0000 BIDRVA 0001 BIDRVB -0002 BIDRVC 0003 BIDRVD 0004 BIDRVE 0005 BIDRVF 0006 BIDRVG -0007 BIDRVH E618 BIHOME E60F BILIST E62D BILISTST E612 BIPUNCH -E627 BIREAD E615 BIREADER E630 BISECTRN E61B BISELDSK E624 BISETDMA -E621 BISETSEC E61E BISETTRK E603 BIWBOOT E62A BIWRITE 0003 BLMOFS -0002 BSHOFS 022F BUFFER 0001 BYTESIZE 000B CKSOFS 003A COLON -000D CR 0001 CREAD 033A CRLF 0020 CROFS 000C CSVOFS -0012 CUROFS 0002 CWRITE 0010 D0OFS 0008 DBFOFS 027A DDATE -0080 DEFBUF 0296 DNAME 020D DOANY 020A DONAME 0292 DORIG -000F DPBLEN 000A DPBOFS 0010 DPHLEN 028C DPROD 026D DPROG -0007 DRMOFS 0000 DROFS 0285 DSER 000D DSKRESET 0005 DSMOFS -02CE DTERM2 02AA DUUID 0001 ENGLISH 001B ESC 0004 EXMOFS -000C EXOFS 0001 F1OFS 0002 F2OFS 0003 F3OFS 0004 F4OFS -0005 F5OFS 0006 F6OFS 0007 F7OFS 0008 F8OFS 0001 FAILURE -0000 FALSE 0024 FCBLEN 0010 FCLOSE 0023 FCOMPSIZE 0013 FDELETE -0214 FINI 0016 FMAKE 000F FOPEN 0017 FRENAME 0218 LCOLON -0221 LDOT 0217 LDRIVE 0020 LENFCB 0222 LEXT 000A LF -0215 LFCBPTR 0219 LNAME 0225 LTERM 0010 LU1OFS 0011 LU2OFS -0010 MAXLABEL 0000 NEVER 0014 NLUOFS 00E5 OEMID 000D OFFOFS -0071 OPENOK 024C PARGV 0251 PCODE1 0254 PCODE2 0255 PCODE3 -0258 PCODE4 025B PCODE5 025C PCODE6 0261 PDAT 0249 PDAY -024E PE5 0232 PHEXRF 00A0 PLEN 0248 PMON 0269 PNAM -0265 PORIG 0263 PPROD 025F PPROG 024F PPRST 0000 PRDWORD -0000 PRHBYTE 0000 PRHWORD 005C PRIFCB 0009 PRINTSTR 0244 PRMJ -0245 PRMN 02CF PRSVD 0247 PRTP 0246 PRUP 0267 PSER -0242 PSIG 0230 PSTART 026B PTERM 024A PYEAR 0021 R0OFS -0022 R1OFS 0023 R2OFS 000F RCOFS 000A READCONBUF 0014 READSEQ -0025 RESETDRIVE 0019 RETCURR 000C RETVERNO 0002 RV1OFS 0004 RV2OFS -0006 RV3OFS 000D S1OFS 000E S2OFS 006C SECFCB 000E SELDSK -001A SETDMA 0024 SETRANDREC 0000 SPANISH 0000 SPTOFS 0200 STACKSIZE -0000 SUCCESS 0009 T1OFS 000A T2OFS 000B T3OFS 0000 TERMCPM -0001 TRUE 0002 WORDSIZE 0022 WRITERAND 0028 WRITERANDZF -0015 WRITESEQ 0000 XIDENT 0000 XLTOFS 0000 XMEMCPY 0000 XMEMSET - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/INFOLIST.H b/branches/s100/Apps/crossdev/INFOLIST.H deleted file mode 100644 index 38ccd4e3..00000000 --- a/branches/s100/Apps/crossdev/INFOLIST.H +++ /dev/null @@ -1,16 +0,0 @@ -/* infolist.h 6/7/2012 dwg - BIOS Information Structure version 2 */ - -struct INFOLIST { - int version; - void * banptr; - void * varloc; - void * tstloc; - void * dpbmap; - void * dphmap; - void * ciomap; -} * pINFOLIST; - -/********************/ -/* eof - infolist.h */ -/********************/ - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/LABEL.C b/branches/s100/Apps/crossdev/LABEL.C deleted file mode 100644 index dc7e3cb2..00000000 --- a/branches/s100/Apps/crossdev/LABEL.C +++ /dev/null @@ -1,124 +0,0 @@ -/* label.c 67/10/2012 dwg - */ - -#include "stdio.h" -#include "cpmbios.h" -#include "bioscall.h" -#include "cpmbdos.h" -#include "bdoscall.h" -#include "metadata.h" -#include "banner.h" - -struct FCB * pPRIFCB; -struct FCB * pSECFCB; -struct DPH * pDPH; -struct DPB * pDPB; - -testdrive(drive) - int drive; -{ - ireghl = pSELDSK; - iregbc = drive; - bioscall(); - pDPH = ireghl; - pDPB = pDPH->dpb; - if(0 == pDPB->off) { - printf("Sorry Drive %c: has no prefix area and cannot be labeled", - drive+'A'); - exit(1); - } - -} - -interactive(drive) - int drive; -{ - int i; - - struct { - char size; - char len; - char data[16]; - } rdcons; - - testdrive(drive); - ireghl = pGETLU; - iregbc = drive; - bioscall(); - if(1 == irega) { - printf("interactive(%d) says drive %c: can't have label",drive,drive); - printf("%c",7); - exit(1); - - } - rdsector(drive,0,11,&metadata,0); - printf("Old label = "); - for(i=0;i<16;i++) { - printf("%c",metadata.label[i]); - } - - printf("\nNew label = "); - rdcons.size=16; - rdcons.len =0; - dregbc = RDCONBUF; - dregde = &rdcons; - bdoscall(); - - if(0 < rdcons.len) { - memset(metadata.label,' ',16); - memcpy(metadata.label,rdcons.data,rdcons.len); - wrsector(drive,0,11,&metadata,0); - } - -} - -noninteractive(drive,label) - int drive; - char * label; -{ - int i; - - testdrive(drive); - - rdsector(drive,0,11,&metadata,0); - memset(metadata.label,' ',16); - for(i=0;idrive-1); - exit(0); - } - } - break; - default: - noninteractive(pPRIFCB->drive-1,0x85); - break; - } - exit(0); -} - \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/LABEL.DWG b/branches/s100/Apps/crossdev/LABEL.DWG deleted file mode 100644 index cbf30794..00000000 --- a/branches/s100/Apps/crossdev/LABEL.DWG +++ /dev/null @@ -1,3 +0,0 @@ -RomWBW/branches/dwg/Apps/crossdev -1234567890123456789012345678901234 - 1 2 3 \ No newline at end of file diff --git a/branches/s100/Apps/crossdev/LABELIB.ASM b/branches/s100/Apps/crossdev/LABELIB.ASM deleted file mode 100644 index 85afc81e..00000000 --- a/branches/s100/Apps/crossdev/LABELIB.ASM +++ /dev/null @@ -1,217 +0,0 @@ -; labelib.asm 2/22/2012 dwg - label library function implementation -; label.asm 2/11/2012 dwg - make ident compliant -; label.asm 2/11/2012 dwg - begin 1.6 enhancements -; label.asm 2/04/2012 dwg - use new macros for benefits -; label.asm 1/20/2012 dwg - label a drive or slice - -; -; Copyright (C) 2011-2012 Douglas Goodall Licensed under GPL Ver 3. -; -; This file is part of NuBiosDWG and is free software: you can -; redistribute it and/or modify it under the terms of the GNU -; General Public License as published by the Free Software Foundation, -; either version 3 of the License, or (at your option) any later version. -; This file is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; You should have received a copy of the GNU General Public License -; along with it. If not, see . -; - - - maclib portab - maclib globals - maclib cpmbios - maclib cpmbdos - maclib bioshdr - maclib hardware - maclib z80 - maclib memory -; maclib applvers -; maclib cpmappl - maclib printers - maclib metadata -; maclib banner - maclib stdlib -; maclib ffhaslu -; maclib identity - - - - cseg - - public x$label -x$label: - mov a,c - sta drive$num - - get$off - mov a,h - ora l - jnz off$ok - printf 'Sorry, you can only label drives with reserved tracks' - jmp main$exit -off$ok: - - lda drive$num - mov c,a - lxi h,buffer - call x$g$meta - - lda DEFBUF ! mov c,a - cpi 0 ! jnz x$lab2 - -; ; Interactive label functionality here... - -prompt: - ; signature exists so label should be displayable - - print old$lbl - -; print label - lxi h,buffer - lxi d,meta$label - dad d - push h - pop d - mvi c,PRINTSTR - call BDOS - - print crlf - print new$lbl - - mvi c,READ$CON$BUF - lxi d,rcbuff - call BDOS - lda rclen - cpi 0 - jnz length$ok - jmp main$exit -length$ok: - inr a - sta DEFBUF - mvi a,' ' - sta DEFBUF+1 - mov c,a - mvi b,0 - lxi h,rcdata - lxi d,DEFBUF+2 - ldir - - print crlf - - lda drive$num - mov c,a - ; fall through to code below - - -;;; not$interactive: - - public x$lab2 -x$lab2: -; This routine can be used interactively or non-interactively. -; You can set up the default buffer at 80h and call x$lab2, -; or you can call x$label and it will interactively redo the label. -; - mov a,c - sta drive$num - - - lxi h,buffer - lxi d,meta$label - dad d - mvi a,' ' - lxi b,meta$label$len ; max length of label - call x$memset - - lda DEFBUF ; pick up length of command tail - cpi 18 ; compare with max size of label - jc lenok ; jump if size is within limits - mvi a,17 ; specify maximum size - sta DEFBUF ; and poke into default buffer size byte - -lenok: lda DEFBUF ; pick up command tail size byte - dcr a ; decrement - - mov c,a ; move to c reg as counter - mvi b,0 - - lxi h,buffer - lxi d,meta$label - dad d - xchg - lxi h,DEFBUF+2 ; set source index for move - ldir - - lxi h,buffer - lxi d,meta$term - dad d - mvi a,'$' - mov m,a - - lda drive$num - mov c,a - - lxi h,buffer - call x$u$meta - cpi FAILURE - jz write$prot$err - - lxi h,buffer - call x$p$meta - - print suc$msg - - jmp main$exit - -write$prot$err: - print wr$prot$msg - jmp main$exit - -readerr: - print rd$err$msg - jmp main$exit - -writeerr: - print wr$err$msg - jmp main$exit - -dontboth: - print usage$msg - -main$exit: - ret - - dseg - -suc$msg db 'Label Written Successfully$' -rd$err$msg db 'Sorry, cannot read label sector$' -wr$err$msg db 'Sorry, cannot write label sector$' -wr$prot$msg db 'Sorry, metadata is write protected$' -usage$msg db 'usage - label
<--
in HEX - Customization Variables: - NUMBASE RAS - Examples: - JUMP E000 or JUMP E000H <-- Jump to E000H - JUMP <-- Jump to 000H - JUMP 0 <-- Jump to 000H - Notes: - JUMP performs a subroutine "call", so the called routine may - return to the ZCPR by either a RET or a Warm Boot. - - - Command: GO - Function: To "call" the subroutine starting at 100H - Forms: - GO <-- Execute reentrant at 100H - Customization Variables: - RAS - Examples: - GO *.ASM <-- Assuming XDIR is loaded, - gives directory of *.ASM - Notes: - This command is identical in function to JUMP 100H; JUMP, - however, leaves the address as the first entry in CP/M BASE + 80H - (the input line buffer), while GO has no such address. - - - Command: GET - Function: To load a file from disk into memory starting at the - specified page - Forms: - GET
<--
in HEX - Customization Variables: - NUMBASE RAS - Examples: - GET 8000 TEST.80 <-- Load TEST.80 starting at 8000H - GET 100 TEST.80 or GET 100H TEST.80 <-- Load TEST.80 - starting at 100H - GET 0 TEST.80 <-- Load TEST.80 starting at 000H - Notes: - GET searches for the specified file according to the same - command hierarchy search employed by the ZCPR command scanner. - Hence, if the user is on B:/10 and the file is on A:/0 with the - current default user number at 0, GET will search from B:/10 to - B:/0 to A:/0 in looking for the file. - - - - - - - Page 17 - - - - - - ZCPR - A Z80 Replacement for the CP/M CCP - - - - ZCPR Error Messages - - The following are the error messages issued by ZCPR and - their meanings. - - Message Meaning - - ? Printed after a command or an argument means that such - was invalid - - No File From DIR, this means that DIR did not locate any files - Also from ERA with the same meaning - - All? Issued in response ERA *.*, asks the user is he really - wants to erase all the files. Unlike under the - original CP/M 2.2 CCP, single character input is - required (Y or y for yes and anything else for no) - with NO to end the line - - Full From SAVE, means that there is not enough space on - disk - From GET or command load by CPR, means that there - is not enough space in memory - - Delete File? - From REN or SAVE, means that the file specified already - exists on disk and the user may type Y or y to delete - it and proceed with the REN or SAVE function - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Page 18 - - - - - - ZCPR - A Z80 Replacement for the CP/M CCP - - - - - Part C - ZCPR Command Levels and How to Use Them - - - ZCPR Version 1.0 and beyond supports three distinct command - levels in its implementation. Each level constitutes a different - way to issue a command for ZCPR to process. - - Command Levels 1 and 2 are common to all implementations of - CP/M and CP/ZM from CP/M Version 1.4. Command Level 1 is that - command level in which the command is issued by the user from his - console terminal. The prompt 'd>' or 'du>' appears on the - terminal, and the user is allowed to enter the command with - editing from the terminal. Command Level 2 is that command level - in which the command is entered from an executing $$$.SUB file. - - In both cases, the command is stored in the internal ZCPR - buffer called CIBUFF (Command Input BUFFer). Under both Command - Levels 1 and 2, the command is placed into this buffer, the - characters of the command line are capitalized, a character count - which indicates the number of characters in the command line is - stored in CBUFF (the byte before CIBUFF), an ending binary 0 is - placed after the last character in the command line, and the - internal pointer CIBPTR (Command Input Buffer PoinTeR) is set to - point to CIBUFF (the first character of the command line). - - Command Level 3 is an extended concept to Command Levels 1 - and 2 which is specifically supported by ZCPR Version 1.0 and - beyond. This command level allows a transient program to place a - command line into CIBUFF and the character count into CBUFF and - have this command line executed by ZCPR. Once control is trans- - ferred to ZCPR to execute the command line, the transient program - which placed the command line loses control and the command is - executed exactly as though it had been typed by the user at his - console terminal. - - In order for a transient program to utilize the Command - Level 3 facility, this program MUST do the following: - - 1. Locate the ZCPR. Since the ZCPR is ALWAYS 2K bytes - in size and located directly under the BDOS, the transient can - locate the ZCPR by examining the BDOS entry page address at - location 7 and subtracting 8 from this number (8 pages = 2K - bytes). The resulting number is the base page address of ZCPR. - - 2. Store the command line in CIBUFF and the character - count in CBUFF. Knowing the base page address of ZCPR, the - following information is useful in doing this: - - - - - - - - Page 19 - - - - - - ZCPR - A Z80 Replacement for the CP/M CCP - - - - - ORG CPRLOC ;Base Address of ZCPR - JMP CPR ;Enter ZCPR and Execute Default Cmd - JMP CPR1 ;Enter ZCPR and Don't Execute - MBUFF: DB BUFLEN ;Size of CIBUFF in bytes - CBUFF: DS 1 ;Number of Bytes in Command Line - CIBUFF: DS BUFLEN ;Buffer for Command Line - DS 1 ;Buffer for Ending 0 (set by ZCPR) - CIBPTR: DS 2 ;Address of CIBUFF (set by ZCPR) - - - 3. Obtain the User/Disk Flag. Location 4 contains - this number, but the user may select a flag of his choice. This - flag is one byte long, and the high-order nybble (4 bits) - contains the user number and the low-order nybble contains the - disk number to process the command from. The User/Disk Flag is - to be passed to ZCPR in the C Register. - - 4. When ready, transfer control to ZCPR to process the - command by JMPing to the base address of ZCPR. The first JMP in - the JMP Table given above is at this address. At this time, ZCPR - will log in the user and disk in the User/Disk Flag and process - the Command Level 3 Command Line. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Page 20 - - - - - - ZCPR - A Z80 Replacement for the CP/M CCP - - - - - The following is a sample program which illustrates the - steps outlined above: - - ; - ; Demonstration of Command Level 3 Facility by RLC - ; - udflag equ 4 ;Address of User/Disk Flag - bdos equ 5 ;Address of BDOS Entry Point - - org 100h - - lxi d,prmpt ;Print User Prompt - mvi c,9 ;PRINT function - call bdos - - lhld bdos+1 ;Get address of BDOS - mov a,h ;High-Order Address in A - sui 8 ;A=High-Order Address of CPR - mov h,a ;HL=Address of CPR - mvi l,0 - shld cpr ;Save address in buffer - - lxi d,6 ;Point to command line buffer - dad d ;HL points to command line buffer - xchg ;DE points to command line buffer - mvi c,10 ;READLN into this buffer - call bdos - - lhld cpr ;Get Address of CPR - lda udflag ;Get User/Disk Flag - mov c,a ; ... in C - pchl ;Run Command Line - - cpr: ds 2 ;CPR Address buffer - prmpt: db 'User Command? $' - - - - - - - Enjoy using ZCPR! - -- RLC - - - - - - - - - - - - - Page 21 - - - - - - \ No newline at end of file diff --git a/branches/s100/Doc/Reference/zsdos.pdf b/branches/s100/Doc/Reference/zsdos.pdf deleted file mode 100644 index f78a2775..00000000 --- a/branches/s100/Doc/Reference/zsdos.pdf +++ /dev/null @@ -1,13114 +0,0 @@ -%PDF-1.4 -%ÐÔÅØ -5 0 obj -<< /S /GoTo /D (section.1) >> -endobj -8 0 obj -(1 Introduction) -endobj -9 0 obj -<< /S /GoTo /D (subsection.1.1) >> -endobj -12 0 obj -(1.1 About This Manual) -endobj -13 0 obj -<< /S /GoTo /D (subsection.1.2) >> -endobj -16 0 obj -(1.2 What is ZSDOS?) -endobj -17 0 obj -<< /S /GoTo /D (subsection.1.3) >> -endobj -20 0 obj -(1.3 The History of ZSDOS) -endobj -21 0 obj -<< /S /GoTo /D (subsection.1.4) >> -endobj -24 0 obj -(1.4 Differences Between ZSDOS and ZDDOS) -endobj -25 0 obj -<< /S /GoTo /D (subsection.1.5) >> -endobj -28 0 obj -(1.5 Differences Between CP/M 2.2, ZRDOS and ZSDOS) -endobj -29 0 obj -<< /S /GoTo /D (subsection.1.6) >> -endobj -32 0 obj -(1.6 Program Summaries and Usage) -endobj -33 0 obj -<< /S /GoTo /D (subsubsection.1.6.1) >> -endobj -36 0 obj -(1.6.1 Program Summary Conventions) -endobj -37 0 obj -<< /S /GoTo /D (subsubsection.1.6.2) >> -endobj -40 0 obj -(1.6.2 Built-in Help) -endobj -41 0 obj -<< /S /GoTo /D (subsubsection.1.6.3) >> -endobj -44 0 obj -(1.6.3 Command Line Options) -endobj -45 0 obj -<< /S /GoTo /D (section.2) >> -endobj -48 0 obj -(2 Features) -endobj -49 0 obj -<< /S /GoTo /D (subsection.2.1) >> -endobj -52 0 obj -(2.1 Automatic Disk Relog) -endobj -53 0 obj -<< /S /GoTo /D (subsection.2.2) >> -endobj -56 0 obj -(2.2 Improved Error Handling) -endobj -57 0 obj -<< /S /GoTo /D (subsection.2.3) >> -endobj -60 0 obj -(2.3 Archive Attribute Support) -endobj -61 0 obj -<< /S /GoTo /D (subsection.2.4) >> -endobj -64 0 obj -(2.4 Larger File and Disk Sizes) -endobj -65 0 obj -<< /S /GoTo /D (subsection.2.5) >> -endobj -68 0 obj -(2.5 Fast Fixed Disk Relog) -endobj -69 0 obj -<< /S /GoTo /D (subsection.2.6) >> -endobj -72 0 obj -(2.6 Backgrounder II Support) -endobj -73 0 obj -<< /S /GoTo /D (subsection.2.7) >> -endobj -76 0 obj -(2.7 Wheel Protection) -endobj -77 0 obj -<< /S /GoTo /D (subsection.2.8) >> -endobj -80 0 obj -(2.8 File Access Modes) -endobj -81 0 obj -<< /S /GoTo /D (subsubsection.2.8.1) >> -endobj -84 0 obj -(2.8.1 Normal Access) -endobj -85 0 obj -<< /S /GoTo /D (subsubsection.2.8.2) >> -endobj -88 0 obj -(2.8.2 Path Access \(ZSDOS only\)) -endobj -89 0 obj -<< /S /GoTo /D (paragraph.2.8.2.1) >> -endobj -92 0 obj -(2.8.2.1 Path Directory Access \(ZSDOS only\)) -endobj -93 0 obj -<< /S /GoTo /D (paragraph.2.8.2.2) >> -endobj -96 0 obj -(2.8.2.2 Path File Access \(ZSDOS only\)) -endobj -97 0 obj -<< /S /GoTo /D (subsubsection.2.8.3) >> -endobj -100 0 obj -(2.8.3 Public Access) -endobj -101 0 obj -<< /S /GoTo /D (subsubsection.2.8.4) >> -endobj -104 0 obj -(2.8.4 Combined Access \(ZSDOS only\)) -endobj -105 0 obj -<< /S /GoTo /D (subsection.2.9) >> -endobj -108 0 obj -(2.9 Enhanced Write Protection) -endobj -109 0 obj -<< /S /GoTo /D (subsection.2.10) >> -endobj -112 0 obj -(2.10 \040Re-entrancy Potential) -endobj -113 0 obj -<< /S /GoTo /D (subsection.2.11) >> -endobj -116 0 obj -(2.11 FCB User Number Support) -endobj -117 0 obj -<< /S /GoTo /D (subsection.2.12) >> -endobj -120 0 obj -(2.12 File Datestamping Support) -endobj -121 0 obj -<< /S /GoTo /D (subsection.2.13) >> -endobj -124 0 obj -(2.13 Run-time Configuration) -endobj -125 0 obj -<< /S /GoTo /D (subsection.2.14) >> -endobj -128 0 obj -(2.14 Other Significant Enhancements) -endobj -129 0 obj -<< /S /GoTo /D (section.3) >> -endobj -132 0 obj -(3 Installing ZSDOS) -endobj -133 0 obj -<< /S /GoTo /D (subsection.3.1) >> -endobj -136 0 obj -(3.1 Installing the Operating System) -endobj -137 0 obj -<< /S /GoTo /D (subsubsection.3.1.1) >> -endobj -140 0 obj -(3.1.1 Installing ZSDOS with INSTALOS) -endobj -141 0 obj -<< /S /GoTo /D (paragraph.3.1.1.1) >> -endobj -144 0 obj -(3.1.1.1 Using INSTALOS) -endobj -145 0 obj -<< /S /GoTo /D (paragraph.3.1.1.2) >> -endobj -148 0 obj -(3.1.1.2 Creating a Boot Disk) -endobj -149 0 obj -<< /S /GoTo /D (paragraph.3.1.1.3) >> -endobj -152 0 obj -(3.1.1.3 INSTALOS Error Messages) -endobj -153 0 obj -<< /S /GoTo /D (subsubsection.3.1.2) >> -endobj -156 0 obj -(3.1.2 Installing ZSDOS with NZCOM) -endobj -157 0 obj -<< /S /GoTo /D (subsubsection.3.1.3) >> -endobj -160 0 obj -(3.1.3 Installing ZSDOS with JetLDR) -endobj -161 0 obj -<< /S /GoTo /D (subsubsection.3.1.4) >> -endobj -164 0 obj -(3.1.4 Installing with XBIOS) -endobj -165 0 obj -<< /S /GoTo /D (subsection.3.2) >> -endobj -168 0 obj -(3.2 Clock and File Stamp Installation) -endobj -169 0 obj -<< /S /GoTo /D (subsubsection.3.2.1) >> -endobj -172 0 obj -(3.2.1 Selecting a Clock Driver) -endobj -173 0 obj -<< /S /GoTo /D (subsubsection.3.2.2) >> -endobj -176 0 obj -(3.2.2 Installing Clock and/or Stamp Method) -endobj -177 0 obj -<< /S /GoTo /D (subsubsection.3.2.3) >> -endobj -180 0 obj -(3.2.3 The LDTIM Program) -endobj -181 0 obj -<< /S /GoTo /D (subsubsection.3.2.4) >> -endobj -184 0 obj -(3.2.4 Preparing Disks for DateStamper \(PUTDS\)) -endobj -185 0 obj -<< /S /GoTo /D (paragraph.3.2.4.1) >> -endobj -188 0 obj -(3.2.4.1 PUTDS Interactive Mode) -endobj -189 0 obj -<< /S /GoTo /D (paragraph.3.2.4.2) >> -endobj -192 0 obj -(3.2.4.2 PUTDS Expert Mode) -endobj -193 0 obj -<< /S /GoTo /D (subsubsection.3.2.5) >> -endobj -196 0 obj -(3.2.5 Preparing Disks for P2DOS Stamps \(INITDIR\)) -endobj -197 0 obj -<< /S /GoTo /D (paragraph.3.2.5.1) >> -endobj -200 0 obj -(3.2.5.1 INITDIR Interactive Mode) -endobj -201 0 obj -<< /S /GoTo /D (paragraph.3.2.5.2) >> -endobj -204 0 obj -(3.2.5.2 INITDIR Expert Mode) -endobj -205 0 obj -<< /S /GoTo /D (paragraph.3.2.5.3) >> -endobj -208 0 obj -(3.2.5.3 INITDIR Error Messages) -endobj -209 0 obj -<< /S /GoTo /D (subsection.3.3) >> -endobj -212 0 obj -(3.3 Installing BackGrounder II for ZSDOS) -endobj -213 0 obj -<< /S /GoTo /D (subsubsection.3.3.1) >> -endobj -216 0 obj -(3.3.1 BackGrounder Installation using MLOAD.COM) -endobj -217 0 obj -<< /S /GoTo /D (subsubsection.3.3.2) >> -endobj -220 0 obj -(3.3.2 Installation using DDT.COM) -endobj -221 0 obj -<< /S /GoTo /D (subsection.3.4) >> -endobj -224 0 obj -(3.4 Advanced Installation Techniques) -endobj -225 0 obj -<< /S /GoTo /D (subsubsection.3.4.1) >> -endobj -228 0 obj -(3.4.1 Replacing CCP and BIOS with INSTALOS) -endobj -229 0 obj -<< /S /GoTo /D (paragraph.3.4.1.1) >> -endobj -232 0 obj -(3.4.1.1 Replacing the CCP) -endobj -233 0 obj -<< /S /GoTo /D (paragraph.3.4.1.2) >> -endobj -236 0 obj -(3.4.1.2 Replacing the BIOS) -endobj -237 0 obj -<< /S /GoTo /D (subsubsection.3.4.2) >> -endobj -240 0 obj -(3.4.2 User-Developed Clock Drivers) -endobj -241 0 obj -<< /S /GoTo /D (subsubsection.3.4.3) >> -endobj -244 0 obj -(3.4.3 Customizing Stamp Installation with SETUPZST) -endobj -245 0 obj -<< /S /GoTo /D (paragraph.3.4.3.1) >> -endobj -248 0 obj -(3.4.3.1 The Different Stamp Modules) -endobj -249 0 obj -<< /S /GoTo /D (paragraph.3.4.3.2) >> -endobj -252 0 obj -(3.4.3.2 Installing a Stamp Module in High Memory) -endobj -253 0 obj -<< /S /GoTo /D (paragraph.3.4.3.3) >> -endobj -256 0 obj -(3.4.3.3 Installing Stamp Module in NZCOM User Space) -endobj -257 0 obj -<< /S /GoTo /D (paragraph.3.4.3.4) >> -endobj -260 0 obj -(3.4.3.4 Changing an existing LDTIM.COM program) -endobj -261 0 obj -<< /S /GoTo /D (subsubsection.3.4.4) >> -endobj -264 0 obj -(3.4.4 Tips on Using ZSCONFIG with Clocks/Stamps) -endobj -265 0 obj -<< /S /GoTo /D (paragraph.3.4.4.1) >> -endobj -268 0 obj -(3.4.4.1 Patching in an Existing Clock) -endobj -269 0 obj -<< /S /GoTo /D (paragraph.3.4.4.2) >> -endobj -272 0 obj -(3.4.4.2 Speed Tip) -endobj -273 0 obj -<< /S /GoTo /D (section.4) >> -endobj -276 0 obj -(4 ZSDOS Utilities) -endobj -277 0 obj -<< /S /GoTo /D (subsection.4.1) >> -endobj -280 0 obj -(4.1 COPY -- Copy Files) -endobj -281 0 obj -<< /S /GoTo /D (subsubsection.4.1.1) >> -endobj -284 0 obj -(4.1.1 Using COPY) -endobj -285 0 obj -<< /S /GoTo /D (subsubsection.4.1.2) >> -endobj -288 0 obj -(4.1.2 COPY Options) -endobj -289 0 obj -<< /S /GoTo /D (paragraph.4.1.2.1) >> -endobj -292 0 obj -(4.1.2.1 Archive Option) -endobj -293 0 obj -<< /S /GoTo /D (paragraph.4.1.2.2) >> -endobj -296 0 obj -(4.1.2.2 File Existence Option) -endobj -297 0 obj -<< /S /GoTo /D (paragraph.4.1.2.3) >> -endobj -300 0 obj -(4.1.2.3 Inspect Files Option) -endobj -301 0 obj -<< /S /GoTo /D (paragraph.4.1.2.4) >> -endobj -304 0 obj -(4.1.2.4 Multiple Copy Option) -endobj -305 0 obj -<< /S /GoTo /D (paragraph.4.1.2.5) >> -endobj -308 0 obj -(4.1.2.5 No Replacement Option) -endobj -309 0 obj -<< /S /GoTo /D (paragraph.4.1.2.6) >> -endobj -312 0 obj -(4.1.2.6 Quiet Option) -endobj -313 0 obj -<< /S /GoTo /D (paragraph.4.1.2.7) >> -endobj -316 0 obj -(4.1.2.7 System Files Option) -endobj -317 0 obj -<< /S /GoTo /D (paragraph.4.1.2.8) >> -endobj -320 0 obj -(4.1.2.8 Verify Option) -endobj -321 0 obj -<< /S /GoTo /D (paragraph.4.1.2.9) >> -endobj -324 0 obj -(4.1.2.9 Archive if Only if File Exists Option) -endobj -325 0 obj -<< /S /GoTo /D (subsection.4.2) >> -endobj -328 0 obj -(4.2 DATSWEEP -- Directory Tool) -endobj -329 0 obj -<< /S /GoTo /D (subsubsection.4.2.1) >> -endobj -332 0 obj -(4.2.1 Overview) -endobj -333 0 obj -<< /S /GoTo /D (paragraph.4.2.1.1) >> -endobj -336 0 obj -(4.2.1.1 The Six Windows) -endobj -337 0 obj -<< /S /GoTo /D (paragraph.4.2.1.2) >> -endobj -340 0 obj -(4.2.1.2 Logging In and Selecting Filesets) -endobj -341 0 obj -<< /S /GoTo /D (paragraph.4.2.1.3) >> -endobj -344 0 obj -(4.2.1.3 Filespecs and Datespecs) -endobj -345 0 obj -<< /S /GoTo /D (paragraph.4.2.1.4) >> -endobj -348 0 obj -(4.2.1.4 Flags \(attributes\)) -endobj -349 0 obj -<< /S /GoTo /D (subsubsection.4.2.2) >> -endobj -352 0 obj -(4.2.2 Using DATSWEEP) -endobj -353 0 obj -<< /S /GoTo /D (paragraph.4.2.2.1) >> -endobj -356 0 obj -(4.2.2.1 Tagging Examples) -endobj -357 0 obj -<< /S /GoTo /D (subsubsection.4.2.3) >> -endobj -360 0 obj -(4.2.3 DATSWEEP Command Summary) -endobj -361 0 obj -<< /S /GoTo /D (paragraph.4.2.3.1) >> -endobj -364 0 obj -(4.2.3.1 File Operation Commands) -endobj -365 0 obj -<< /S /GoTo /D (paragraph.4.2.3.2) >> -endobj -368 0 obj -(4.2.3.2 Tagging Commands) -endobj -369 0 obj -<< /S /GoTo /D (paragraph.4.2.3.3) >> -endobj -372 0 obj -(4.2.3.3 Miscellaneous Commands) -endobj -373 0 obj -<< /S /GoTo /D (paragraph.4.2.3.4) >> -endobj -376 0 obj -(4.2.3.4 Viewing a File) -endobj -377 0 obj -<< /S /GoTo /D (paragraph.4.2.3.5) >> -endobj -380 0 obj -(4.2.3.5 Viewing Squeezed Files) -endobj -381 0 obj -<< /S /GoTo /D (subsubsection.4.2.4) >> -endobj -384 0 obj -(4.2.4 Command Line Options) -endobj -385 0 obj -<< /S /GoTo /D (paragraph.4.2.4.1) >> -endobj -388 0 obj -(4.2.4.1 Special Characters) -endobj -389 0 obj -<< /S /GoTo /D (paragraph.4.2.4.2) >> -endobj -392 0 obj -(4.2.4.2 OSPrompt Level) -endobj -393 0 obj -<< /S /GoTo /D (paragraph.4.2.4.3) >> -endobj -396 0 obj -(4.2.4.3 SUBMIT or ZEX Scripts) -endobj -397 0 obj -<< /S /GoTo /D (paragraph.4.2.4.4) >> -endobj -400 0 obj -(4.2.4.4 Passing Parameters) -endobj -401 0 obj -<< /S /GoTo /D (paragraph.4.2.4.5) >> -endobj -404 0 obj -(4.2.4.5 The \137C Switch) -endobj -405 0 obj -<< /S /GoTo /D (paragraph.4.2.4.6) >> -endobj -408 0 obj -(4.2.4.6 Limitations of the Command Line Option) -endobj -409 0 obj -<< /S /GoTo /D (subsubsection.4.2.5) >> -endobj -412 0 obj -(4.2.5 Installation and Configuration) -endobj -413 0 obj -<< /S /GoTo /D (paragraph.4.2.5.1) >> -endobj -416 0 obj -(4.2.5.1 Installation) -endobj -417 0 obj -<< /S /GoTo /D (paragraph.4.2.5.2) >> -endobj -420 0 obj -(4.2.5.2 Configuration) -endobj -421 0 obj -<< /S /GoTo /D (subsubsection.4.2.6) >> -endobj -424 0 obj -(4.2.6 Technical Information) -endobj -425 0 obj -<< /S /GoTo /D (paragraph.4.2.6.1) >> -endobj -428 0 obj -(4.2.6.1 Filesizes and Disk Space) -endobj -429 0 obj -<< /S /GoTo /D (paragraph.4.2.6.2) >> -endobj -432 0 obj -(4.2.6.2 Error Procedures) -endobj -433 0 obj -<< /S /GoTo /D (paragraph.4.2.6.3) >> -endobj -436 0 obj -(4.2.6.3 Very Large Directories) -endobj -437 0 obj -<< /S /GoTo /D (subsection.4.3) >> -endobj -440 0 obj -(4.3 FILEATTR -- Set or Display Attributes) -endobj -441 0 obj -<< /S /GoTo /D (subsubsection.4.3.1) >> -endobj -444 0 obj -(4.3.1 Using FILEATTR) -endobj -445 0 obj -<< /S /GoTo /D (paragraph.4.3.1.1) >> -endobj -448 0 obj -(4.3.1.1 FILEATTR Display Commands) -endobj -449 0 obj -<< /S /GoTo /D (paragraph.4.3.1.2) >> -endobj -452 0 obj -(4.3.1.2 FILEATTR Set Commands) -endobj -453 0 obj -<< /S /GoTo /D (paragraph.4.3.1.3) >> -endobj -456 0 obj -(4.3.1.3 FILEATTR Options) -endobj -457 0 obj -<< /S /GoTo /D (paragraph.4.3.1.4) >> -endobj -460 0 obj -(4.3.1.4 FILEATTR Output) -endobj -461 0 obj -<< /S /GoTo /D (subsubsection.4.3.2) >> -endobj -464 0 obj -(4.3.2 FILEATTR Error Messages) -endobj -465 0 obj -<< /S /GoTo /D (subsection.4.4) >> -endobj -468 0 obj -(4.4 FILEDATE -- Display File Dates) -endobj -469 0 obj -<< /S /GoTo /D (subsubsection.4.4.1) >> -endobj -472 0 obj -(4.4.1 FILEDATE Syntax) -endobj -473 0 obj -<< /S /GoTo /D (paragraph.4.4.1.1) >> -endobj -476 0 obj -(4.4.1.1 FILEDATE Syntax Summary) -endobj -477 0 obj -<< /S /GoTo /D (paragraph.4.4.1.2) >> -endobj -480 0 obj -(4.4.1.2 The File Specification Field) -endobj -481 0 obj -<< /S /GoTo /D (paragraph.4.4.1.3) >> -endobj -484 0 obj -(4.4.1.3 The Option Field) -endobj -485 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.3.1) >> -endobj -488 0 obj -(4.4.1.3.1 Sorting by Date) -endobj -489 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.3.2) >> -endobj -492 0 obj -(4.4.1.3.2 Using Access and Create Stamps) -endobj -493 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.3.3) >> -endobj -496 0 obj -(4.4.1.3.3 Displaying All Stamps) -endobj -497 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.3.4) >> -endobj -500 0 obj -(4.4.1.3.4 No Pause) -endobj -501 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.3.5) >> -endobj -504 0 obj -(4.4.1.3.5 Showing System Files) -endobj -505 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.3.6) >> -endobj -508 0 obj -(4.4.1.3.6 Showing All User Areas) -endobj -509 0 obj -<< /S /GoTo /D (paragraph.4.4.1.4) >> -endobj -512 0 obj -(4.4.1.4 The Date Specification Field) -endobj -513 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.4.1) >> -endobj -516 0 obj -(4.4.1.4.1 Date Signifiers) -endobj -517 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.4.2) >> -endobj -520 0 obj -(4.4.1.4.2 Dates) -endobj -521 0 obj -<< /S /GoTo /D (subparagraph.4.4.1.4.3) >> -endobj -524 0 obj -(4.4.1.4.3 Date Specifications) -endobj -525 0 obj -<< /S /GoTo /D (paragraph.4.4.1.5) >> -endobj -528 0 obj -(4.4.1.5 The Complete FILEDATE Syntax) -endobj -529 0 obj -<< /S /GoTo /D (subsubsection.4.4.2) >> -endobj -532 0 obj -(4.4.2 FILEDATE Output) -endobj -533 0 obj -<< /S /GoTo /D (paragraph.4.4.2.1) >> -endobj -536 0 obj -(4.4.2.1 Default Display) -endobj -537 0 obj -<< /S /GoTo /D (paragraph.4.4.2.2) >> -endobj -540 0 obj -(4.4.2.2 Display Sorted by Access Date) -endobj -541 0 obj -<< /S /GoTo /D (paragraph.4.4.2.3) >> -endobj -544 0 obj -(4.4.2.3 Display Selected by Modify Date) -endobj -545 0 obj -<< /S /GoTo /D (paragraph.4.4.2.4) >> -endobj -548 0 obj -(4.4.2.4 Note on Relative Times) -endobj -549 0 obj -<< /S /GoTo /D (paragraph.4.4.2.5) >> -endobj -552 0 obj -(4.4.2.5 Notes on Missing Stamps) -endobj -553 0 obj -<< /S /GoTo /D (subsubsection.4.4.3) >> -endobj -556 0 obj -(4.4.3 FILEDATE Error Messages) -endobj -557 0 obj -<< /S /GoTo /D (subsection.4.5) >> -endobj -560 0 obj -(4.5 RELOG -- Reset Disk System) -endobj -561 0 obj -<< /S /GoTo /D (subsection.4.6) >> -endobj -564 0 obj -(4.6 TD -- Read and Set Clock) -endobj -565 0 obj -<< /S /GoTo /D (subsubsection.4.6.1) >> -endobj -568 0 obj -(4.6.1 Using TD) -endobj -569 0 obj -<< /S /GoTo /D (subsubsection.4.6.2) >> -endobj -572 0 obj -(4.6.2 TD Error Messages) -endobj -573 0 obj -<< /S /GoTo /D (subsection.4.7) >> -endobj -576 0 obj -(4.7 ZCAL -- Display Month) -endobj -577 0 obj -<< /S /GoTo /D (subsubsection.4.7.1) >> -endobj -580 0 obj -(4.7.1 Using ZCAL) -endobj -581 0 obj -<< /S /GoTo /D (paragraph.4.7.1.1) >> -endobj -584 0 obj -(4.7.1.1 ZCAL System Requirements) -endobj -585 0 obj -<< /S /GoTo /D (paragraph.4.7.1.2) >> -endobj -588 0 obj -(4.7.1.2 ZCAL Syntax) -endobj -589 0 obj -<< /S /GoTo /D (subsubsection.4.7.2) >> -endobj -592 0 obj -(4.7.2 ZCAL Error Messages) -endobj -593 0 obj -<< /S /GoTo /D (subsection.4.8) >> -endobj -596 0 obj -(4.8 ZCNFG - Configuration Utility) -endobj -597 0 obj -<< /S /GoTo /D (subsubsection.4.8.1) >> -endobj -600 0 obj -(4.8.1 Using ZCNFG) -endobj -601 0 obj -<< /S /GoTo /D (paragraph.4.8.1.1) >> -endobj -604 0 obj -(4.8.1.1 ZCNFG Toggle Displays) -endobj -605 0 obj -<< /S /GoTo /D (paragraph.4.8.1.2) >> -endobj -608 0 obj -(4.8.1.2 ZCNFG Value Displays) -endobj -609 0 obj -<< /S /GoTo /D (paragraph.4.8.1.3) >> -endobj -612 0 obj -(4.8.1.3 Note on COPY) -endobj -613 0 obj -<< /S /GoTo /D (subsection.4.9) >> -endobj -616 0 obj -(4.9 ZPATH - Set ZSDOS Path) -endobj -617 0 obj -<< /S /GoTo /D (subsubsection.4.9.1) >> -endobj -620 0 obj -(4.9.1 Using ZPAT) -endobj -621 0 obj -<< /S /GoTo /D (paragraph.4.9.1.1) >> -endobj -624 0 obj -(4.9.1.1 ZPATH Option Characters) -endobj -625 0 obj -<< /S /GoTo /D (paragraph.4.9.1.2) >> -endobj -628 0 obj -(4.9.1.2 ZPATH Examples) -endobj -629 0 obj -<< /S /GoTo /D (subsubsection.4.9.2) >> -endobj -632 0 obj -(4.9.2 ZPATH Error and Warning Messages) -endobj -633 0 obj -<< /S /GoTo /D (subsection.4.10) >> -endobj -636 0 obj -(4.10 ZSCONFIG -- Configure a Running ZSDOS System) -endobj -637 0 obj -<< /S /GoTo /D (subsubsection.4.10.1) >> -endobj -640 0 obj -(4.10.1 ZSCONFIG Interactive Mode) -endobj -641 0 obj -<< /S /GoTo /D (subsubsection.4.10.2) >> -endobj -644 0 obj -(4.10.2 ZSCONFIG Expert Mode) -endobj -645 0 obj -<< /S /GoTo /D (subsubsection.4.10.3) >> -endobj -648 0 obj -(4.10.3 ZSCONFIG Options) -endobj -649 0 obj -<< /S /GoTo /D (paragraph.4.10.3.1) >> -endobj -652 0 obj -(4.10.3.1 Public Files \(ZSDOS and ZDDOS\)) -endobj -653 0 obj -<< /S /GoTo /D (paragraph.4.10.3.2) >> -endobj -656 0 obj -(4.10.3.2 Public/Path Write Enable \(ZSDOS and ZDDOS\)) -endobj -657 0 obj -<< /S /GoTo /D (paragraph.4.10.3.3) >> -endobj -660 0 obj -(4.10.3.3 Read-Only Vector Sustain \(ZSDOS and ZDDOS\)) -endobj -661 0 obj -<< /S /GoTo /D (paragraph.4.10.3.4) >> -endobj -664 0 obj -(4.10.3.4 Fast Fixed Disk Relog \(ZSDOS and ZDDOS\)) -endobj -665 0 obj -<< /S /GoTo /D (paragraph.4.10.3.5) >> -endobj -668 0 obj -(4.10.3.5 Disk Change Warning \(ZSDOS and ZDDOS\)) -endobj -669 0 obj -<< /S /GoTo /D (paragraph.4.10.3.6) >> -endobj -672 0 obj -(4.10.3.6 Path Without System Attribute \(ZSDOS only\)) -endobj -673 0 obj -<< /S /GoTo /D (paragraph.4.10.3.7) >> -endobj -676 0 obj -(4.10.3.7 DOS Search Path \(ZSDOS only\)) -endobj -677 0 obj -<< /S /GoTo /D (paragraph.4.10.3.8) >> -endobj -680 0 obj -(4.10.3.8 Wheel Byte Write Protect \(ZSDOS and ZDDOS\)) -endobj -681 0 obj -<< /S /GoTo /D (paragraph.4.10.3.9) >> -endobj -684 0 obj -(4.10.3.9 Time Routine \(Clock Driver\) \(ZSDOS and ZDDOS\)) -endobj -685 0 obj -<< /S /GoTo /D (paragraph.4.10.3.10) >> -endobj -688 0 obj -(4.10.3.10 Stamp Last Accessed Time \(ZSDOS and ZDDOS\)) -endobj -689 0 obj -<< /S /GoTo /D (paragraph.4.10.3.11) >> -endobj -692 0 obj -(4.10.3.11 Stamp Create Time \(ZSDOS only\)) -endobj -693 0 obj -<< /S /GoTo /D (paragraph.4.10.3.12) >> -endobj -696 0 obj -(4.10.3.12 Stamp Modify Time \(ZSDOS and ZDDOS\)) -endobj -697 0 obj -<< /S /GoTo /D (paragraph.4.10.3.13) >> -endobj -700 0 obj -(4.10.3.13 Get Date/Time Stamp \(ZSDOS only\)) -endobj -701 0 obj -<< /S /GoTo /D (paragraph.4.10.3.14) >> -endobj -704 0 obj -(4.10.3.14 Set Date/Time Stamp \(ZSDOS only\)) -endobj -705 0 obj -<< /S /GoTo /D (subsubsection.4.10.4) >> -endobj -708 0 obj -(4.10.4 ZSCONFIG Error Messages) -endobj -709 0 obj -<< /S /GoTo /D (subsection.4.11) >> -endobj -712 0 obj -(4.11 ZXD - Extended Directory Utility) -endobj -713 0 obj -<< /S /GoTo /D (subsubsection.4.11.1) >> -endobj -716 0 obj -(4.11.1 Using ZXD) -endobj -717 0 obj -<< /S /GoTo /D (subsubsection.4.11.2) >> -endobj -720 0 obj -(4.11.2 ZXD Options) -endobj -721 0 obj -<< /S /GoTo /D (paragraph.4.11.2.1) >> -endobj -724 0 obj -(4.11.2.1 Select Files by Attribute) -endobj -725 0 obj -<< /S /GoTo /D (paragraph.4.11.2.2) >> -endobj -728 0 obj -(4.11.2.2 Date Display Format) -endobj -729 0 obj -<< /S /GoTo /D (paragraph.4.11.2.3) >> -endobj -732 0 obj -(4.11.2.3 Disable Date \(NoDate\) Display) -endobj -733 0 obj -<< /S /GoTo /D (paragraph.4.11.2.4) >> -endobj -736 0 obj -(4.11.2.4 Output Control Option) -endobj -737 0 obj -<< /S /GoTo /D (paragraph.4.11.2.5) >> -endobj -740 0 obj -(4.11.2.5 Output to Printer) -endobj -741 0 obj -<< /S /GoTo /D (paragraph.4.11.2.6) >> -endobj -744 0 obj -(4.11.2.6 Sort by Name or Type) -endobj -745 0 obj -<< /S /GoTo /D (paragraph.4.11.2.7) >> -endobj -748 0 obj -(4.11.2.7 Primary DateStamp) -endobj -749 0 obj -<< /S /GoTo /D (paragraph.4.11.2.8) >> -endobj -752 0 obj -(4.11.2.8 All User Areas) -endobj -753 0 obj -<< /S /GoTo /D (paragraph.4.11.2.9) >> -endobj -756 0 obj -(4.11.2.9 Wide Display) -endobj -757 0 obj -<< /S /GoTo /D (appendix.A) >> -endobj -760 0 obj -(A ZSDOS Functions Quick Reference) -endobj -761 0 obj -<< /S /GoTo /D (subsection.A.1) >> -endobj -764 0 obj -(A.1 Summary of BDOS Return Codes) -endobj -765 0 obj -<< /S /GoTo /D (appendix.B) >> -endobj -768 0 obj -(B BIOS Functions Quick Reference) -endobj -769 0 obj -<< /S /GoTo /D (appendix.C) >> -endobj -772 0 obj -(C Datespec and File Stamp Formats) -endobj -773 0 obj -<< /S /GoTo /D (appendix.D) >> -endobj -776 0 obj -(D ZSDOS Memory Allocation \046 Usage) -endobj -777 0 obj -<< /S /GoTo /D (appendix.E) >> -endobj -780 0 obj -(E File Attributes) -endobj -781 0 obj -<< /S /GoTo /D (subsection.E.1) >> -endobj -784 0 obj -(E.1 What are file attributes?) -endobj -785 0 obj -<< /S /GoTo /D (subsection.E.2) >> -endobj -788 0 obj -(E.2 File Attribute Meanings) -endobj -789 0 obj -<< /S /GoTo /D (subsubsection.E.2.1) >> -endobj -792 0 obj -(E.2.1 Public file attribute \(f2\)) -endobj -793 0 obj -<< /S /GoTo /D (subsubsection.E.2.2) >> -endobj -796 0 obj -(E.2.2 No access stamp attribute \(f3\)) -endobj -797 0 obj -<< /S /GoTo /D (subsubsection.E.2.3) >> -endobj -800 0 obj -(E.2.3 Wheel protect attribute \(f8\)) -endobj -801 0 obj -<< /S /GoTo /D (subsubsection.E.2.4) >> -endobj -804 0 obj -(E.2.4 Read-only attribute \(t1\)) -endobj -805 0 obj -<< /S /GoTo /D (subsubsection.E.2.5) >> -endobj -808 0 obj -(E.2.5 System attribute \(t2\)) -endobj -809 0 obj -<< /S /GoTo /D (subsubsection.E.2.6) >> -endobj -812 0 obj -(E.2.6 Archive attribute \(t3\)) -endobj -813 0 obj -<< /S /GoTo /D (appendix.F) >> -endobj -816 0 obj -(F Clock Driver Descriptions) -endobj -817 0 obj -<< /S /GoTo /D [818 0 R /FitH ] >> -endobj -820 0 obj << -/Length 1124 -/Filter /FlateDecode ->> -stream -xÚVKsâ8¾ó+tUA±$¿´{"$$L%„§f³3s0 ‚«ŒÍÊ&©üûm©Å+ÅVÍIÒ§¯ßÝ–òFrß þg½É:×Cž0Á£d+""Å“8NW-ÉúÏìöyÖíÉ$¢œÝ_Ù7ÒS!KDDz‚3ÅSäõ‘3˜\?áN0››ƒ‚©Þ–ùBotÕ•œ¶Vøz¢HX¸ŒX$8éÉ¥±÷aÞ ýDÛ2f!Û\2&xÿ›º\‚ Ó!³kBoê®H釕ÔESså%½×ƒ|£M]¡èw/:¨[S”]NK'üH‰¯r¦9ˆ¥Ý;‰ˆcÈLÂR!wr;DâX þ}jн‚ÓðDÀ !g¶ns'UøïMñ3àq»Æ£…nÿ ¢Àèw„%œ8ªŒY …daè=Ô[gÒok›%W ¥LJ0#kõò´>=ÉdêŽ4p&ºXI»¡×‹«4¾B×`›\¡Ë’¬ÒÓÌ.Ï#ÇÄüá›N{Â¥Lüná”Wžs¡Ü±/·«uç.ëüÛáàt@8I #ɬ‹Mçǯ€,ÿfS¤RòáXÆ)¬%™uþ¡J‰b*†9‚$XúNøNÍÖEVƒ˜nMýfò öàÊh»¦^µ>Ž”æFÿ 0¡KàXï³È+ܽ,b¾k½xÑâ -‘_×÷›º }I—Åê󜴫–ÚsÚµWÐj³ñNÕ«/w÷ã¿Ñ•69NIp^™Én^  ©„> ]5VXA, ®ÛÝÜNXÑX­œ.‘:·ñ}"í8즒bfà4s™I™9áÔIÞÂ\A¶B¡¨.@‡Amï–~˜: -ºèN­yo¡CCR—<…Õ·HõE0gqûi¨·Ö¾¾ž” -°H†´Ì[çà'î°ƒž”)¡Î…Ÿ6 - -È™Ç%_ú» -WŒ„Gt cÞ³fö¸ €ûÂáö½Cæ§Ä]£W»ÒŽ(W ú}”=<¿d(Ù¿z´Ë9§ýé´?Î^}“~@Úë]{©-4Æm=„÷4â´ØlËÂÅ7º¹1˜ºvŸ?¸qµ¹§»©E`ÔÖ½3ze¯žd4eã»Ù Á¡å?Oñ¦ØÄ‰N»iH³Ñàå±ï¯'/ÓÉóìŽ!k}w!t -‰ÃÅ݃CíûcûËö|1ÃÒ‹?Žwc0–ý›fåbö¦6ž·ÔmïÌÅ^yÅÞbÒRï>‰°_çþ½ÁÒbôBøyNn—Þ¦í>ѺDŠQ€QrŒÐC”pqŒÒ*-ëê qÛ ¶ØÒ°ó-mÛ% -háUuk{.„Ñ6E{9ë5fÃg?´cúOœf_>šH>ÿ4\!8ªì -¥â$Bì)oÜõ÷9ãÔóáå°ÐÜË7í±§>*—Êc/³>»ø’HxÒ(ùÝ—äì7íôE‘üŽʪćÕYÛÓÁê²zó -endstream -endobj -818 0 obj << -/Type /Page -/Contents 820 0 R -/Resources 819 0 R -/MediaBox [0 0 612 792] -/Parent 827 0 R ->> endobj -821 0 obj << -/D [818 0 R /XYZ 72 720 null] ->> endobj -822 0 obj << -/D [818 0 R /XYZ 72 720 null] ->> endobj -819 0 obj << -/Font << /F16 823 0 R /F17 824 0 R /F23 825 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -831 0 obj << -/Length 2040 -/Filter /FlateDecode ->> -stream -xÚµ]sÛ6ì=¿ÂoSv±*êÃ’ÖÝn޽ÄéÕ©/r×»t{P$ÆÖ"K>Jn–?€;f·§½X$€øho°xƒë3¿—˳wWÉ uÓ‘?,±?ˆ…çzAœc™¦µI³¨FœC$%T‰ï -ZÔfíÛ4‰˜Þ7XÏܱûÁ$¢Ú­VœVCúŒëšÎîLÝïL&vRQ ”ÖB{s{³œÞܹ“OsÐ(Zz?öA5Å…©$À£×i”œ[ÌÝ…h…u…D@¡N+ >DŽ$œç5I`¾¦sºômûÒ• Á‡í+l"¤Û÷.XÏÆèxyEY6´acYâLçG™û;;Þ³émºa(bg»Va¯f$­3|÷ñ@Û·s³­åkãÁ#\Bk¦ šŒ4]Ÿo¶ZlE.¹ñÈ/pÌ~£)‚Ǩýò7wœÍm©CšìÃ+Þ‡Ú{Ûá†lg ›ûÉíÞvMø)…=vZôa|4‚ ø0Ì|˜ÐÁ^¾¦Ó™®]ϵ|AytÃó/Z6Bè×yóD4ëjC°ÇV$¯kÊܪYÑÑŽeC¿hY›¢Þ•’€¤Kì\Ó¶jÌÖ°9¨~ÎŒª*WæâyÕ“odmWSÇßN=hyZ(ÿ&¸J*> endobj -828 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [434.072 323.542 453.776 334.944] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -832 0 obj << -/D [830 0 R /XYZ 72 720 null] ->> endobj -829 0 obj << -/Font << /F8 826 0 R /F11 833 0 R /F23 825 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -836 0 obj << -/Length 491 -/Filter /FlateDecode ->> -stream -xÚmSQo›0~ϯðÛŒT`H`{jÒ¥Y«ªÓ@ÚÔi¸`ÅÁ‘måßÏøLÖV}Áç»ï>ßwwĨC1º]Äþ\׋Û•Q¹L—¨~F«­’8ŠÉ -Õ-ú…®¿>VWAHÁT4ò0Ù¾g‡ãçàw}giÂ$‰Ê<‡„§êæ’ðtóÒ+Ã;ª¤hÁ»à\Ë ]áS˜)p…€ÞÐSrßßH£¸o€J_p\X;šë#qTÔwÝLì9'ÁÚîÀ‚0ÁÃt7úÓ{švŒ*3ÅÏ–¾Œ±éé°×Þ–p~ç@ ·MOÕÀ´UœÅ® ûë¤AðÖÊ÷‘mP¬,›Ð±e|l%NªÚÿ©Ú0>x̵ÿŽz9ç‰ðí³ƒq¥]‘ýÕ{*½‚Þ?–á;ÚÈ?¶Ž®ÄkÅÛÎM§´»ÀM3¬ìú'¬!.ȱaÀñ UÇf†:(2lgdóÎ@ó Ôí'SVØw_ *Ú1ŸN‡¹0Ûó¹vØ®‡¼ëÝñ,}”·|èÀ9êW²— ûÄM[czÆ,ôL¨![ã8”g·Ýê~¬àfz%Çγñ9óH¦pT\úõv{cOÅ£š¹]½ü–(%I”Ç% -ó¼ŒI¡Tò -ô¥^üËëøØ -endstream -endobj -835 0 obj << -/Type /Page -/Contents 836 0 R -/Resources 834 0 R -/MediaBox [0 0 612 792] -/Parent 827 0 R ->> endobj -837 0 obj << -/D [835 0 R /XYZ 72 720 null] ->> endobj -834 0 obj << -/Font << /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -840 0 obj << -/Length 128 -/Filter /FlateDecode ->> -stream -xÚ3PHW0Ppç2€ÒN!\ún -–z–fFf -!i -æF -æ†zÆæ -!) -Ñ!™ÅšºÆÆÆ‰é© –‰L$3OÓÈB£$Beæç%æäTB”䤦•@%å$æekƆxÁíT026Ô35°TÐ53¶@Ød‚¢È5„ ËŽ) -endstream -endobj -839 0 obj << -/Type /Page -/Contents 840 0 R -/Resources 838 0 R -/MediaBox [0 0 612 792] -/Parent 827 0 R ->> endobj -841 0 obj << -/D [839 0 R /XYZ 72 720 null] ->> endobj -838 0 obj << -/Font << /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -876 0 obj << -/Length 1260 -/Filter /FlateDecode ->> -stream -xÚíš[sÚ8†ïó+|iÏÔ®%˲uµ“„¤ÉNÓ0NgÚì…*h -6#Ë»Ûýõ+Yì $mìÀø÷ùô~;tFNè¼; -Íö¤ôö`  B:ý¯N„A%Nè|qO‹Ü‹€+¨Þ”Þ_ý?€<:tøÈÑ;7ïäi`ê€`ˆÕYBLJi O<ŸÀؽ”瀮à…çËí°&Ï®NhoÈA1bÉ?ôðÁëÝ¿œbB¤ÄÈë‚B÷øÎ“÷ã•WŽ"·?f¥ÚCîU–{ò—*›,ßǟ➇ánnÐý+bb Ë~Ý„¦Âb4€>3ƒÆ‚ùÜë\÷þX½NŒÉo+Ùko¶„(2ˆúcªÉ\°Rü»ÆU|ÕÛ×ê%‘\Y;%év"§L´6dÀtØm"Êi> fñœP¡\íõA¥s/V”¦•åCƒ­Ó‚ÀdGtoU­­t¼¦Ò§Ý·WZ_À7Fé£>’ê{ÀÞ‡²êré¯íV[’Y»¼ñlªuêUÓiÆ™Õw©ËlDBÅñÞåèVñã§Ä‡0 5Ô@è>d‡W  î¿ë—»‰«ª¶²qáOuöÍ„nFy]ä(O*6>3&qA'³Õk$Þóܸ6¼È9-¦2âÁ’!¿g9Õ=k t È.öÏW>yBù•–Ð’ SÓBMêÆðÜ#Ø¥™¨8-ïÓè᢬D1ÍhæV~ÓÌoè¤5V¥<âÐXàùPði6Y‚µš{8, gâë/™ù¨«rO&Ʀ ¾·pnÃ8œOé‘[ä“ïò+ÐXEºÝñu³™îÒ´ˆ_/ˆ%º¿Ã8,g)*Ñ´‰&ЯId{Á[‡oS?›6–ŽüœqCT›éé?•vÙ­î&vÕnÎÏè×ö8¶b„9ZL†•K߱ܢ>êЖEégî=¹ó´cGñ˜ó“‚ûíE -1ÕäY>Îòü“ê¤9³S¦.—=@kýŸ†xÏ—F+ ´vøƒÐóÓ»7Ô§õ3?Á%“kÛ/„}Ø|_*Žö} þ¢ldù×ó%‰áôDÛÍÇ’šÙø‡jª~Я¹Ù1†²¦Gf³8ŇùVØ@ÃfÞ w2AK‘MgêqÅê\RÍë¤É"^ŸE¤YÜT¹/ØÔð8-òÛ Q%µçY[Ipr°­À4Žk1¶VÕc£\½G…™Î%æAŸNþS“y0‘ÕÀ~é–ßt˜ÿ b×MF"­ü2©³þÑÿ à D -endstream -endobj -875 0 obj << -/Type /Page -/Contents 876 0 R -/Resources 874 0 R -/MediaBox [0 0 612 792] -/Parent 827 0 R -/Annots [ 842 0 R 843 0 R 844 0 R 845 0 R 846 0 R 847 0 R 848 0 R 849 0 R 850 0 R 851 0 R 852 0 R 853 0 R 854 0 R 855 0 R 856 0 R 857 0 R 858 0 R 859 0 R 860 0 R 861 0 R 862 0 R 863 0 R 864 0 R 865 0 R 866 0 R 867 0 R 868 0 R 869 0 R 870 0 R 871 0 R 872 0 R ] ->> endobj -842 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 680.149 151.106 689.06] -/Subtype /Link -/A << /S /GoTo /D (section.1) >> ->> endobj -843 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 661.22 197.253 670.131] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.1) >> ->> endobj -844 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 642.291 186.045 651.202] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.2) >> ->> endobj -845 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 621.425 210.702 632.273] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.3) >> ->> endobj -846 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 604.433 290.957 613.344] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4) >> ->> endobj -847 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 583.014 340.909 594.969] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.5) >> ->> endobj -848 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 564.638 248.173 575.486] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -849 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 545.709 282.212 556.447] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.1.6.1) >> ->> endobj -850 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 526.78 199.882 537.628] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.1.6.2) >> ->> endobj -851 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 507.851 247.537 518.699] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.1.6.3) >> ->> endobj -852 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 480.897 130.324 489.725] -/Subtype /Link -/A << /S /GoTo /D (section.2) >> ->> endobj -853 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 460.03 207.769 470.879] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.1) >> ->> endobj -854 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 441.101 221.523 451.95] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.2) >> ->> endobj -855 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 422.172 226.892 433.021] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.3) >> ->> endobj -856 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 403.243 225.729 414.092] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.4) >> ->> endobj -857 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 384.314 207.824 395.163] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.5) >> ->> endobj -858 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 365.385 220.388 376.234] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.6) >> ->> endobj -859 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 348.393 187.124 357.305] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.7) >> ->> endobj -860 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 329.464 190.86 338.376] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.8) >> ->> endobj -861 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 310.535 207.077 319.446] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.1) >> ->> endobj -862 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 289.116 261.014 301.071] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.2) >> ->> endobj -863 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 270.187 346.333 282.142] -/Subtype /Link -/A << /S /GoTo /D (paragraph.2.8.2.1) >> ->> endobj -864 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 251.258 321.648 263.213] -/Subtype /Link -/A << /S /GoTo /D (paragraph.2.8.2.2) >> ->> endobj -865 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 234.819 202.483 243.73] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.3) >> ->> endobj -866 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 213.4 284.122 225.355] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.4) >> ->> endobj -867 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 196.961 230.185 205.872] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.9) >> ->> endobj -868 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 176.095 209.678 186.943] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.10) >> ->> endobj -869 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 157.166 231.375 168.014] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.11) >> ->> endobj -870 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 138.237 229.936 149.085] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.12) >> ->> endobj -871 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 119.308 215.075 130.156] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.13) >> ->> endobj -872 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 100.379 251.66 111.227] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.14) >> ->> endobj -877 0 obj << -/D [875 0 R /XYZ 72 720 null] ->> endobj -878 0 obj << -/D [875 0 R /XYZ 72 700.172 null] ->> endobj -874 0 obj << -/Font << /F16 823 0 R /F28 879 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -915 0 obj << -/Length 1249 -/Filter /FlateDecode ->> -stream -xÚíšIs›HÇïþá¦7–£-l)ËR\5åd”Ô‘¨hÀžd>ý44 ¥!’;N"¡¹ˆFBýÞë¿¥Me¢˜ÊÝ…Y{5•d¢ðÁãÝÅuxqy Å5\ ZJøY±¡bÓ0‘­„c壊4Ý…DõiÍfñb¢éÈÁê³ÔÀÓt ò‘öWø¡¾‚‰eŒØIñÐ)>ï~y»ygc`×Utà.tËû€ÝÅ„pûR³)ÍX¬4:*M¢,^°§™ð·ƒoiFçÛOöQ‡®­šNLóGØußáW~Õa€TFiw BÃX°Fa€ñŽ=˜KÞ à¦ù'Φ|ä?¡æ õê~ì>vñÏúß¿Ø>r€04.CËVŸÒÚÛ¿Ò¶Ün9ìáÝ}Í&¾°äÛKh®%∮—…œ,3~êÅé¸Î1‚RˆQ‰˜û-æ~[èÄ “è$Y&ü¬OÓ4šÐT✺8ÈÑÔÛd¾Ewž{ƒþî¸uK  c Eoaûf÷ޣఎyêÓÿpÆD‚1na¼ûçµ/.nÄt~ÇŸ?†ù ‡^oÜ`F÷f|}iìå 7A´s ÜÆ3ÊGAÍWeèÁ ÆVÊåBx&àÿ-ñ¦Öt@gt”Õ¡Œ?D± $‰_5h³G~zt >ùž5¬7Kl]R¹ ìÜve6G.yв19òø%›ò‹Ç s£+kª-·ZSÃ*O¿÷B¿Ï“å$‰æb\m˜Œ›Ø«ev˜ÐU”Ô.§1)‡ÿ¹rc/ÊhéÊEý„¿ûÉ$æð)ô6B”cáSMÈ1KÈÒ:!/¸T«b®ÏM"&á¯ù¸tó~)TLiPGYo“³Ö©øÙ›¯•C–)xŸ/ˆ"Q‚OqIÛo:9¾z›ÿ’Ã%aë„§P†”_šk‚ÿà‡žÿؤ -Èljµ$”ÕRë@Éâ%hò[ []ŒÁ0”RKÀÔÃEÀƸ[aÂ;¢Eh«êj­¾YÈíH &“­,†í’]¤¨¥uñLá.Y¾,ÆU åëï(,/) Å#r6'ŒäòfTçÍ-¸7ËÅ;/ëöIÿ~åÊ3šê¢èØDŽ›)"ÛÉpk8xŽç…MX¬ó«"ìgÜR]Ã¥2\_5BÔh1¢ã6·,úx´(ïLñß/¢ü"lìú>vÀrkx¤«Y4ZWtzúŒSj¶_5¤ëV[È9îr4›#^¼ÑŠÞâYo¾@Ø]9ívq^ްÙîÛÔ±˜ÊtXéÉÔ×ëßSJóÍJ‰T=x”'j³e™fŒ÷ßóTDj Ï®(I$\½ª÷^Òl9ÿÍM3[TòÜÖmÚê¼²Ën§ásÀ¾ -¢ã¸G-ÁDV‚Q-Áa% ^üɈ&”J6Œ -£˜“]mgÌ/ì“Yáþ©HÍ9=Ýx?¯\—ª„n½}0ú 5ϪG—¡ôñdZåÓóeòMØsHàqNeK -j‡¶ŸVµ5¥¸œ©rÕQ[E#±¼ ÉoDm)D¸Ú`6“-¯*!ЯqºÞyVtÆŒ˪¹;Fxdþ³½Å±þXÀ°m¶(C™%—mW» /þtDö -endstream -endobj -914 0 obj << -/Type /Page -/Contents 915 0 R -/Resources 913 0 R -/MediaBox [0 0 612 792] -/Parent 827 0 R -/Annots [ 873 0 R 880 0 R 881 0 R 882 0 R 883 0 R 884 0 R 885 0 R 886 0 R 887 0 R 888 0 R 889 0 R 890 0 R 891 0 R 892 0 R 893 0 R 894 0 R 895 0 R 896 0 R 897 0 R 898 0 R 899 0 R 900 0 R 901 0 R 902 0 R 903 0 R 904 0 R 905 0 R 906 0 R 907 0 R 908 0 R 909 0 R 910 0 R 911 0 R ] ->> endobj -873 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 707.104 175.778 717.952] -/Subtype /Link -/A << /S /GoTo /D (section.3) >> ->> endobj -880 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 688.175 250.747 699.023] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.1) >> ->> endobj -881 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 669.246 295.274 680.094] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.1) >> ->> endobj -882 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 650.317 261.54 661.054] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.1.1.1) >> ->> endobj -883 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 631.388 276.926 642.236] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.1.1.2) >> ->> endobj -884 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 612.459 303.383 623.196] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.1.1.3) >> ->> endobj -885 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 593.53 282.959 604.378] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.2) >> ->> endobj -886 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 574.601 279.915 585.449] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.3) >> ->> endobj -887 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 555.672 240.895 566.52] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.4) >> ->> endobj -888 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 536.743 259.104 547.591] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.2) >> ->> endobj -889 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 517.814 248.643 528.662] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.1) >> ->> endobj -890 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 498.331 313.29 510.286] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -891 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 479.956 238.127 490.804] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.3) >> ->> endobj -892 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 460.473 334.322 472.428] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.4) >> ->> endobj -893 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 444.035 295.689 452.946] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.2.4.1) >> ->> endobj -894 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 423.169 279.223 434.017] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.2.4.2) >> ->> endobj -895 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 403.686 350.539 415.641] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.5) >> ->> endobj -896 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 387.248 301.501 396.159] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.2.5.1) >> ->> endobj -897 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 366.382 285.035 377.23] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.2.5.2) >> ->> endobj -898 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 347.453 293.835 358.19] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.2.5.3) >> ->> endobj -899 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 328.524 279.874 339.372] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.3) >> ->> endobj -900 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 309.595 352.878 320.443] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.3.1) >> ->> endobj -901 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 290.666 270.976 301.514] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.3.2) >> ->> endobj -902 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 271.737 257.638 282.585] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.4) >> ->> endobj -903 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 252.808 332.579 263.656] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.4.1) >> ->> endobj -904 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 233.879 267.988 244.727] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.1.1) >> ->> endobj -905 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 214.949 270.755 225.798] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.1.2) >> ->> endobj -906 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 196.02 273.55 206.869] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.4.2) >> ->> endobj -907 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 177.091 360.087 187.94] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.4.3) >> ->> endobj -908 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 158.162 313.594 169.011] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.3.1) >> ->> endobj -909 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 139.233 375.169 150.082] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.3.2) >> ->> endobj -910 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 120.304 395.703 131.153] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.3.3) >> ->> endobj -911 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 101.375 379.625 112.224] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.3.4) >> ->> endobj -916 0 obj << -/D [914 0 R /XYZ 72 720 null] ->> endobj -913 0 obj << -/Font << /F28 879 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -951 0 obj << -/Length 1164 -/Filter /FlateDecode ->> -stream -xÚíšMw›F†÷þ,ÑB˜ùféX–{’ÈhrÒ´ *å9E ŠãæÏw†a¤ArB£VÞ!,£óÜ;ï}ï\kf¹Öõ™«@¼ºV6³Ô›w×g¯Â³óa`Q‡zгÂ; ¸Ô H`ùÀu\ä[áÔúd#;¸×c;䋼×GÛi"Èþ%çÉL½ýu|9z;¼¹VðÀ‹{õùeœöú0°'=ñòg~>.¢¹ø7¿‡?U¿ÍúÔG˜ØN¯O\÷À¿@l¬}l¢µp‚X}8ÒI–Ðóí[‰#*J*÷Dž(|‘æ{õ…çEuuåæO (>4„˜Ò½àu›ÈBMv¼|›±©b)²Ö¸ ÜÃL·Ã>„uÁè{ÔñµDN:*B,($B£±@ D¢à1/DtlÎ6>&žC0'ê»´¼Ütãµûb Béz¨µåBh_Žn?ªØÕ ']È%ó¨Î†î@gßH;hòH§ü@ºÁ I¼nÑ/%èt>ªˆKq"¬úæìš‚™˜´Ã»•n•ÌO=âHÁ,*ûC½£\26}9M‰ZBT™6C¶áóT<Õ-ÆF´´Ú•…{Ãó ‹ã(aé2ß›øÚ7Ç•W{/ºêª¯ˆjc"C8až÷x·Zá&M¸Ç-û›Mw<žãïaŒtp­±[»‚Õ#šríK %Âuéà^ódmÛT]@»³§ò¯øoÅ_Ù†ÕÓ‡źÖÝGY4)Xf -2ÆÉ}éê2ð€ãûVúDñ]oL®Â³ýcÏa -endstream -endobj -950 0 obj << -/Type /Page -/Contents 951 0 R -/Resources 949 0 R -/MediaBox [0 0 612 792] -/Parent 953 0 R -/Annots [ 912 0 R 917 0 R 918 0 R 919 0 R 920 0 R 921 0 R 922 0 R 923 0 R 924 0 R 925 0 R 926 0 R 927 0 R 928 0 R 929 0 R 930 0 R 931 0 R 932 0 R 933 0 R 934 0 R 935 0 R 936 0 R 937 0 R 938 0 R 939 0 R 940 0 R 941 0 R 942 0 R 943 0 R 944 0 R 945 0 R 946 0 R 947 0 R ] ->> endobj -912 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 706.55 350.996 718.506] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.4.4) >> ->> endobj -917 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 688.175 314.535 699.023] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.4.1) >> ->> endobj -918 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 669.246 228.137 680.094] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.4.2) >> ->> endobj -919 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 642.291 169.109 651.202] -/Subtype /Link -/A << /S /GoTo /D (section.4) >> ->> endobj -920 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 621.425 198.083 632.273] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.1) >> ->> endobj -921 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 602.496 199.937 613.234] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.1.1) >> ->> endobj -922 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 583.567 209.623 594.305] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.1.2) >> ->> endobj -923 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 564.638 250.581 575.486] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.1) >> ->> endobj -924 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 545.709 278.559 556.557] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.2) >> ->> endobj -925 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 526.78 272.665 537.628] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.3) >> ->> endobj -926 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 507.851 280.164 518.699] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.4) >> ->> endobj -927 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 488.922 288.882 499.77] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.5) >> ->> endobj -928 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 469.993 241.697 480.731] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.6) >> ->> endobj -929 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 451.064 272.388 461.912] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.7) >> ->> endobj -930 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 432.135 243.385 442.983] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.8) >> ->> endobj -931 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 413.206 343.123 424.054] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.1.2.9) >> ->> endobj -932 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 394.277 243.607 405.125] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.2) >> ->> endobj -933 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 377.285 183.443 386.085] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.1) >> ->> endobj -934 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 358.356 260.848 367.267] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.1.1) >> ->> endobj -935 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 337.49 327.874 348.338] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.1.2) >> ->> endobj -936 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 318.561 288.688 329.409] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.1.3) >> ->> endobj -937 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 299.078 260.516 311.034] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.1.4) >> ->> endobj -938 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 280.703 228.026 291.44] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.2) >> ->> endobj -939 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 261.774 263.477 272.622] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.2.1) >> ->> endobj -940 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 242.845 293.309 253.693] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.3) >> ->> endobj -941 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 223.916 299.481 234.764] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.3.1) >> ->> endobj -942 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 204.987 270.257 215.835] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.3.2) >> ->> endobj -943 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 187.995 295.274 196.906] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.3.3) >> ->> endobj -944 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 167.129 246.817 177.977] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.3.4) >> ->> endobj -945 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 148.2 285.339 159.048] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.3.5) >> ->> endobj -946 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 129.271 247.537 140.119] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.4) >> ->> endobj -947 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 110.342 264.777 121.19] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.4.1) >> ->> endobj -952 0 obj << -/D [950 0 R /XYZ 72 720 null] ->> endobj -949 0 obj << -/Font << /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -989 0 obj << -/Length 1216 -/Filter /FlateDecode ->> -stream -xÚíšMw›F†÷ú³D Ñùb`–Ž-ç8ÇiÜçäÔÍ‚ ±Ì©* :nÿ|g`„%fT7Tv%Ü…FÂXϽ¼÷½w€` x;€z‹ä+ù Ô;ßÞ„ƒÎÀ]Î0á-@¹>áÀGÐ…ÄáÜ8ÔÅ®üŽf¾óar5DNž¥òwg)wËáˆê\Šß‡8pÄ|ø%|×\ÜŒ<8îPnà¿¡œ?ïZß!ä9 o6à _G(p9æ›À‰>¹~óþ"T‰“åõöçñçšú$΃eY´/í{ð`°ÿ;úV¦¤Sª™^©TŠ"YÌj õ¬ídBÑ,´A]«É8Ï¥ŽÔu®òl8’I‹éJªë4ü9æ¬×I½•Û{d¾n1? êˆüAwòQ>ëLÎE\fy"Læ>>Ú.}ÿ)=ò¨ës¯ YVwûùÅåøDIv~¬Éþ©B”Û½ÔŽåIÜîè†w;Sª†>ÞòoFùR=¡~+²ø5_ðÕLž¬á@ݼm¼œŽ‡ïÔ*3ÖµðaQåè›QŸÏ8¼†pØåˆ¶LÝú±¤^˜YI"[ÌÃã—vÿû—y醽 ïĶ‚HdËjö!âDÍWãfí@}F̧F¢û¸K½¹’6Wmòvóã½ÒñÑÓˆ1—*X9W:@îL²¼lÔ¿nÔDU ÍvÎïñÀÈ'Ýr¶RÅòúñÑ„“8–¦®½f˜ µ–‰2J—fïÇfÈl%D;"šÐ†ózD5×ë ÕnDÍ#J&ÂúѬuÆH5ƳÍ`V…q£zŒ¾‚)Ø^ÙzkA¼ËÕû&?'E)R=‡T‹GFGüì%è…ò;³c»Ø5÷öu!ô¬üDŠ ¥ÓE½Ï»ÑîrLÛ¶çì±N|Ÿô÷ò¬Ä1aýªÉÙÀ™ÌI˃ŒÒ~ X¬@½N÷8mLŽuB¨ÿgnÒmÞFUCŽÁˆ`—@Mv{d;¤ Ø -endstream -endobj -988 0 obj << -/Type /Page -/Contents 989 0 R -/Resources 987 0 R -/MediaBox [0 0 612 792] -/Parent 953 0 R -/Annots [ 948 0 R 954 0 R 955 0 R 956 0 R 957 0 R 958 0 R 959 0 R 960 0 R 961 0 R 962 0 R 963 0 R 964 0 R 965 0 R 966 0 R 967 0 R 968 0 R 969 0 R 970 0 R 971 0 R 972 0 R 973 0 R 974 0 R 975 0 R 976 0 R 977 0 R 978 0 R 979 0 R 980 0 R 981 0 R 982 0 R 983 0 R 984 0 R 985 0 R ] ->> endobj -948 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 707.104 256.392 717.952] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.4.2) >> ->> endobj -954 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 688.175 292.728 698.912] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.4.3) >> ->> endobj -955 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 669.246 268.762 679.983] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.4.4) >> ->> endobj -956 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 652.254 247.221 661.165] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.4.5) >> ->> endobj -957 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 631.388 366.286 642.236] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.4.6) >> ->> endobj -958 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 612.459 274.823 623.307] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.5) >> ->> endobj -959 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 595.467 233.174 604.378] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.5.1) >> ->> endobj -960 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 574.601 243.385 585.449] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.5.2) >> ->> endobj -961 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 557.609 238.515 566.52] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.6) >> ->> endobj -962 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 536.743 290.016 547.591] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.6.1) >> ->> endobj -963 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 519.751 258.495 528.662] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.6.2) >> ->> endobj -964 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 498.885 281.991 509.622] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.2.6.3) >> ->> endobj -965 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 479.956 284.122 490.804] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.3) >> ->> endobj -966 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 461.027 222.215 471.764] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.3.1) >> ->> endobj -967 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 442.098 323.031 452.946] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.3.1.1) >> ->> endobj -968 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 425.106 304.296 434.017] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.3.1.2) >> ->> endobj -969 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 404.24 272.748 414.977] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.3.1.3) >> ->> endobj -970 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 385.311 270.478 396.048] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.3.1.4) >> ->> endobj -971 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 366.382 264.058 377.119] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.3.2) >> ->> endobj -972 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 347.453 254.04 358.301] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.4) >> ->> endobj -973 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 328.524 227.279 339.261] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.4.1) >> ->> endobj -974 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 309.595 313.262 320.332] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.1.1) >> ->> endobj -975 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 290.666 304.241 301.514] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.1.2) >> ->> endobj -976 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 271.737 259.824 282.585] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.1.3) >> ->> endobj -977 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 252.808 292.064 263.656] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.3.1) >> ->> endobj -978 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 233.879 366.037 244.727] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.3.2) >> ->> endobj -979 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 214.949 320.098 225.798] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.3.3) >> ->> endobj -980 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 197.958 263.587 206.758] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.3.4) >> ->> endobj -981 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 177.091 317.054 187.94] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.3.5) >> ->> endobj -982 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 158.162 326.103 169.011] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.3.6) >> ->> endobj -983 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 139.233 308.668 150.082] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.1.4) >> ->> endobj -984 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 120.304 286.031 131.153] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.4.1) >> ->> endobj -985 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 103.313 247.26 112.113] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.4.2) >> ->> endobj -990 0 obj << -/D [988 0 R /XYZ 72 720 null] ->> endobj -987 0 obj << -/Font << /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1026 0 obj << -/Length 1210 -/Filter /FlateDecode ->> -stream -xÚíš[sâ6Çßó)ühpu³%=¦\Òt’ÀowöÒ/8ijÆP0dúå+!°%âv1y&f†Ëïýÿç Xc XW »Bñ¬ùØROî¯.~õ/~é2‹;ÜCžå?XBÇCÔ¢8SËY_lâŠ?ÜhB̸ÝÒ°ÑÄÛƒY£‰˜£¯’aFÓdÑøÓÿ}ý™Ö—&€ÙN£ép¸ áüàïiº” „®M½Âm«ÕDÜaŒYMÈŽø6FW@DµýÇŒak:™ÅaN´{}Ói7µ/ŒØ~GÞ%ö íçDÞNƒ§òwr]tÿ}E’ -’P'‰GHÈ`½e:Ì–iùc9À?5¥”Ñô¥8ì ƒ³„n‡Á2NU·£Å,BžµPús‚y‹øë°½=`g”sÞB«Dx:OÑzþM®„ìþåp.Y<¤d—uƒº?œÏ‘²×ïÆáЈôvºò»Qôð¼›+æäÔ²J@Iônš»Ù4Q×û0µÁß’q¨Ú&¡V)¸„ÖK‡×Ý‚»(Ò½‹(g¥BLfYQÓÞZ? ÒeþÏ2¢3Ÿ‹*b:WÿÝ -9 Ɔ´uÙ©S­ -ž¿\ #‡CR/³ dßwnzWŠî?¹T,ÂMñ=KêçEN´¤^-‹†ŠÁ`àÕÂâeaðÛ¥™ùÉhÓé†v›V¬¬p(5ý»BNæ‘ÍËq2¯oUjK±ú°‘{¹2{ÈÏú[‡G_Fën4_HÂ8”k஫¥4&°¢±ÐLÑ>·.o -š¦Uù·S5Py,æsµ•ýリi5iØ*Vå)Á‘‡Z5X2¨Ú G„d=ÃÉW Î+®¬økÍÃI¨Œ¦d”’“ K5’À &Rp 3[îñ³Ka#j\±s£kËÝ(ý¦ëT“ÒåXøÍ:ÎÖ6{ו)žõpÍ|K#‘ûAãå|µ#¤n~H£8J#að÷Òs¯p숆ÙUóДµ‡xõBy˜T©³:±‚§n-lû †íéx‡Z]jØ9E°&ýš‘.yµÏ²‚ÏÀþ!Áñr®žW3¡9 ]¼sˆßêõ?éM,®³HïÛ}ÑH]Q´p·ŒœçFÚ—é{)üßïf¾•f‚>h÷ê^_æu ·®@~>]УcöUnôÕ¾Ü!P‘*bÞû´ím"d6Z¾m´[É–Po¶©?[Á<¦«!¶ÜÕÑ]ÁZú€ûjàÛ.«Sí<òÈ’>8‹´72®zމoÚXݶúÙõ>ÌG`ždr¤:]™Ò¦n—s^¯rœVlW!o+]vÐêÝu¯‹;Ž›n5+x‚lìµL’êoÌ×¼‰?YñeÕ쩽r¯¯ÈõZM½B)·…C«ã3ÔiGfõήµ|ý1Á™xwžf+®á<ÝâÌìÑjÏV;õEÎû¬#ãUÀcxU^èçAy/Â5îV+ñ$|©3T#ýå7‘Óq4Tü»QœŸ…ú -\°¥Ñk¿üÜ÷Ä‹P+Õ¹wªz]"¹~zСT”Èn¤ø“½ã_ü HBf -endstream -endobj -1025 0 obj << -/Type /Page -/Contents 1026 0 R -/Resources 1024 0 R -/MediaBox [0 0 612 792] -/Parent 953 0 R -/Annots [ 986 0 R 991 0 R 992 0 R 993 0 R 994 0 R 995 0 R 996 0 R 997 0 R 998 0 R 999 0 R 1000 0 R 1001 0 R 1002 0 R 1003 0 R 1004 0 R 1005 0 R 1006 0 R 1007 0 R 1008 0 R 1009 0 R 1010 0 R 1011 0 R 1012 0 R 1013 0 R 1014 0 R 1015 0 R 1016 0 R 1017 0 R 1018 0 R 1019 0 R 1020 0 R 1021 0 R 1022 0 R ] ->> endobj -986 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [170.63 707.104 305.652 717.952] -/Subtype /Link -/A << /S /GoTo /D (subparagraph.4.4.1.4.3) >> ->> endobj -991 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 688.175 333.437 699.023] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.1.5) >> ->> endobj -992 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 669.246 229.216 679.983] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.4.2) >> ->> endobj -993 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 650.317 251.715 661.165] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.2.1) >> ->> endobj -994 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 631.388 317.718 642.236] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.2.2) >> ->> endobj -995 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 612.459 327.265 623.307] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.2.3) >> ->> endobj -996 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 595.467 287 604.378] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.2.4) >> ->> endobj -997 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 574.601 293.946 585.338] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.4.2.5) >> ->> endobj -998 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 555.672 263.643 566.409] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.4.3) >> ->> endobj -999 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 536.743 239.912 547.591] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.5) >> ->> endobj -1000 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 519.751 224.041 528.662] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.6) >> ->> endobj -1001 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 498.885 185.547 509.622] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.6.1) >> ->> endobj -1002 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 479.956 227.39 490.693] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.6.2) >> ->> endobj -1003 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 461.027 214.134 471.875] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.7) >> ->> endobj -1004 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 442.098 197.723 452.835] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.7.1) >> ->> endobj -1005 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 423.169 307.977 433.906] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.7.1.1) >> ->> endobj -1006 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 404.24 244.05 414.977] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.7.1.2) >> ->> endobj -1007 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 385.311 239.566 396.048] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.7.2) >> ->> endobj -1008 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 366.382 247.246 377.23] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8) >> ->> endobj -1009 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 347.453 205.541 358.19] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.8.1) >> ->> endobj -1010 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 328.524 290.03 339.372] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.8.1.1) >> ->> endobj -1011 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 309.595 285.879 320.443] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.8.1.2) >> ->> endobj -1012 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 292.603 250.691 301.403] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.8.1.3) >> ->> endobj -1013 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 273.674 228.054 282.585] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.9) >> ->> endobj -1014 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 252.808 196.616 263.545] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.9.1) >> ->> endobj -1015 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 233.879 301.169 244.727] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.9.1.1) >> ->> endobj -1016 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 214.949 262.231 225.798] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.9.1.2) >> ->> endobj -1017 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 196.02 305.735 206.869] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.9.2) >> ->> endobj -1018 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 177.091 335.858 187.94] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -1019 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 160.1 272.208 169.011] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.10.1) >> ->> endobj -1020 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 139.233 255.742 150.082] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.10.2) >> ->> endobj -1021 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 120.304 232.385 131.042] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.10.3) >> ->> endobj -1022 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 100.822 335.983 112.777] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.1) >> ->> endobj -1027 0 obj << -/D [1025 0 R /XYZ 72 720 null] ->> endobj -1024 0 obj << -/Font << /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1061 0 obj << -/Length 1271 -/Filter /FlateDecode ->> -stream -xÚåš]S«8Çïý\íÀE‘$¼$—µµÎÙYn[×Ïî¶±2Rp =süö›ð„¾µÊ íêMKJg~ù?¯Á1f†cœ9úÉOÇÈf\ ÏŽNÆGÇj0›ùØ7Æwr‘fȱã©ñÃtm9"6¶:˜—‹[ ™q49¾´p`†âÞêBÌk‹3‹‡áiÞÆúúÇsnFý‹ Ãdª.\ó¦/“7‘õïø÷å2æaÓ¶:žã´ðå2¶íÞ³iBžÉ6WS…&?;ˆÚ ³ <ð y8í\$ñ<ë_Š -Ÿˆ4ƒñh‘‹0JrÁÄå%<¸ð ,êša.àAÑ/>…‡ïGù\ yœÎà~= ²ë´è­_mâò׊Jï>Lf|ÍÔÂ,‰’YC!y­pÚ­ wçäk§daºæŠ"qŸ.„¶¸§\ð9ð調 ‘E· Qï›Ri¹µÂBìPEš‘ -´¢Ê'ñ0›(Ú¦7%¨C: œp^ßs£“'ÁkCáe– -º4æ“ýiÍm‡œq4׆ңdÍäzqju¤ø ->š~ýTCžšy6—¡=x/¯'äHÔH„óGxÂ?tp$fw2áy.™!SkdÅóí?ÞK>[¥ƒ*tzK³*i¸¯uVÄó>Ô‡·)0¿!B\Ax†7îž^T•LÓKKï%{óÙaúõ !1Äθ6þÜñŠÑ’ä«eçÑà$4Ú›«…Ö6Šü}¤ò «¢Ø:Ù”¢x’œïJ õ.¾¾¤Ó,+KÆsÂÏ«–GSWïoÛl'mŒm†Ü -mQTÊzów0wt³â—àÉtUŠfEÅ®ý㕈âH¨ìø©Ú§  oŸ[°mlz¿ÊuùêÛñl’À£ŸYÕûܧfO°öA¥]\<Š(M*.Çû Zäp“³7l‡/w9ήíØäž(K Š˜ëò‘˜ƒ(–‘ ¸¼—µÂFcã¹—"䓊f„k_¶³ûËz¢åq¨@j¨UƧÙ<Ot?ìÛäK–ÌÕAÀ -¶J¿§j\ÖúîÆãâîcÑ®àÕ£0ïSfmòÖ-©a©ì¹j$†eQ£_ú¶ôâÈɲÇ8äb‘é—.zºÿ]m¨a~ -¶V&þ%RîɺDN¤D(6O¾mUˆ«‚w+$@D)$Ø¢å)йÌÝ“sKI©à–«n36ùf„2 -4\Éð§Ì¢hK—Ë,ª½ª0|/ðå2è®eh}¹ D×­äœÏ¡Ÿ(—"ãEZ¬mÉzñ‡ßàÞ•êôVu‰•Óovv6­cf;HZ+ql‚|XÚ,ÝNÇGÿV,¼¿ -endstream -endobj -1060 0 obj << -/Type /Page -/Contents 1061 0 R -/Resources 1059 0 R -/MediaBox [0 0 612 792] -/Parent 953 0 R -/Annots [ 1023 0 R 1028 0 R 1029 0 R 1030 0 R 1031 0 R 1032 0 R 1033 0 R 1034 0 R 1035 0 R 1036 0 R 1037 0 R 1038 0 R 1039 0 R 1040 0 R 1041 0 R 1042 0 R 1043 0 R 1044 0 R 1045 0 R 1046 0 R 1047 0 R 1048 0 R 1049 0 R 1050 0 R 1051 0 R 1052 0 R 1053 0 R 1054 0 R 1055 0 R 1056 0 R 1057 0 R ] ->> endobj -1023 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 706.55 399.19 718.506] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.2) >> ->> endobj -1028 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 687.621 398.415 699.577] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.3) >> ->> endobj -1029 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 668.692 381.424 680.648] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.4) >> ->> endobj -1030 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 649.763 380.427 661.719] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.5) >> ->> endobj -1031 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 630.834 389.006 642.79] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.6) >> ->> endobj -1032 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 611.905 325.992 623.861] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.7) >> ->> endobj -1033 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 592.976 399.08 604.932] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.8) >> ->> endobj -1034 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 574.047 411.533 586.002] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.9) >> ->> endobj -1035 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 555.118 402.926 567.073] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.10) >> ->> endobj -1036 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 536.189 335.402 548.144] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.11) >> ->> endobj -1037 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 517.26 373.011 529.215] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.12) >> ->> endobj -1038 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 498.331 348.588 510.286] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.13) >> ->> endobj -1039 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 479.402 346.305 491.357] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.10.3.14) >> ->> endobj -1040 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 461.027 264.542 471.764] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.10.4) >> ->> endobj -1041 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 442.098 259.658 452.946] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.11) >> ->> endobj -1042 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 423.169 191.912 433.906] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.11.1) >> ->> endobj -1043 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 404.24 201.598 414.977] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.11.2) >> ->> endobj -1044 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 385.311 290.902 396.159] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.1) >> ->> endobj -1045 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 366.382 275.404 377.23] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.2) >> ->> endobj -1046 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 346.899 320.126 358.854] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.3) >> ->> endobj -1047 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 328.524 285.727 339.372] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.4) >> ->> endobj -1048 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 309.595 262.093 320.332] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.5) >> ->> endobj -1049 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 290.666 282.157 301.514] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.6) >> ->> endobj -1050 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 271.737 271.917 282.474] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.7) >> ->> endobj -1051 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 254.745 247.675 263.656] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.8) >> ->> endobj -1052 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [140.742 233.879 242.445 244.727] -/Subtype /Link -/A << /S /GoTo /D (paragraph.4.11.2.9) >> ->> endobj -1053 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 204.987 263.096 215.835] -/Subtype /Link -/A << /S /GoTo /D (appendix.A) >> ->> endobj -1054 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 186.058 258.883 196.906] -/Subtype /Link -/A << /S /GoTo /D (subsection.A.1) >> ->> endobj -1055 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 157.166 253.438 168.014] -/Subtype /Link -/A << /S /GoTo /D (appendix.B) >> ->> endobj -1056 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 128.274 259.043 139.123] -/Subtype /Link -/A << /S /GoTo /D (appendix.C) >> ->> endobj -1057 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 99.383 272.768 110.231] -/Subtype /Link -/A << /S /GoTo /D (appendix.D) >> ->> endobj -1062 0 obj << -/D [1060 0 R /XYZ 72 720 null] ->> endobj -1059 0 obj << -/Font << /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1074 0 obj << -/Length 522 -/Filter /FlateDecode ->> -stream -xÚíWÉnÛ0½û+x¤d¸Šä©p(РHäö +Œ-T± ‰)¿):F´E{¨'Ž(‚šÑ{³°\NÈVR¿P/@|¸¾œœf““ÓÀ`“²d÷@1 (Á„+Ý[x‘ %œ••M×NΠsu9t¶I~dŸwßB¬©ô›ö.¥¬=ê=™½Ö‰—X+ -ÕØ0³ÕŒi‚´`ðf™;¯›s˜×6>|'T´qó`LBakϧ®A·­É8A’¡Æì=;"ÑùÍ<)•;šö»‰_{Ô°HÍÖ-<#Ó„é[ÄW_l¾*W‹f Sþ§ØHŒRÂG cØP1à%Iüú8¯Ê¢-> endobj -1058 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 709.041 162.696 717.952] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1063 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 690.112 218.894 699.023] -/Subtype /Link -/A << /S /GoTo /D (subsection.E.1) >> ->> endobj -1064 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [85.948 669.246 216.237 680.094] -/Subtype /Link -/A << /S /GoTo /D (subsection.E.2) >> ->> endobj -1065 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 649.763 247.786 661.719] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.E.2.1) >> ->> endobj -1066 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 630.834 275.764 642.79] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.E.2.2) >> ->> endobj -1067 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 611.905 265.663 623.861] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.E.2.3) >> ->> endobj -1068 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 592.976 248.893 604.932] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.E.2.4) >> ->> endobj -1069 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 574.047 236.079 586.002] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.E.2.5) >> ->> endobj -1070 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [108.862 555.118 237.989 567.073] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.E.2.6) >> ->> endobj -1071 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [71.004 526.78 218.453 537.628] -/Subtype /Link -/A << /S /GoTo /D (appendix.F) >> ->> endobj -1075 0 obj << -/D [1073 0 R /XYZ 72 720 null] ->> endobj -1072 0 obj << -/Font << /F28 879 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1078 0 obj << -/Length 2608 -/Filter /FlateDecode ->> -stream -xÚµÉrÛÈõî¯àmÀ*Æ2—”å­”ÇS–¦RåL- Iv 8Ý€dåëó¶@Šöd>áõëííK#ZìÑâËH¾W·/^½‹Eœ…iV$‹Ûí¢Le…QZ.nëÅ¿ƒx¹Šã$®Ûe½í–+øÖCÕ›®]þçö¯Þ¯›pS$n«d–›ŒwYÝ<¹^–«,Ûo»gèÓq ëmUoÚãxåK”ë ³ðÍ£àËÍ2Þ~ºyÉCãx­jù«Û½j+]óÈêc£*}Ðíï¹õGõ{8J3|¥œ©þ„(à Ù‰ãp“ÌŽg&-ãÀéÝt"º-ßüúê#BQ„‰LYþ~ù ¬0‡_y‘{ž@²úàÂå*Ï‹àZü=гÞ1lZþö{Í@»Äcªáaæ÷B×÷hTMÓ“•êAjssf±Gþ"®˜äBNCZÇ áº¹ègŸ~kv¦'aðY;Ú®l…KöÈ.|?{ƒÌ´¼.Ÿ^É×9ÆÔx|W­’2BI÷5OtCïL­G/1J ¦©g0ÍÎÄSd;8S‘ØÊ/ƒ{žTmÍê©Ñ¼°7}6]ƒ¨åü^ŽdïˆwÑ ®³}Èž„®H$&âKi–¥_z_|}GNL¢VóàvoC¹é¢¼èšy˜âš² ñò -sÚþ$èKÀªkq¤XD*l?žÖ ré-ª‘XòñfÍ ;G™o;4DXøâøÒ:ƤWï“tF5„¦M–QTI7 “/ÏöÌE(<­ý { 1E`0é•Ó‡x’GQ gÞ"X PÓjÆ£3 r¯›#cžèn`ôŽÌ¹çñ†K€ºœŒôÖZÆvr¾AÓšÞ€G>-×iΰβ9¹Epôò ë  4Cöª€æzTÆ©°'ûLƒVx]|~÷úíÇwaòÏ·<åÕ%,Šå× wkî†I5ÌïhlÅò_Å›°Lò¿®±[O÷{”‹Vý`µØ[^ÆB|ɸǽáp"ÔiEsnoµ -Rm5$ ™“ØÑ£å>âZ·gþ0:q­~0Ý tpŒuáÿ-†â¯‹áº…pÑ4’ó‘g„ÑlÁXªîpltOVHy3ö9!æ0r•5GÖ"È -á»gçãY9|Á–ÐTv o>Ÿ¸ÇôÌas+ÔrT¾g%1ŒRû¡B#ÛI’'ÁßzÓ€£i"Jr¨]¸ €ä²¹3˜HAÄI±¹à–ã`%4;M»¢ ›]+Hn¨×wó_Å¢FŠ%¹øöç4¢hJ SöC…t£)2+ ·:ÂÍÂ_[›ÑEfÁe–µáò,<,¡p|7†zÍ^ÙšŠ¯ÁÀ´ÅŠEôCù{Í×íšÎ9eŸ˜žyyÃÂA+äì<¯='} óÛôÃØÁ=¹¨C9hø#CåëÖ__믧LÜ“ŠŸ$FbëlíÎJ“ãÞ*çUyÎÍ<Á@®äM8‚„ ‰9*%1§£ä1nÌ"į¶ÛYu8pY“9V`‰â£Î‰‘áŒ[$p, )|¹yüÊ‚çÁ( ¶C[M‘T×ÈÔ«בìwjd¸ö®¹´ÕîµË.jd¨¿*²ôšFÏìÁKK5®Ïâ:}Ã4êÎW‰RW¦ÈÉýN -OU×yñºõ1K·Rô=öT)þk¯¤Fô" ìïß®E“>6a™âøë³ H ƹï¶d–£ÒZ!È­Bçýâ°ÃŒ€løÈ±æ(ŠåØ–¿œEp 5U4eù+M‚ÔT!0OÐçºåú"Úœ¡ŒÒ_§V¢8"Hløm«f¨ÉAhÄßJ99ë‰p…ØŸMSS^E4Šñqßñ ÚïÍg/:01½è€Zèmdïí;Ž$vBb¸r#Ä:õ{«õ%Í %N˜I4ž½ ¡ý¥ëàSë×NúÓ³W˜&ºb_BR‚œ²pÖ‡]_øyÑÂÔÍ$ZNCˆ¼’–™Û É&J² ÷mcÈ£é麉Ѓ³[æÏâ,P23îÆGš®Á~%ÍsîÒ _[Ãõ¾“)¶òüYXb$ 9…ît+ ì@& J|“‹)â{*wÌx»Óm×_bù¾õ (TĉàVó^*/‘é¸Öû!¶üD$®!Këg?H&ÈÔÁ@õ’_>EE:wÑFÛ—ü -;…`t_á¥/ëxc««þœ>y)MÇd^Šh>8f @È5T‘sLÌÖ³G ŒX>˜ÞµçéÑ4èMônñÄ ‰eÜÉËJkF&…ðéû-YCâoY^àµdU|‡4÷ù¡7ý :õ5íÕõ§›o®d+ˆk*Ú6,^ü>ZÓ÷ø“l¦…Sƒ3鶪—!+»EBºÂ—ž¬¢g5ZOµ6®FIx£ƒã2*47s%BL‰=ÍqÅ+|¬Å¨xÑŸ9ˆÆ¯hRéêŒ@LæÉ{Ç‹¹'})dð (œ4öÇàÖ¾føæ“& ©Îb -qÛ(É“s; -xé™ÓÄü6ßIÔ¸°RíO=OÜÍWS§xɨЈ=AóÃäGA‚EQšä )TFDüì× Øk9¨%Ü.Á.á¦'NÍœâý-Ͼ>P–GÔ/°®þ¯¨Ø#´ç°‡€—^ÐOþ™FÀ-* ¦œhÏY/ðÙêG¼<8—Ø^0™nthÜY×+º`d–žäO¡Žæ¾2Ÿõ•ä˽*o¨X¤¦5ÇÓï­ÔQÝɓظ­=yrX$É&Œâ ô„›p½^K[™œ,zwûâó½s& -endstream -endobj -1077 0 obj << -/Type /Page -/Contents 1078 0 R -/Resources 1076 0 R -/MediaBox [0 0 612 792] -/Parent 953 0 R ->> endobj -1079 0 obj << -/D [1077 0 R /XYZ 72 720 null] ->> endobj -6 0 obj << -/D [1077 0 R /XYZ 72 720 null] ->> endobj -10 0 obj << -/D [1077 0 R /XYZ 72 629.585 null] ->> endobj -14 0 obj << -/D [1077 0 R /XYZ 72 358.44 null] ->> endobj -1076 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F23 825 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1082 0 obj << -/Length 3307 -/Filter /FlateDecode ->> -stream -xÚ}Z[wÛ6~ï¯ð[èm¬ˆ¤(Q±“´ÉÖ­í=Ù“í> dqC,HÆqýÎ73 )—é“€\À\¾jyöp¶<û釥þ^Þÿðê]~¶]l×Éúì~¶IÎ6ñr±L7g÷»³ÿDÝÁµöü"Ýä‘óçqT>”µ©ª'!µ}ÓT¥Ý¡·‰Ëî ôî`…T¸cÓwÖ/Î/2ê¾ýfŽMe[aºý0ºÕñe]TýN7ü÷åûß§Í¹¡+çÑuYxw]Öç - ¼»Ë8_¾<ÿïý:ÛE/¶Y&§xôe×ÙúübE£?Ÿ'›èIÚצ"¥ýO{l^R3K#SÓQw oeGð_ï¾b3Z†æwB»?ÏÓ¨÷ŸÏ/ˆænÁùíZX"µx<ºÈõ&¦‹týƒ.­fÍÍA,§³ìÃQ Iå2Ewr®µú÷`E“Ò8¡žü’E•Âo@ƒ5¾“&kÔ÷\nÐDn\}¼ÆÈ'!“ŠJƒ4¨ð¶³:B‡èÖû0Ý*Æ,PÚ-Øú*ÒéÒovV—r³ímS‘òí0uM -¹³*=µD;á}Ác{γ¨rl³eÍù¢ +œ¨4HmGÇ!£Ô|f4ödÇnÔ ÝB<Ñý¡Ô‘']6••qzÃ]éê|³sG ¯žË«ãZÆÜÏ¢OwlJhâ­ñ«÷!ãÃÁÀp^‚‘ô.‡‰º¿´i]zØUˆ§ÐªuuVØAŒÃÔV·)k•‡´iæLÁ¼^´b¤awXnëö£æÓ-Ïúgö=«õ–]’g³ æ¸ÞŽÇ!êä…‰‡£ ‹\¹ºul¯XĬ¸àÜxq+…m[çI­³¥¸CžvuƒH¶žˆ„ˆ<îC¿·GÄ»ºeß0s+¯·[Ö¾ ´¯!ã#ªÍ/á|äÞ¶ìk k+œÇ;Y¢óÅidÀNEɘŽ:Aì–Ⱦ¯kÚþh•êI–zð+gÂ&bÓ2§;ŸE’mèìô–Þ–™­¶ÆÆ Ÿ—o£;+pÁãI™×•UÙ©wa<2Öø}™-Û>8PŒnüæý­4``T¥„ô͸±Æ3áãŠ@4òƒ`H«Çºª·áåK¡ÚÅ °ŒRE_0åêæVHdR¥U¶ú|6Bôƒ¢}«À†^zîpäk<MŸ¸Ì£ŠVòÒ웚ÑÀ7µ?˜0PçÎýi‚VK²EºN5½•7æÉC¢•^hL"@‡“‡Càp6''‡›Àº_‡×ÏÃõ2ð .!Zõ3ù&¨KNûVÖ´V{-Áa+#ÞcêêA¿¥ÌÇxͳæ´Û»F}=WB,I~ʼnlåš ÔK4Э*2$ -%j¤›8'}luÔé±0~r, Ø{k‡@ÈÄœ“žòg9&o] IŒÎ—®o…!¢ú–´¿¤œ9ïM"þ'KGÏš­¢Ÿ_"—QXB¢^úþ: : ×C„_9¬›èìù’µŒÓÌ wçK‘±+¿ÆPV¤*Íj" Á ã[§2|,+j¿œ³`šûc’Ñ;O¦£}µ¸\HëNƒÂRÍ^=Í ö!U~6ùÒÖÿ3GF[¸§ÓøÞ~üëðŸwÕNwÓ]/'™[ØVÔ–˜úh&‹8ž¯ ŒžæJÁšgoF„ e¸Î—ß)4±¹'©†(nQt1\=HRAøÖ%ãá43ZScf}Çp»Ä8g¡©FO4>ÝK€™œ–Î/+»¾Ð…‚”²Ûß]Ê*‰ÞXÊ,ZiÄ9üC4¹ì—è–>÷â=VÉÉ*¯«†l”›wR:‘Εó -º|ˆ&D…sÖ²ê*4¨a¿¶G±K R.PïRB¨SñØÆ¼Ab¶F*p›ÞXoN?^l4¾hôÔJ•×p±ïiRim Õ`=€Ïw!tÊÅŽˆ&ϵH¡JšÇš6·ÒÑ«¯¥+¡>FŠ“æK²ü¶” ÍS†ä„zÁhð´¬ÅûÈç¦êÿq#>mo‹NˆúL/dð¥a·þå'ïúš!¨e©âÔ³Øó éð]gŽÁ  N€(”uÉ.×'…\¡ðéW¥ÊG©ˆ8*uZxLIMSNGMZV¦ïÎëp9 ?âfa•É×G¿(FÏC˜;MïÈ݇˜¤ÓÂX¢PŒ R¤—vÂh¼ýŠÂ ‹GÑÒ¬I,Ÿ!=6±f¤)ùŠkPçƒîKZÙWŒ,u7½€$Ôi`¦¬2¬Þr®„AIé´6Ûš½Ulª¾ÈŽMÆ…„$Õ; ß^ ¹…ë+µ‡gèÌn`¦.w•cñíõwÓ”2‡á¨¤¾¼²«d.0'á« tãæ^Ìžæ4‡²r­kÁTÕÀ$¨ Ò3'ë±Î…öXÍÂh¹Ô᪠ù*yÙ€¥ˆáC\Ÿô­Š4[àÞ÷uPv:u ¸tS=ý)˜,<ð„¢Eó•hû&‹ê)¹ ·‡¦ã9Øcù§Üe jœ¬äâXžoèí8&ǘÍ0Fi:øž±4÷¹JEB\öÅ©µ©5°–‘ßvÈ숫îN²ʤDÆü¡ðµ”úþ×;Ž ¯‘Fd~õÛ¯ïÞÿôòfÑÝÛûÝ|¢ás"ØQ>mÈSVnD¹3Jǧ䑬ò·¦Óï8ãBcgsy**ûw$YÅVšä&¢…a(Þ%2Ð â¾÷úÍŠˆ{o&¥Ö$_ŒÒ4€CÙ¿¼z× ,.WY®¦Ñ­ÁêøÈµ^âº8ÉbaÊã© M߯=çjν÷ãm¦«HS9Ê4¿•ªY¶:wÙj€@h“bj6°“éd”8 ©)ÜE¹ÓéÇ1%£ñdžT²Õ F¯œWQ—iº¡)¼b…™h#OÓ„öÃTÂèÐüÕRÀŽÞÞÚJZ!GûY.D‰Ý‡R]ÃN©OÆW®scr†:Ç[$Úbƒi2cÀ2AL6M¦&K=ÍÖÒx4Æ9ì.ÝvÇÓð}U„•‹RÓÏ(ñùx{Câ3­^Ê\C¸‘A»²@9ý ɹ£Î o&Åd]…Y@:@g!–ÿ»œF´ä|.N§ÊÔ -EëL(aPÂÁváÈŠ˜ôˆ)ZœNï–zµ«/§,¡„@é+ä+³¸Lá†+T+E”V:%Ùk]L1¸Erí1 j)‘Rø˜ -²Fd’èoý«Ó¯D­‚c›ùîÌnmø‹ÆY’lËx{Fñc‘§Z‰Ó“Aoïø?TX¢ -endstream -endobj -1081 0 obj << -/Type /Page -/Contents 1082 0 R -/Resources 1080 0 R -/MediaBox [0 0 612 792] -/Parent 1084 0 R ->> endobj -1083 0 obj << -/D [1081 0 R /XYZ 72 720 null] ->> endobj -18 0 obj << -/D [1081 0 R /XYZ 72 433.581 null] ->> endobj -1080 0 obj << -/Font << /F8 826 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1087 0 obj << -/Length 2397 -/Filter /FlateDecode ->> -stream -xÚ­YYsÜÆ~ç¯@åEX a08“'KSqE1MÒ•D–S.†»ˆ°ÀxÅüúô5X€\YÅÄ/ÜAOÏÑ=_Ÿ ½z> å÷ÍÝÙë+•zJE’DÞ݃—E^¦Â Ô™wWy?ù*ˆWJE‰Y •6½iׯ®.t–øo̰ÒÊ?àcZ&~¸½üþ–‡e»R~%äK$ÿ|÷Ýë«Ü+‚"RÕMǨè€ ®ØÉ£e>=#rqÍ%àu@°âÄÁ°¦ìYyçø -,«bfÛ›­Ãð;¨>]צÑé´’N‘{`Ð_oJ+7r1@$&H:&úh³[h"eM,ÐqÇ!ãA« ¦Ï„Úü òë*IA5£ oÞÔëzpŠQˆð#‘²ç}™Ð[$ñ„\•ñªLT…‡péýàN`KÈ}ò k\݌讌p[þœÌ®0¡è -h…Öþ¬jû‡-ì\»/XÏÅÍ-Ѝ˜™›Ÿ:‚½‡X‘C€öÌ#„èìØ°Và‹¡|Ü.ãí„þ+Kè‹ü®•CÛrç~¸¸eTÐpŸó¨ëy=¹8¡ zS‡6à‚QJ©Ó -N¸,s;”;öûÂp:OÉy!Ç›@VJH‚aSöÓ<2Ooþ O`yFî¢&¿3œùÌÎÜ‘»ÚÑ|=äùI|Ôýe¬Éá—ù<€£!{‡0ê|ÏØð¼bœ_%¿èWI@…0—EµÀ;“Õi‰¶ÄS® Mm·nÇ -ƒáÓ…Ì|T|j0ù“1Œ½j\ ~ð>-ùÕ8gO‹D‚8@°ÆNeg/¥‰?ÌÜ0"?Yþ´ { -Øq>wÝq1áb&rÜ‘ yçÔ½7ÎÔ²ŠýȾ^ƒû}d¼²a&VкD+8%-j>À6@Y` ]‘×êì5á‹7E† F@…×òèÅÓ•rˆFÒí?íÁÈ&}!‡sqàÞ!u“×2‹Ë™ -T’À»Þ”dRÄ|<þ¡ë׿”ã~$Ï1r®FÃ/;ŠÎ‰÷âTŽ1Ìe~p cZz#ÌšBùP³,”@¦àÝÚ=ú^Œq@Cx\&“dØ.‘<çñA‚Ž·å<æ8Úìäë£Ò1íðfÛ  W ¾1B*$*ƒlfùwÜójÒ6|ŸObeÖ5…$¶õ2áÓ: {È£X9ÂŽõ`»žv®ÆT§ÃÊßW¹ö%,{l!|L±0™RÉÞˆ;ì—<–2ꃘxb,[÷aêžYÀƒPºÐ—VâÔÉÌÕ—’ÏsN뜣²{=\ÉÑ~Vorž±ÄTà8’\ð)Jvé‡êq5ÄkË; nmõ¤\‚¹{[”œ0r ýÚá -—/ìf(ìÒ½»;ûåL8¡§°N‹sDEä­wg?ýzÐAØ@¹w ®eyk6ÞíÙO–§E tþ[ËC© e9•‹Ñ¼z˲ Èr/΢ ‹D¿W«"õÙcƒ‘è߇-IE—oå]–òè$Ä›¾üROd ëâVI’Y¿T%§4’²L±F$kÿšŠ°PE\(ÿoøÈ…*ü’¹Ù/«åÅ[ÊÇA¿‡\qÄJbÆ‘¨ÊvÁ2þµnËÃ$ü× üUtäiôõåiö5}è4È;ÏÒSŒ×ÜíȼXÓ°*ÉÀNrO©ÓáÝûç=¥DÞÅŒíJŠí˨àÛq/ôPd]ag* ¥Ê"í¿£ü/Õ8¼Ë7_Ví‹u³TmE˜ýP‹â .¤/tMFt5ÕQ·Ø.(]'ˆ”³Ð¸¥øˆ©w³<;þ-¼X‚¥BpA‰úƒb/VQhÚf©@Ý;$`zÎÂp÷ŠóÀn»Û´8†+v<ÂÓh0Ûß=?ìwÀý¨• «YܺŽ0€àÄvÖ^¤‘K·éÁx@bºˆµ³§;¥dåܤÂ÷j¦Ù(Hw÷[³’zÅ8˜º> endobj -1088 0 obj << -/D [1086 0 R /XYZ 72 720 null] ->> endobj -22 0 obj << -/D [1086 0 R /XYZ 72 720 null] ->> endobj -26 0 obj << -/D [1086 0 R /XYZ 72 346.349 null] ->> endobj -1085 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F28 879 0 R /F7 1089 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1092 0 obj << -/Length 2329 -/Filter /FlateDecode ->> -stream -xÚ­Z[sÛ6~÷¯ÐL–nW0î ú–ÄN§i’µíl²y %Øæ,%º$UÇýõ{.´hËŠéòE"A<ßwîéìjFg?Ðøÿǃ:c3Ãg†Y’S6[¬¾|¥³%Œÿ:£DØ|vëïZÍ„V„[ÇÕììà_ž§†h©÷=w2b•Š¿9?8zÇó™%Vs=;¿œC¬ÉAF¸³óåìKöîäõ¡ÕÙù§Ó“Ã9cR³ìíÇ£ßç"—'9¥ÙçÓãg8(2FL<ÃÁ¯ç¿œœoI+…ñ8Æ‹ü±”æÅŒi‹ÅXÆv¦mNrcaÇeãP!DvåüÌÖî[ZÔë¶®\<9ä&».šbѹæpΕáÙûúp®h®ÃQ"ûÏ!PíÚ§‰dHD.ˆf -"rM,—ˆ“¦©›ùeã"Ør}Èó €V®@Üâi¼V_ž–‡,CþÀ€2 Lr-!&‘±ŸÑˆ†„FDÎÿ!\H3˜IÂP´Œb½ h/6ÿ¥L¸Æ-êM”ë›M²•¢ªö¡-楲DòIÔ®¡,ªýmôÜÔÕü4àhQPíÍ yžÕM‡Ðº×å\æ‚=Rñ{Ј^Bô0| -ôŠª¢Ž_oº:€^–íÿ‚zWÕW@åɫѽƒW#3^Ikžáç£eBŠ(6‰Â…%ŒÆ ñ;ªªhÖàß,» -W®m‹«äÜë0X<âFôÜp©öQsæ*ªÅ8ÉÓ쌆7d‡ ¢ô$Á a2ùÓ³ÓF¿—ßÜò É9c›…Ñ0†,À%Mõ,0E˜6rêºM³~ÄA ø‰ Œh®­•B€H>òÐ?À¿²–€COŸ -¨¢òÇø{ýÁ/×F½_ýßã…bÏ¡³Sè^aúË{ÝÏ]L Åzq‡U¤áâ!Ð2ÈÑRAEŒœBÁÊX"xTð™‹þ&ÔÁ ^‡õO\Õ>ï-AFHö’’f¼ÜCØ¢M>‰nµ!f¼¯ñ"Æòј©ý¾mînº*9A¡Ø{¿Y¹ÆŸ ª³“õUU¶×{ÐŽwˆR2”S UŠHH*!–—•[+ׇ@þÃr6Eõ2ºy¯þ­l転øãñ é€t5R©£òYlrÊ«âÂÓйÔûôÞ–ÁX®„|û96?Zî!lÈÃvŠ„®#ŠF#<Ù»‡mìØRSÆ_|¬äCÜy­žDÝÌ¥¢º?n.ªàÁhûØäÖM‰þnEΞÊ×÷%ËžR~¼ÀC¼T:‰³SC”5áÍbhãœïòàçTf£Å€”–C—1…R¥UDC& (Ñq‹î:à¼lêUpaŸÅ˜¯Ú‹vRÇ <Ä›S2…N¡­$2I,EŠ¥?¬«»€41p”®Õv›6JÅc…"Ö9´ r -̆#ØÓ˜›JÏ?}Ú -×þí½]ÀÈåÙ³X dȃ҄åv -”%ÆDÝÿ~í\ÀÞ4u(RÒ{·É™|q]:^ì!j)¡]˜DûÒè$·ÚÏÍzÑ•u¬K„Ùê¼Û˜°Ýeë3U\®,/Ã=kç–ÈÃuÝ­ãA 9œp3‰%Er-áSëbͺF@à+<¸€"Ý„–«Örï0F¼}ƒ"ìîî;DŒF2$‚ý|ãà‚Øh±SÙ/ÇAí—HŽ­H¿ny…qQªŒAõ£„ЙÌa„RŽOÃ-÷6͉Гè?Þåqÿ캇›ÌÚ®XÝ`Ê3ùž5øö`-ì«°)v#$¥zÒ]8!·³á/èg.‰Tù8Ež*ê´+±?c‚qö´£îƒ7Z¾!<áU˜BÂhBíM&tBѧãñ>t£Å¢Ó”(9‰ò´$LDå›ô[+R‰`–þT+q÷n ),³Ïëç û²MÛWŒ5ö ÀýÎç_…{Þ×±rL›¼½(íæ~×/v™ OwíZ—JPw´ÿL—êÍU„¶›§E‹”¾l ï‡WUi1.AØzS{×vnÕz0GÁQ{€M`ø+׌hÌ”ÐlꫦÀÞØ¨ìl³ZaéOö.|ò‹|~ÚÁg0+WPÜÏJÎ 1ü~^àæEÃÜwa·R…À󇞢ðŠ]o[;r—Ë<Û´þÀf­ ý^ƒŠÁ+®Å>®l¯‘,ÇÝ -•w´å{a^„ Ý`A½^ -+düï®Ë8²*ü=›ôÜóÃñ¥kM&wé¡(ä-J—Rý•hŽxí&Ptÿ¾`_Å¢ëÍq«¶ .ŠÀÐòJïСÕá÷ L©rhhTf×®qaܰäð§žÔD6`¸q7 ØR£¥2Žã ø0ùçã=ßÂùez?~>óø®‹MYuó2ÎqüËi8XÔ`aëåO>ÔÑŸ ½ôî5Q,67~&ûeùÓ×/ÅåúënsÙzä<ù£A|CY{Ó{•’ô@v̇õ"¦]¿Š_oÂI労_—6­¡2Á-ûˆ²êŸËãs2E%¸îRëTĦºˆËåUÑ¿òºÆwÞßmk»uÉùÒ«ã¾BÝö_I—‹¢»ÿ¤Ä[P»3f¸ìÒ\áoË$sëÒ+Ê~»:Åñ€ûÏYª'¹ Ñ%ç6BD‡,×¢lq%Ù‡…t$20÷ç–PfÁV-Éó¸ÏÆÔà&(þÊQÎ -endstream -endobj -1091 0 obj << -/Type /Page -/Contents 1092 0 R -/Resources 1090 0 R -/MediaBox [0 0 612 792] -/Parent 1084 0 R ->> endobj -1093 0 obj << -/D [1091 0 R /XYZ 72 720 null] ->> endobj -30 0 obj << -/D [1091 0 R /XYZ 72 267.47 null] ->> endobj -34 0 obj << -/D [1091 0 R /XYZ 72 239.727 null] ->> endobj -1090 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F16 823 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1097 0 obj << -/Length 2674 -/Filter /FlateDecode ->> -stream -xÚ­ZYsœH~ׯèðËÒV‰¢ŠË/òµ£‰ÏHŽØõñ€ÔM mËú÷›Y™EC µ»_Ôuù‘•LJÜÅzá.þ}æòïË›³‹·Ñ"qà‹›»Eè-Bé -W…‹›tñÑyù°<מtVU¹ô"ç+þÉÌe›WåsÔž“ßѤ¼Í¶ ]&»ÝòÜ ,©y¬Ä_×)ª%ˆïÍ>5‰VI“™”ó€òª#ùvy¡äMwÛ´yÛµ?¤ V¬DB·uR®yšùºô')º¬¡)wëÖn’–Dh>U,?ßü -K)bß',®È<¥â¡yy¹&Z¨Tä¼÷îÍ_$zuyý†„eUo“¢x »-bÐ5-ÝÝÂV€Ý ¸¡Ófu–²à[²ji!<·!a³©Ðô{|J»`AÕ­74§Û-¥³£=kU5-+h>!c‚?eì}^8C9iµG#±ӄ댜¡N`žp‘í¶Â·úNr{[g_ó¤¡á¤Îh¬kÐ4Ñ ‘u5Ý -·Ýð¢†&¤yó7IÒ:§ç6`º/¥óÉ•ºÈh°L¶½Üî&-š§ˆåyJçºÚNš} 8ÚŠ¿À©gonξœIXá.$”@‡Â Õbµ=ûøÙ]¤ ‡ý„УŽ™µ]¨Ð.)×g,WZÄ2>¶f’n´ÜœVot\C‡l ß È„Ë àËžë:¿eI‰~úÈ -8½¨ß|UY??Šƒç ?ðçâ0ƒé{øXèù‘s³1'K;¯Þ]üÆm¼É\Yo¢)EÖÂÉã÷~I?í¦¶gK;ï–‘¦à0ãlSÆHHƒÒ €ZȘCxGvP ÐN‡ÑÕ¢'²¦I& v[üËQ‰ÐÐŽû å(yй¶ŒðãHþI|Âõ„§­Oä`gàG±}¹^½ûËúD­Úª~ s1’<§‘»ºÚ2„%ûI[‘ Ë -Ì…$¦È•Ô°{/¢¬ ÀµÊu»y¯ù‹ž.?v…q$éî@ù@Å¡sÉV¼\0{Üæë²LÕ±w¼Í‹ŒfüžP`6r¦–cCˆ2ú§|B±.XFB)IV~r}·äúI* ™/]%u:õNŸÑ´}’Â)I³_ü¯gXÈ@,Ó½ðŸÏúLÂ+ ·zûJ(%ަù¦‘ <ƧðŽ *dïHŒwh_õÞqI|ƒCõŽ¡É1|kë:ƒ1—mb‹}Íw`™k×ߑҧ€Å×êH‚åŒ -Âaâ)ªô zrù5. ¥ù:o*,S—Ð)…¡¾Äm$ßè>ÍšUïL« m¹V¡¡›pÝ!Ý«r¬˜ ß!§ùÒñó=çj3œ÷·™Ü²zXd|d¡›hõ?cq6ÅÔMó•á ð®2*¡õ^ìZÃTs8Tä%O²d‚Vžó?ì -‘µÂ¬lBŒUf«z/ŒHè;eÕÚÇ®Š.nH—†ÝÒ°¤[ö»}ñevĘL§mé—É´zÊx¶ -i7åäÓ!&}"ó¤Pqp“V4ª›%ھنƻ¦#v oF4,Jxì.銖n¾.}¹8x0Ϫø¹Ö±KÃKæ¸åúÕ+ž`É"ù™Ð 3´–Câ„‹xš=ØSÖo=îÖ<:üð³GIy¾©Ú¸k^Àœ \N*cF(Sá”I=Ìé"6MÇi¿á^GÖ£+‹¬iú­›l¨Ê§Ug¶y‡YñÕ(Çan¬ÆÁ6K' ¿÷ Q®5È\Ô™¹ÔO0Ä šœíbqöÍ@ —ÝnÀQÂ=uLpqHR‚ˆbåÆc‚ÎÊìÒõgf–ã<ü0~ñª{Kü˜”4÷®3­ÙÃŽ,оEimuŸPÊ4'vÏ%©at×-È»üƒÑ}Åô{Ú4Ѩ"Âþq¢1p… § 6*Ä'!üzãñªÚîÐõ)—ðÛ~—nTj9_¡GöèãËÂH¡ô)¸%@õ§˜[2¯Ò‡‚¿œ_/yxUï ±^ŸD«d—· y'xIÃÕDέãð“Á04`C§Í|2xòÙF1Ó1Ìý©NGGPª…ò=À.°'ªÿ¶±/Jûo˜]µv.! >ïK~Ëú VrIz[pì»|OO¢4×Ì1H*MO‚’†:Ñ2 -}büQª³/]^s¨ž6f¶:ck<_èlŽ­?±j •ð½StGJ†BÚöúcúâ3œÔ@KKÑ@°~A´]Ó&}opgî -ªU¤³NЉ¯Š¿°ßÝUEŸÈà³ç–jÃå±ªŠª<ògƒ0ÆÐ•ÂNsr]_H[Q½ÜŸ¶+ËlMG.iG}æ^efY S?ŠkûN¿ñuõÙVŽ@ò¢z&ý3®þ3[ à¨ÁIš^/’³MïÇä®ül>‡ŽIÚïøÄÜ Y.K•¶“-ûÜÃ<Üm7™±çá©·8„1†/BWŸÂÕ½ ¶ìíÇä·Böû1u;hÈDƒžbè1]ó‚#`¾yÐñ/?(š&Š@ØFÒ9H"¢ô]çe—í¹)f þ%+vhÉ^¨§!#¨@ñ‡jÓOIî $¨Aðáúõ×$ÛÕè¦kŒ»x•l‰Ò5ÓÆß `òm‡,è“ð’åTÇ,šÚ²†Ä÷›¼ÿŽcšØì@„{nlÈëåA¯ƒÏõ;’¹ iþoa‡yÃr8†Ê@›1Õ§†$b†Äņ€Ì_ç >Á -#>•.þ; y”9©,Ë÷ÊUŸSZtkϳ Î#wuÖl7psŸbÇG_/P½"i6? —‹ ú`c”½®håQ˜ÕÞvW@#‡.îü'ÒÅ[å¸J$¢˜sö‡ÿ¾†0½ïÅÅ´[á\.ěƮõ‚X²Jpû>§A2Eì{ ˾µY™ô``ø…n™ArBΕƒPÐîÿp;^1òáØ¥O‰¡qA¸3‘¦^ý~>Õ^ß,#ˆàÿ1;ˆ" ŸÐ¶UÝ7¢ -l `xÏš&Y[€Î)2îS&iÑ÷M1 iÔFŒÞíÂóbˆ§ñâ܇RTr@•ÁhĺÿVÒ'á -endstream -endobj -1096 0 obj << -/Type /Page -/Contents 1097 0 R -/Resources 1095 0 R -/MediaBox [0 0 612 792] -/Parent 1084 0 R ->> endobj -1098 0 obj << -/D [1096 0 R /XYZ 72 720 null] ->> endobj -38 0 obj << -/D [1096 0 R /XYZ 72 251.364 null] ->> endobj -1095 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1102 0 obj << -/Length 741 -/Filter /FlateDecode ->> -stream -xÚ­UMoÛ0 ½çWø(‹#Yvb_».† -Öж;h¶ s¬@VÚåßå$‚v‰(Šä£C£MD£û çíj2[¦ET&åëíVtu<å'ßT'”‘‡Uºë㟫¯³åy,MÓ<ásŽ¡¾‹.N rˆ§iY’—§»‡'wFoŒØöxÛŠ8] V¿àX—ˆR¢¼ÿ»ûѿݯ¬Ñjmô%ÛH*À -° äd¤FÿV¹Kö¡lƒ¦:à÷—FU.ts -ãK?†’]•Œ%ežc•VC|Vx䀰GÌ„?ûVmWªm¨©Õe\éë´¨üp²rè]AI<ÍxInƒO¥OMq~Šù);Uæ,… 6j°FýÚJƒ¢† -Íw˜5\vª•VºüZxd´¹Ö -ùGlw­t`8Çîqž‘G¼#8”Uwa3¤‡¨G²çlÉéËŠ¤(SLúò|Oó4'7É -×™yæS‰}/{äÅqÈ>ÓÔÊÈÊj(¹·ªUöŒ£~âž^½Eh[TÁ<³Vj½Ñœ(8¾‰åû)‡›²ŠÞÛÝÞŽ“œqׇçsåôÑOÐ`ŒÓDÉ®‚±\™óù‚ôªÛ´2È­èq3€ f•Ë: %9 Ñ¡ UA ›€ht’ -Ï»VTrp³•¢î2¿F>>/°!ðì{§@¿éÔú€þ¶vBh#{;Nâž®tàD|àc‹9OÈ®‡ùö»ëKgãæôn;²Œ¬`¡äZ\‚l 8ÿŸýƒØ mUÀ«êáÛªüw±oÞVŠ[îÖP_ Ýù®ô>D {6޽ vO°(®!®*`hd6 -?î'Ñ«÷ÈÆFu{='kOV‡E›|ø>@ÍÈì‘[š– ee.“´þ±#«/«É_³ôÊu -endstream -endobj -1101 0 obj << -/Type /Page -/Contents 1102 0 R -/Resources 1100 0 R -/MediaBox [0 0 612 792] -/Parent 1084 0 R -/Annots [ 1099 0 R ] ->> endobj -1099 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [335.485 517.8 355.189 529.755] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.11) >> ->> endobj -1103 0 obj << -/D [1101 0 R /XYZ 72 720 null] ->> endobj -42 0 obj << -/D [1101 0 R /XYZ 72 720 null] ->> endobj -1100 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1106 0 obj << -/Length 2708 -/Filter /FlateDecode ->> -stream -xÚ•YÝoÛÈÏ_!ô¥tÓü¦xb'¾øÐKŒÄÀ¥iú°WŠH*ŠÑ¾3ó›¥(‡)z/âììììì|ï*XlÁâ×~¯^\݆Ù"Lü8É¢ÅÃz‘G‹< ü Îåâ_^tq†QêÝ^‰gÍpèlñï‡ß®n—‹Â/²(ãUÁâ2Zúy‘`Ñç¯ß¼¸LÂÀ«z| >«v·¯í`1êì¾6+»³ÍE´ô ×màúĤÁ÷æþêw@‘ø¼ ^ÞÛ×YŽ£ÏŽàEãб÷ñf€MoK>Ÿ$ ý"Íp’þ©ìŽÏžÑï‘¥µuÍ£åˆýüòúß1§Ëý‹Ëå2ÕB[·ª·ß„[gj {T¾M©&8ìl×t‘m¶¦YÙ„kgP·ÃÙARdßµÌæ[Uò²¨ÈE©üm‡­íBãQ‘Y&÷>AGî²¼%ï'6­ªÇÚb|¬†í9ÛÜ#‚‹±µ=Y#ïñ0œ‹³k{ÇŒÒ$çµ>4«¡j¢Š“gÌÝóÈ›=1œ1ÞÜ_„žH’³$ 5ugM©´ö{ÅR0žåb”Ýî•â Rد6Ìî âÃLq_þv‚µ] ÕÍ®lþõW²iSÚN·ªæù%Hƒã¶‚Þˆ0N¼’äoI3ĶfT,cK C +¥ªšU} åøã>K¿ˆ -ìó°2ÒvoE«l*Pç 2ﱫì§„œÎø­"É,ÇÛt­±8¹.ÖŽœ<˜ÀNàþ|©úœlÞ”˜(úT ­ì·éu£STÈÊ/AÓ±æü(šlÙ[ã($òèÀþ%*8¡½˜‰ ,Òp²ˆ$#ñKÀã³ß×ÕÊ8% yè¦3»cu쪡j6Ài"e¡çcø±Ý)ï [Ûrc§ÂD?‹dÌ8#3íá0Ñ ׳ºŸ.B”©€? ¯tO©§b §Œ²õÖ‘©»´i’{wk`U 6lYÆšµÙUue:Œ‘$˜¤Ç)YÒµÛA«– RC’<öÈ¥¥„%’åM£ü5®;òo¸<ÏÃádŸ/aœ”š¨WïÿjÛñêVy®sïÏ#.I¸Gá²™ç.µngM£ I:8ÈŠ¿èèšV¿¥Œz/­3(*ƒ(^hX9Ê@‹ ƒÏM‹&«këË9í€Jø9–”«vûa.ÐþCi1&fóu,4\!Þ ßLÇlAd94\%Bï®Ö”eÅÙ„ój–º„©kE+ô­[rˆœICœ¥JÝG)(LíÐ)…@x„]·N¼Õ|M‡©¸ÊŒAÇeàeå0©­´E”|X‚-™Dš¢llÐz,š¦^9YDÍ QRqh!™+ -”µ CŽ I/ ™qG·±è ’dKÛý^Óc49‚¨q³3GŸDßKM-´WÓ¨Ù%ÒŠË?ÎCŸ4¹T’ÐiÂࣶÄ,kÍK £Ñ—Åü_­ %Dqö0a)y‘T݃Ð\­®x–fu*c´§]*ân…6DR)»†”}Zèn/nÜ›µeÿ¥Îø­¶!¬—K¨Z8¾*ŒDåO’'³É; R%#:1C]ÖxY -\aèÜêÌá,U‚HY¥Ïò*ÍP‡Yëœ&µî,·¸ u„lÀŠƒmT–ö%¡4ƒ=W6Lº²6W¿F“I8%jî(Ǿü½¾“A¥}¬u3üJ¢\–VcƒZi(Gb,ƒ9yUÓâ;´¬É¶ 1›«» ÃwßMŒéô.‚éWîq Œ‡‹e"Eé‰IÑrî£4K2‘+†ÌKÒ³“Íx‹KçœWÍ4[M4?ô¸„Ã\oI¬5©j2ä›Ê‘4K†ƒƒWÚ…“N&Š#?Ï2’Gäøû½NîçIáæùö…dv%Ÿ†éyN;yA4wör W%«SÔ]Èc÷È®M½Èht^0öŒ¼€Z[6Óæ žf?ó]Wp‰kGìÚÕèÐ44º7up‚*þöîoÞ½úýÿðÏ{·ÏÜÿ£®ð:H·wÉOû11Ï€ÙèÒVúBHn·¯5Ëq!ÒÇA½ú™{u<Å£‡Êˆo€ô•51vމä -!æ·§g¬E.ŸµŸÎá¼ý'Ϲª+nš~Ђf¯½•éôéÖ5HëgïÇqt::»¶ÝÙk G4r³—­V.vy†ç°<÷þàÆNËgžãÄ=Hø4× Ï] ȈôD4‡<›ó? «É³¹\’ø5Ù–åx¹S0!N×FÂö‡½öÝÐ;†CWI~Kó“2rö±-±àt4ÿ·ª"§˜héÞZ}άъ-¹z -FÎË€;/ÃîëâG®™"ðРz0|êz–Ï»ÆH׳Ô÷ÏglÜÕ•aºœô=^&xãiïã÷JdŸæ¾E~T´#? ôU.\ž½yxñ_V©o -endstream -endobj -1105 0 obj << -/Type /Page -/Contents 1106 0 R -/Resources 1104 0 R -/MediaBox [0 0 612 792] -/Parent 1084 0 R ->> endobj -1107 0 obj << -/D [1105 0 R /XYZ 72 720 null] ->> endobj -46 0 obj << -/D [1105 0 R /XYZ 72 720 null] ->> endobj -50 0 obj << -/D [1105 0 R /XYZ 72 550.794 null] ->> endobj -54 0 obj << -/D [1105 0 R /XYZ 72 333.159 null] ->> endobj -1104 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F11 833 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1113 0 obj << -/Length 2979 -/Filter /FlateDecode ->> -stream -xÚËrÛ8òž¯PåªÖVħȣÄYïæá²=5µ™ì! eŠTä8Î×o¿R1“ÍEl4€F£Ño-g»ÙröþÅR¾—÷/^_å³bQdQ6»ßÎVÑl.Ëx5»/gªªæçqM7ƒ½žŸ‡ELhkÛò¬bÔã<ÊeŒ\ÏÏaØÀï -·3Âm6=ï ³å‰/wo?ß JˆšZÆ J½U}ÕŽgü©–z1?O’ep|âÄ›½ªwº|¾A·­ÚiÆÔ|šÿ÷þ_ “ó0\iÊ·çàº8t­ÖƒQŠ“ 4í«:ùÖ(ˆ'^Ò™ƒPx4Ýž¡Ž8„É/wo>ºº~Ïè¾3•éxo ÏS¾(¢‚yr‚J@܆^ Uµƒª <ʰ–ïñX™êL#ˆNÖwêa.w„mý›–1Nj‚0ËÊÔ;mms`hÄÑÚÝà °2¬îëÍpx’âKe+x)xì Á—A«Ib¹%ùpf1pX Špã4úVX(D•Ý!h@«ëMÕ—~ÙŸ(yk:Íà +šŽÓ ÝO O¾µ†…Ex|÷’Ù»ÄåJwzÓ‡×ôœÄ9?|­îz[3¼iH‘:ÛTãE>'°5zQÀ!Æ6;«-J7-‚‹áÑåÊ H¡¬XÉÁxØ–MµÞ ½Ø§SFVóåkÜßMݯTbÍ®š¶Tç+7¾_’¯à¾‡#°»¬€Ðl7éo¦íè©pt”ë‚ôÓ() N&)ŒEcÕÊ÷p¬ôA³ŒÑ†©dRù3Žì„Ƕ_ƒ>2ÜlOný¨¼I”0ð%>¢4xsóúã?àVá*¸îd®•ïÏjlÇ.D滽êx·xR0ôÉrPê¥Á[Dñy·£?ÅY -Ç¢¥š6ª‰'õ&ï - eÈs1L@ >:'ý-S?˜ºm¬æðžøœ Žl¹ -.xjA¥;YRêvcÍQÔ’….G!;òòºr8‰P™šü3 Œ,An'îæœ -èë ó í«–=õG~‘^UgâäÙW¦ð(¦Â ÀèV•U®~îÂ9>eEP7ö *†ËF.Ð'ï–Çâv³Á¢ÐC¤¬dÍà À”ÐyÕ²UY9öÐ8HëtÝŠcèZí ¦Õ|Éœv¶C—xø„ ­>Vjã­ -%„Ž1Iæ0±ÅoW0‰Ç!Žl…Q$tÖ<ĺ“ƒî¼ÕðÐU{ºÞ¹Õ£ý5£Ç2=ajgœG#<¨ËÄ Á«²ƒnÃ/BX²œÙÝŒÛ÷/f‘.\,BZàÒ-ØM -ñú*ÌfL3¬ Nˆ“EžÅ|B´ˆáýB0Í »™Çy/øàc¬9£ ë¬Y÷ îzd -Ðà9ø€qRä£t;ò¬~® )mšÓ9p¥ý  0½6_—é²Õnéo^–¾[D‹ìG±Éî)ÀÀ:q ‘¿%«¨žxò™“Æ%dÈ©ØÀ‚q÷ìžcÜ!jGqRaAíФWI°îAÃHÁ³ ¯+ãS#£."”†—"«¶ÌL\ E¬€z.V@®Íp¹OØÂ1m§:¡óÈ1zLúë2LqºàœG68©KF -)Ög þeâÖC°ˆóH æ…=Xз%Àó;’_—5¼ÏÅP|[žùÆÉZÑÞ‡þø’—ùXë“X r°BwÌv(éÒ"±Lf’tµ(GGz4¨>QÎ) ⸅e°œsá-/Ú62Õª­’rP•¨XnÒ겯KUo`2 0ñŠ—`Ž,^20d)C´/.K®±Ž5`W2 b´®žx¡»*/¦wAô^^n ø“7aéî¹RÈpQÕ<ä²+)³ekŸË<¼M ðŽ÷Â9O íÕP=HþMG¹ èCR²Ñ~ã*Eb•@Y…‹Ä-ïbÃ]ð§¿Ó»†’SÀJæõTZöåêúû[ Þ—œqX¿¹¹¾Á—“¡Â›•R¸í%¤ò‚q…F‹Þ|¾ùÏâÍç<-Ç—nä‰ráà(¤Äa'' X/`6ó‹ÐÉÛóЂžõ—á%rá%‘ðòAÙz+ïµV¬xËiÆóÍë—Å;Æ¢ù‘3H-£*wÀ¤Llmˆp¦œE#‡Úòô°å¡ËL¢àË­’äŽÖ4B˜jäjØ–³BXÒ`ùœ§` r3d”ÎÀG}¨ú‘±1÷ ªIGž-“ü,]eøˆp/.…É—ÇÌfÈàÎì”›–’$qòæH.( ïR*·pÜ“îâÐs7BÅÑÙ*ËÊL1|Ð7­g'náE(ÓD’ -rüÀË/Ü­°Ÿ¶N”è¾gs@EYt&‰«wP¯V<°zÓØR–![éz×í/‰JE˯æ6%®¤çßô3ý¾ÕpôÿÕï‹áúL’zdD:êljÒΆ’Áô¸‡:ldÏCñ7Kx“Ò(ÿì¯:×.³Ç'±ú0êÕ—ŽÑ‡âCQ†”> Üì•}Æ0÷°–ÁíÅÇaJžÿr2WòýæŠd¯ist±*Y¦Dë¥K¬x¨¹)Uó%ó˜ 7A‡)ÇKž‘]ÂnŽÐã ƒ¤Ê J‡-9ô¹‘Ò-6p½ dzç´Åb4]q¾7™/Z­Jâ,vû‘*¢Jc©ßc´¬¡b…ý'^!7ƒ¹ZæxØ>µ>dÃAÍp† ¨e,ï’4—¬véÞ“0FMÇiWä£`šÃÁӛ¶í9• ³QbÍ_–Í+¹çË-TBP­˜Rç¤ÃHF5جvŠºmC´_¹@Ø ‚œö¦®©(xwËÐøQé¹d“P9ÕF¤!:÷ø§4FQNSÏËžM% -’[dè4$Ýtœksœøb qW˜Ó®ÝP¹Ýü§¾ŠÓX-÷…y—hä×”•ÒAæzƒQ—_B Vžœëš©WÉ'Nt¦‘þ¢Æ¹Ž˜[óãfµs±øº81Êrï“;wDZ÷L g -ˆ÷­cDk\UiêdäëFªºQ|^ŽSÌ3®‹|â‚&lÑõ^y&$-wÛ 0%{ª™í©.§\‚X;ÑðéY0¼$QÊW.QÊå=<ý+ä/¤»JˆËk2D€¤È]9gCǸår<²˜‘ò–¿C:ˆe4çrÛ˜ÕêÅn:8=ToÙâš[܇UZ„ÿÎ_Q²’PÿæG:Ò¿=ŒRhpRâøâm ¹2¯·üõüâ`”õQjA$I{ðwf ÈzåhüÇb‘´Gúw¹oZ¤(½¢È“€T>Ǿ­µý‘ûxÈÑ–¿ž”óÞ¤!Ôgxpê%|(þ qU{èÞL§3ÒçÚt½Ä·œÿ´ÎÈ`¹‡“ÿšyH½˜s±!ÅI]0GÚ{~$\¹¤P2ω‹æÚ_4=_"ò~<—gÅ=XP¾Û’{+Âðõ–÷’,OZQT,–aõ”6‘˜KXœ,zwÿâUïib -endstream -endobj -1112 0 obj << -/Type /Page -/Contents 1113 0 R -/Resources 1111 0 R -/MediaBox [0 0 612 792] -/Parent 1115 0 R -/Annots [ 1108 0 R 1109 0 R 1110 0 R ] ->> endobj -1108 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [116.666 542.72 133.879 553.569] -/Subtype /Link -/A << /S /GoTo /D (subsection.A.1) >> ->> endobj -1109 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [230.473 481.941 254.744 493.897] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.E.2.6) >> ->> endobj -1110 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [487.886 422.166 502.608 434.121] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.1) >> ->> endobj -1114 0 obj << -/D [1112 0 R /XYZ 72 720 null] ->> endobj -58 0 obj << -/D [1112 0 R /XYZ 72 529.776 null] ->> endobj -62 0 obj << -/D [1112 0 R /XYZ 72 409.221 null] ->> endobj -66 0 obj << -/D [1112 0 R /XYZ 72 325.639 null] ->> endobj -1111 0 obj << -/Font << /F8 826 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1119 0 obj << -/Length 2525 -/Filter /FlateDecode ->> -stream -xÚ•ÛrÛ¶òÝ_¡æÅTÆVDP¼¨ou{Ò6‰Çv§3iÎ,AÆ¡C‚qü÷go )›ÍäèAÄ.€ÅÞwùd;™O®Næò½¸;ysYL–³e¦²ÉÝf’«IÏgó$ŸÜ­'ÿD_nß}¾ž'ªˆüεÓ8Úî¦*<âòèǺa@óº¯óxñݬXÛæg›v½6UùÄøûé9ü›•Û›»Sw8Laø4-’è ÑËžtpG-tÍÞ±¥SÐü}i(?SÀÒM[­P5 %ù‘º3–O53Eµ\ ¨DÔ®‘MÄhü$, ‡®‘oœÈL(©]SvéÞó bÏǽìùˆ$ÏŸqê{ úîööœ#œÓ—Ó’Ќ蓿p#\aöÇSžXMåà@ºmHV‹îpè+5:¦Ê,L†Dø!UMm+’P¶R˜ppT«T‘J±q$Ìwv¦Ó*t4bo%j&ÀÚFo€ÛAeÅS:eŽ(U›,stêBœz9,‚Ktur=BK¬/±â¸FlÌ#q²ìjŒ ¾ŽpT†&^­LÓ’ƒ¤4Áè›Õ<£¯ótî¹6¾ºlþÅþÛÚš+²^°"¾ÜpüZÊZ#Ù0ñ,åY——’#œƒ9²yÂ…ƒȷωŒØh[6¼— Öò 5d¹™‘ÛŽ›÷~¾â!gPæzDº½î²r10fÒÐÏû‘$(æÄ‚uŒÜƒHè$’“œbƒÊƒšw1(“CSÙÉ¡’C‚¢aÑ»·ÜÜÞ1~(! "ü[Gæå£ÏÕ”Òß\ÆÙ„×)ìyaW²˜Y»Ô,¶c•FP% ÷»ŽA+ Q‚CÚJ¶qv…ÑuÙ¾¾fßß@º:­Ó\`®zÕcZË_ŒÆ‹+k»Èˆ#eQs#î@õØÔ&ä‹€ë|Ææ»7UÓEÐ@>¢2ìx16îV ó9 Æ–^>Jø¼ùí#/áR1"êg1Ń^Âqß‹Ü QÀÁÆa+…ãEˆ¸`/ L«z -õã–i@qÁш¸Bí»s FbæÏÒeôN{-+´Ðïb ¬06ñBçŸñz€ª i`Dègœ̹*Ô3FU“‰7Tx`Ú|×ûC‰M¤ZR'„+ŠxÁ"5ƒÍ¡6zÝì UW@ ¸ “•;XªˆÕSÅ5bˆH¾jC¡Ç ‡Z¶áÒµþÐú±6HNφ§ƒ -M„r99ã“3ªÖ"1¹2ðÂ븖v!K±¿¦r½”kJøTD9µPïúwp›êÔËÂZ´ÁãéHH#Wh_Œ)%15dC_ÓÝp‹|Å(PíJŽgëä/ÒÌlÌKîP†ú‰¯•Füœ{k¹0†&¾Ï‡8ký/|¿º5rõ»5]orÃAóI½ðàæêdòmKf -„N¢ _(ðF४n¶j|è)înKÝÆÅXÃö‡UD…*’Kù¼¸äjq];ßKôÃZv©ëmØE0%HøR‚Tsp¸rI—™˜ë2L¾½~ó‘1è‘u#ÓŽn{Ü⨸oq`L•÷,! ÈŽ@®;›K+sîa­ðI*ñŸ±,îÂAZŠŽ¸·2 tR`ôÊ}}Ã_¦1ÚxlåÎ ùÙ³ëþpÄôi8¥ïà®U[ï<x'$ ú@o$€“ mð¡#`YWÈ€´‡È¼oý³«lŸT*çƒþ¤[,£¢¶*¹ÕE›îdEçJ,çM°q:o(x`êªtM£ë'ÑÚÀs\E±´[CŠä yO1l©\½—ÞNÅüX§ð øÓFlþöú&}F¢ŠMmÜõù%+?~Z;¶ˆ” rºžbÍŸzÆWÜ‗g¤Û4íÞ¼ ίxصr®£³wwƒúëýƒ[ûÍb~ߎ‰Ý ùŸoÚRÞÈ ü|³¥Ùbëû3é¤triɃ!›ünA0þè¨ ]³«ý0³5¤ÏžÓBâCÊ éð†@É#PêÉACŠ—½ÁR|ù•Óe¥4ŽN™ˆÙ!ÀÞ ƒÏ>Qð—ÔàËÜàÑÏ"pa,é 6 ¨?Pøvý–w$»[d¦ðöŒgÒ»F’ÅÜCã´WйxCžŸa>Q&a:âÂG«ep^•Ï#BÍïÂøfTÓÃÉ“<ÃÂÔëqâáã'ˆKÀý_tãtÛ{è’Zòt”È[GÛ=¿$±±ÐRÏXKÌT¼86Èk^ð‰Ê -Ô?Ù_ÝR»^쿼“øé9QÀæÂòd±ÓühÍû»“ÿ*ØÇ -endstream -endobj -1118 0 obj << -/Type /Page -/Contents 1119 0 R -/Resources 1117 0 R -/MediaBox [0 0 612 792] -/Parent 1115 0 R -/Annots [ 1116 0 R ] ->> endobj -1116 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [218.257 429.693 232.98 440.541] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.3) >> ->> endobj -1120 0 obj << -/D [1118 0 R /XYZ 72 720 null] ->> endobj -70 0 obj << -/D [1118 0 R /XYZ 72 538.687 null] ->> endobj -74 0 obj << -/D [1118 0 R /XYZ 72 416.748 null] ->> endobj -78 0 obj << -/D [1118 0 R /XYZ 72 308.702 null] ->> endobj -1121 0 obj << -/D [1118 0 R /XYZ 72 225.556 null] ->> endobj -1122 0 obj << -/D [1118 0 R /XYZ 72 207.568 null] ->> endobj -1123 0 obj << -/D [1118 0 R /XYZ 72 185.705 null] ->> endobj -1124 0 obj << -/D [1118 0 R /XYZ 72 167.717 null] ->> endobj -1125 0 obj << -/D [1118 0 R /XYZ 72 147.792 null] ->> endobj -1117 0 obj << -/Font << /F8 826 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1134 0 obj << -/Length 2834 -/Filter /FlateDecode ->> -stream -xÚ¥YKsܸ¾ëW0§UYÁ7ZÛrœJlEšÔVÙÙEBTø˜%9–õïÓ/˜­ÝM.C »4€~| ¼G/ð>œòýy{vy{…_¤aêm¼,ô2øA”yÛÚûºÙîô¨Ï/â$ß”U¥ÇÛŦ*÷å½i̹ÚLF ±6ÿT¤ú–[Ó®·sô2WÓpc?èo¦?ŒÜûùÝç;n zß”•nuw ÀW›7ÀÊ‹éªæP›î‘%¿Ü ŸÛ×f§7ç¿nÿ»»PÊ/’„÷ñåŽ¦Ž -µ%ãFc;œ÷„í¶Ä¥žYèþü:"5ꉩSÏ„[]ÖLùÜ5ÏLë¦ ïò—ó<Ú fÒL3,‡Û¶:|;_Vh{Z¯Ö#ì$UÅæNW}W㎃ÔÑR9’<2™xuÛeGz›„?Î w…Ý#om¾™úº®É=ð>‹.+œkÇ=>TÔE%¸ÍyOtIÈžvúh®Nã€id"ZÍ]Ž“–é—=rì #ZAßjwIy2`e‡ií ô÷=-Ú¬NÈ=À©-s@‡n ¹Ü­Í «©ž™JJYŸtWëš{¬&š_”€ùutjp÷p‘²fÔO;žãæpߘJFÒÕ ªd‘ÊAËâƒ.§yMávýЖÍÚ–—Iâ`ó´Ó·žq¥þÀžMÿøHSCÛ°»õÜã[ƒÆ»Á°µ^þk¤ Ú¨4’…Ìl<ú™[ƒMÆÅàL2¹{¼¨N'*Ìî í¶ìÌþД“黣}¦¼ÏÃ1ˆPE›‡CW‘(õ蘢ØÙ5ŸÎà :MÍ]k ‰?/ûEXð7.GRFÁqOÒšvåÄ›ÁûÍä~1ß/´eC¡{¿Hdð`óØñÁ+ˆƒ¦-C.K oÃÞ^•véyÖ¦/eh¹ßâ¥lœæê‡²—+&·cð&ƒ`Óã™ðý ¶èxsEæ0év?‰óâjs ƒ Ž¦‹¼¤Ðy@†“WóH¼â5wër*y¬cü -\š½Tá¥Á ÿa!tu¦ pÑå dôýz0€K~šÚY ·§ÜpG›kt^R8¬Ff|h¦í8KX)Íœñ.dÅÄ: õÌÆÆp3n8>FÒ2‡ëif­V4‘#JÝøÚøJè‚Ql@ÀËY¿uà'Ê5ÊD-w–‹ ý¢Îa Õ ×s®KĹÈZæ8¾‚ĺt¢f[Ã9pÝ[+2Hy¢ä>ëðg -vxãÇÛgÞW -ýÜIÄbb’ Ì”ƒ¶Š¯Ÿ…Éé/¯CX³ ÂuäSâ€{åàœŸhøÉè0ñ£4âávHì€ lã âw¾Nì´ºì,þv„ó`‰Ú%LA–èþÙ:4=! q ? 礅sl6$"œ‹1@!õ^€¶çˆ3îYÇA)°AI’€dpágHù­ävx úãÀ:L6âêÓì 8À}:Æ«?t5Z8Àvg„=#&ÉV!#±#‚šd,‰ºoo.ÿÁ”ÐEãÓ0*ÈHêa!bÖú¡„(!)È‚h·^h[µÈ²©¢mb¯˜eZ,vŠ]ÞœG¡8ób™ÐÆù’ÀB_ làÁ@R¿k¶Wä‚Í—·7·ÑÁ®‰îŸŒ£.‡ -MlÇý=­â!sJÉŽžœ2Myo:¥ùÊ‘aC R§)L3©¶ö‹ŠÙõì`¬I^¡d†%Â`ì#ËP™²r±˜Èq}Ñ úÜf»Â–-w¤+õŠÃ©ý$Ôªo[V :rj¼{èã©!d¬ÄAìänp˜q©P¡¸ˆÁ5껩˜"Ç­Ž÷@!Rh#r¬¢ÕˆÌœ²é©ÈR6tMŒ i6…ü*–Ü…9(ç\!Ä5d0?"k.'5è=订0CL 3ÀÓßËJÆte«}^ç=ܯ±!XGÙ±EZÙµd[=täåýl!ÈF‹-®iÐɹ¯¿›QôÈ X`âTR¡[!.ªmf¶ äÆI™Kð—’ÏIÉ wåT¦•ÕëhǦ¿§rce×µÑçpÂfòí¬Î˜ '*ÓhQ }¹{ûùÓõÇ>w·Ô á¨=3ºyà6«E5¤’‘—×4ö 2GƒÉ.ù周þlÿÊ$Fû<Áª}'ÁH)`ŽZ`,¯B ñ_œ œK¡ÃDZÀ’(þ°Ö} I°.™ã|]œƒL‘’ÅÑQ„­[æTb7Ðì¬)[ÆÇKs‰Ó’Âqæ,ãú:Ëæ A̹Q`Ìy -8Œ)‘xÁ"gYñ`žh€VLÏ.bŽ'Î7ïP S²Q“daÓ=gŸÈØBØi„ш:qQ¿î¥¤Öê—ÕT̪9P ØB…Š›°“ÀC÷#æu[NÓ` š ÃÄÇAâçJž€Rõl†^æ™ÏÚ¤?M L€ÒZ4@úân¨=þ°P¿GƒY}Üq ËxsmÅÎ)ÇX´üv0 áãØâ¨Ø}! ˜‚w -ƒ¸`oýÜ!ûy)ÆIN$GâÝŒäNf_üuÛËawµùþŠ+èû®[W® û8þºŸ¯Ýn¾Böë?‚ùÃõ/è*«u,:,‚9L#Ë[Øý1Ø -£ÌϲV=¹Ç0 H–<€¬vÜÅ”ŠBUÓCH~frÕpßòæÕÕT£º“5K ¬B 9qóc*ÓlˆdDZ5#j0Ü1ÍÌÃ]ì -<~û؈sßpø€4:ò0Î$[U34§Ê)‰–zøz(G¨Ié1XÞs4KíÌãn=‚ö€ÃtWÛKùèômˆŸ@×ïå\Ázñ á³ï…¼ã;?º@Ï¥ŒÀO…€EòyH˜9ðÛjÂ9`×ì÷ýöì7ñå©$ñÃ"ôÀ|•†^Õž}ý5ðj`Â9øQ‘{O$ÚzQ üX¥Ðn¼»³žL¥¢§ÒÀ/ŠäµI/GKÎeŽ`í•x*óC•Ädîiâ牳O&Æ/ç -àîÕí§Ÿ>¼ô D4æ"„kT9ùˆy,Yò4éÄàËw—È» -æ7hî>ác¼ÈÖÌèd?‰œ$#gÖnfà·ŒŠñ#ñ{s|ßæ­cÛȳE¦NÇ\ûb=®œ€D¾ŠïϽHb³äë<à=ñ¿±ó”¼¢à¡³¸Xjà¾[Þûùߊüå«/>Ëså„l)œçýÜÁ))”ÏR„ƒL)Û¼±¢ØIø ² wÊ(¨Õãs$,Ñ%w Ü}¨NÝw?ML'ÀTÎo$@9B¬(MÇË_=+Xƒ\ä%þà3:Ÿox–ëÏøw{kóȱëÇIê'Añ?xíËðsdEúg¹zxò8yì&ÒµgŠÐâùóƒExü`¾–CUèG‘²9T,- -ž{ ëTéÅ©JG†Àì£÷yp+0gÝNgŽÐM8³Š&'a‡x -2¥Ä§¥JÜ¿°ðS|½âæR0coYЙaÖép<¹…™/ ‡» ¥¨ITa æ˜ã¤L³dÄ9˜âŸƒ®D›ågÅ+ø€ÈÄKîºè3$ÃàßÛIÂtàZ2µÅ¡˜hmÉÅÇåÐâ:aXø*Ë%~H¢ Õ‘8ПA -endstream -endobj -1133 0 obj << -/Type /Page -/Contents 1134 0 R -/Resources 1132 0 R -/MediaBox [0 0 612 792] -/Parent 1115 0 R -/Annots [ 1126 0 R 1127 0 R 1128 0 R 1129 0 R 1130 0 R ] ->> endobj -1126 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [463.985 591.98 486.456 603.935] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.4) >> ->> endobj -1127 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [125.854 379.873 140.576 391.828] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.9) >> ->> endobj -1128 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [202.234 379.873 209.208 391.828] -/Subtype /Link -/A << /S /GoTo /D (section.4) >> ->> endobj -1129 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [477.893 337.033 486.665 348.989] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1130 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [243.528 162.988 258.25 174.943] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.3) >> ->> endobj -1135 0 obj << -/D [1133 0 R /XYZ 72 720 null] ->> endobj -82 0 obj << -/D [1133 0 R /XYZ 72 569.571 null] ->> endobj -86 0 obj << -/D [1133 0 R /XYZ 72 487.428 null] ->> endobj -90 0 obj << -/D [1133 0 R /XYZ 72 312.134 null] ->> endobj -94 0 obj << -/D [1133 0 R /XYZ 72 146.656 null] ->> endobj -1132 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F15 1136 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1141 0 obj << -/Length 3216 -/Filter /FlateDecode ->> -stream -xÚZYsܸ~ׯ˜·pR«1 ‚×£¼¶'YÛ±”rÕ:û@ 1#”yhyXÒ¿O_ 1#ÆIöi€F£qu}pÂÍqnÞ]„òûúöâÕu¾)vEªÒÍía“©M…»0Î6·ÕækðåÞÖf{©“4ïíÀ­¦Üª$âL‚Jvq³7Mg ?)N¸ÿHOO®Ám[Âóà³-{ÝÛêˆï‡¿Ø‘ßÏÔ5—­Ìyczói¿ìÿ6['Œà{ ùS=ýùßñ.‰7`uÏÃhpkÍOœDÑ"tQ¾}yè»c_6pU„øÚ¤³ØF¥WEúrØÅÇJmäõÐwheÏØ™<2‘{Sr ›¥£Êaƒî³l¤W‚]é8 n ¦hv]“n=J6›MùN)ËFÓλ¨¸åôpÕl’ÐìŽ;4(ƇÍP¯£¦Æa×2²`ÏÇHçÃüDçëg="ƒª<èj×÷†²dÂfÆý•.J -²éqÂȘ…$‡)Ðï»áT"Óù1hs0±g~ -O±zø2 õ©z$É«$`¾W<†û„ÑVS-`fBOø-_=Z‚IhÝÙ‘‡Š øBŒƒŒƒfí¼ÚŒ#ÚŠïŽökd:Á5Îo £ãpF¦^=°[0meŸ~;ÀúörÜm¥|[F½œ—YºÀî>DZ·wÓh†Ý|çù®PK¹±-j”õ‚3a²8:hïɆ(Ñ[¸7 ÏO¶ebe ïûÅ7à «³ -°Ðƒ¸‹ NÞ–„ /@ê£Ä@ô\3 ÈÞoGÚßQ0¶¿P5QÌ4¥UȨfå:kQæ®(µm,+’ÑœîË–;žNS¤ññuü…Áƒ\¨˜ª[p6”s_,¢¬¾o“DÀl,Fèg¾(þÒ™(KVÑvê%,P#.µŠ bè‡ñ'D—\ÞXö¹»P ØN°må·ä­à.m]’1™ÚŠ`š¿¾yóñFøe¹,r< 5~½ÆÓÀ'wm%XA•˜¼…eüM±X ¿(Ò‰üp¦¦·šsŒØ.ùg6$‰É`… ~Y#±Õ—¢AÐY¨EB|•Ì…d!Y7¦ÁðÜ?>’ÈmãЬy¸þ·Eó1ü ûû¦lÅ®`öÊÑKðôÆ{ËÁ††bLpNY0CŽ;óYE‹k/0ã( @È3¨ÔØEìäìÒPVÄ¡}9QEE¯B6_$FÖ¼#çÞskLt„íÁ”½ Ü÷nÇT¬Ö³ûN#QYðí“ —Ê{aã°%M€­ŽÌ -o:.<þ%§§QâþŒ±ØM9Ë Ù`¸Ðp½˜|Ðk#GËTñtuîö¾ùü¢-äC2È  ã&Îðí^ ö¦aä1ÿ~°o洍ܾÁÚ4¦W” 0ÛrØ­1V˜u{±;R| ^d L¡Ì^%ÎI‚óØêE)1CçEñ)0Ͼ)ò‚ùE¬"÷q"JV‰9ÜoÓ˜ -m¢–k]9ï-^2À¨¡ ¶XVÎ=,þ²KÀ§ øn^š+lyþ*wÉË §û’NŽ‹§pœâ6¡åÜ&4Émæîêóù:¡5_"¨Mq)†+ýÙÄ‹è#–èCSv¿ŠWC†ë™1Ыž¬ÎþxÇû(œ -Ó˜º~2¤ŠBÒÒŒPºd†ÀÖv"ì'Ã-ŠëÂÐ7"'O&¹É‚(Næ”ü3; ™ã¿Ð¥Nyìà öñƒHD¥^$…‡ž‰©DžXwo¥•°šSÃ¥(ôôsS®ŠÈÜažëR¥‚[ºþÑ2„‹ó%¯ìöÃ.;qšÊ©×/mFU’‹©÷d‡ÕÁ™¦ç¬é±B\(Á±â­ªÐÏRÖ hgèejIìa)ðVåX2¥îryÇ ¦&RT`)¥m +U(µ($?Š·¡LÖJE$^¿ÿû[Xþ -ÅÞÞ~f"x¶ÚŽ. P˜+v°»!Xë9ØÁ6 -½Â‚K -ë°a˜Ææjzp1*†©sJÌŠAôGy÷(À{‚Ht Î8¢ºCí…ËØ!SÓÚÓ\IÔá¾›jÉI¡[Ö„T\%N;Vžó` -F8Ÿ°Ø£ãŸë4³S]j6ëH"'F‚–&–,¶æFzóûd{sbÏ&xeL¼ 6ôTœLÏŽÜ3í;Jµ¹ F@øÎ§n^>ËàxëdX³üÅ‘Mz- ÅËÜ$hì§~ɯâ,òcM1D˜ÿlkëÊÈãßS¶x7”Gva f´œbp¿“…Écc>J6 f Îd±³×SÅÏ -L72cŸŽW7K”²rÜæi” –´tåm_âk°ÈIV®=Yòd¡Ø‰w.8Äαîî–*" ÂWåRe· ¼-U&mcÎ#h©VbÖòóÇ×ïßqχ^Ì~Óý¾½½ø]üm´‰’d§ -µ‰£tWDéfß\|ý-ÜT0²‹‹|óH¬Í&£–pSon.þq&DÑF%ÑNEêGBÂMšì’P‹Œp­†%›(A‰ÆZ$àù.O"Z¾Hɾl#H³¯>xÿáÝËòåeÆ4çRÁœ(ç9ïœ08ËÌ$“Ìv›Ø ÛÊ|_Æ9ÖºžãXæ,"KȤ~3 ª®ýE9® ÌÕv¦°á ²4òÓSú$Á­ÈS?Ÿ¬ÆFp¢ô:IA‹? ¯/ e„Qüÿ)¹:ûR¥@Uu-5{-5ûŸ»fCtn[z‰œ¾ªPˆ„ >aÎ_D¯‘³z* -þ·Ê¾›£#QùŒ*ÌØ_>Ðhùú£±–Ñ n† ^ü -l⦽b‚ö>+]¢H>Ê'Ë)cÃx­Ä<Ù;?–Ñ‘“¨‡ò*I7|´. !$N‹àµÌšèËÌŠªr$›ë ¹{ˆ(NÃiX¾T±]aüOµE*…ÌþÆúå#öK7i^×K þ§Õ“ɹ¶‰¿òQà| ›˜Q0Se¿Ûj*ëµpÙ!&¸‰÷ÌKû”3b@媯0xþµǹÀNœÎÞ±ã%öØ¥‘Â3ú¹/ûÊñQ’ì ÊOINr*“1,SIðÞm³ª,Bœœå¼P"NJ‹±Q[J(áL%~†=~0ïK³ò‡hB7ÕXYPRTÃßC9P-Ûs‘(ñ¾$A›8'ŠI(ÙùÊúºËì½ãp¥([‘šGÙRÍͽjîÔöBsq‹?D%Λ ¥Ÿ7 WÉ@k]Äþ}Nä -=W,±M67_ª@ÿ‰!N÷ t” Ð9$àÏÕÌ2ò¯ìÜá“û41ÈÎé™ -ÔjŒÓ·ÙÁC áâ½^N¹¦ •Içî»?´P+N–Ή—Öl»ãÃFC…šHÿ Ю>­µTûž¤ò×[Óîp º`mU–,ÇÑ4"fQJ7i©Øj—ñ™5q­ÊJúµšžÜRQ†êx²gî Ààïþôí䉔|v#²«=AûÊÃ;œJìMcØ3ÈmÈ0ßšš‹èç2—Jn‹Ñ'_’ì¸ê™‹“RRxßbÑïN‡è)u®ÿß:Úß -endstream -endobj -1140 0 obj << -/Type /Page -/Contents 1141 0 R -/Resources 1139 0 R -/MediaBox [0 0 612 792] -/Parent 1115 0 R -/Annots [ 1131 0 R 1137 0 R 1138 0 R ] ->> endobj -1131 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [463.339 682.64 485.81 694.595] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.4) >> ->> endobj -1137 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [532.224 588.542 540.996 600.497] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1138 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.873 445.578 128.344 454.489] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.4) >> ->> endobj -1142 0 obj << -/D [1140 0 R /XYZ 72 720 null] ->> endobj -98 0 obj << -/D [1140 0 R /XYZ 72 669.696 null] ->> endobj -102 0 obj << -/D [1140 0 R /XYZ 72 236.873 null] ->> endobj -1139 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F15 1136 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1145 0 obj << -/Length 2788 -/Filter /FlateDecode ->> -stream -xÚÙŽã¸ñ}¾ÂÉ˪nnY '³½é`73Ø609Øm#KŽŽuz¾~«XÅCõ,’'‘Åb±XwQáê¸ -W?¼ ùûn÷æíÃfU®Ë<ÎW»ÃªˆWE®Ã¤XíªÕ?ÑÜÄ›àåæ.MË`ìeG#ÑIA£¶oÃé& -äÍ](t¬:«_nâ"·*6ÁG¤'[ïÞ‹†ÿ -£´©hüq|®ÕÞÁkÙÓäеg>u8V¦LõWð­:>á¢n›#  .ÀÍúæß»¿€Dî¢h]fÝýáf“-Oà*ò¿â|©ñI–ýx¹ÜÜÁMÚ^"$ál¤ÉgœHy™,1¡ODµzDGë-®ÿ¢·tµÐòîiEð%‚’ÜÓÔ -'ª!º•êä~h»o£û5ܯ,‚ÝIõ„"êZŸuíxÚ%Œú~›ÙN=¶BÚH6‘6’'>€…šÐ`­‰MÀä¶·ô}Z¿ždC Ç€ëöHP¥ ˜$ª¤GUŒ$ËÄß[»Â±6Q1Øû85,\|ß‚º…jPT Äá¤7–›@ Ѧ‹ƒ¦¥4-ÍÀì±0VCOKzå‰Õb3ò³6/¹¤²ðîË`ëþé…w:rr«~”%›úeéê’âìþËú¸Ýý™Ìêíû?lÃß4¬ëIù¡¤—²'Š­ a^c£$JÒmxÿ{ è\Ÿ†N@@†»AÚäPôp£ú½Ÿæjš|B&Î\bÅe86dŠI1+(üA·TÈÈN Æ äJ¬_vÐæ}ž9Õ4ùOèq¡v<ž¾v§s§ª¥Ãøè¦hpl§>]¡ ;«U8YšïÇÙ2LÀCdV¶|ëëI‹æh—Yðx d§ßÒÈ‘‚|wÆÉ`媣Y'çÅ–¿š³p%Ez¹S‡.XüÏh -å~P:¶ÃòA;«;·ëe} |Nƒ€ÁÙˆ¥{;Ì{‹é÷‰G¡9;š±Q:¯DC.ÇÑFPSýƒWêTXÑ‘"šÖ 0%¿ObmYEX:«Ð¼IxVg2á^G#ÜÓ2ÉP“L¦õÑRè$ÂÙ«\g¶`@§€D蔌 Œ• ¸²jöÒÂAyTûÀÔA˜°ìRÃA©Îõ2lš*œPÿ‚ÔTižúÂ%/ÚjM+¯4÷K92}»á:MŒW -8šè•.N´•}Â*ÇñÔ뀨Ø\5&{KBú{ÃûE#ý@Â'|AÑ.““pjCHNØC6ÐemšñõÜÏCÍ:Y ô©þ¤.a] kÑ5ãŽ@fë å«75ùPœ„²ŽfØŒŒƒ¶“<›•7綘¦mÃrc›»]à&ËýuÌHÛÌÂsÿr>›Ò…í4G;U¦2šFpº@F¥¬+Ê$P)à*£MôLÓ¶nÑ1M*Zs/TNá÷¹SÕQÒØôþ…éýuSl2,pzi—hÀYñ…fÜ Œƒõa¬iÉ×0Al _12vfa1Á\:›Xm€nAaâSv…‰lN‚P¬`Á¦â¶;#ÆšpÇ -LRŽb€z_DW9GŽ òŸ¶&ùV·&aø]tF÷â<¹d³Zß±g÷~:ä2CA3i°qª|'ž ˆLx!ÑÚ¢HŸØý»˜,û.ä Dî‰÷ý(ggïÑâ£àÌéÿ, ?=QõøÓßü~½ûÛî7KHÕôC7îêvÃÂeW,ÎtÙrµ‹œÔ(3œËJ¹îÔõŒÓÁn_èâ†SCÓ ~'ƒ‘„q -²CŽ7¿š77¥ßõÀŒ„½qsIòkLé=²”æµãÕj¡äjP©€Ë£$xdÈ@ypø‚ô”à±8ÞCOi¢«–(Îuîªte 7åsÞÃr1HÝo0á¶­ªãŠ¡Ôàèä£ÙÛØœ¸<•µqâDå:·Ró‚±'}”6}íÿQ°=P6ੌ¦}AˆËÅw˜«:7o»'ïöÌ®yÚ]3ßPö¿˜ä>oX´Ã›¢ â¯ö¢ö« örq–|òD· _üõú#¼ÿÝRØú¤cP¬Ë~—•¬°¸t* Eäó;Oý³q^©ŠZY8 ÷<4 †˜yc£VMtN‚ªà(ã<Ó -ךà8´g¡%´Ü{fÃ$âf^šDú¸==À+…œï@k[bKj2: 0@ÿÃmÈ'Î'b4‡ Frm¬ÆäõZ B3Gi|á’ýg9é?˧Ù9Wýàòì©™ßëÁäYhI}Ö ¾"ØxaRظr—JwôùÖJvhí9?ĵ´‚j‚]O43%|–›d—åΞ3S'ƒÖò=Û5÷y¶÷ÂR£ÆšŠ‰¹uâ—Ø“ Ù{u1§?û,Klº¢åY3>X΢·úpÒÍøAÕ ·Ï´íÿÄ@';Ãh²3ô^yâ7Ó¤ -c„7³YlqãàÉÔ“06”¨ÒÏ8ö?“·Åfy\†N=/ah™àβ¢¼òC+æŸUñÔ¿cû³ª¤'Þ¥MN 5’z!§NQ…öéI¿2âì Ü ¥çbêjÒh‹RþS”Nh¥Ç¢<ÔqwljÒçÂ~z(âE±t)«˜Ðxç z‹1WøõS ?:ÁÊÛIcAK¼Ò|®„àßÀ\V$¹•}T¢U,°bœ*1îQ/ƹ™§D‰©tµ§DÌvCº˜a›{ë?AA`ø™&¶D~¦§t@û€Mc­#‡¾Jì0žãß.zJJ&{¿ætÉ‚¢x.úÈþø„>Ü¿VG·KŽë’¶¦ñÞÆ06– #gLX%ÑÇš ÞëI¯³ŠãrF%4*åz³Ùcq2Aú~÷æW3+a -endstream -endobj -1144 0 obj << -/Type /Page -/Contents 1145 0 R -/Resources 1143 0 R -/MediaBox [0 0 612 792] -/Parent 1115 0 R ->> endobj -1146 0 obj << -/D [1144 0 R /XYZ 72 720 null] ->> endobj -1143 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1150 0 obj << -/Length 2613 -/Filter /FlateDecode ->> -stream -xÚÙrã6ò}¾B»/¡ª,™—Hqßf&qj¶2c—íÄU“ìLBkx¨r<ޯ߾ÀCælRyÐènô-õ´òW?¿ñåûîþÍåÕ~•m³$LV÷‡U®ÒÀßúQºº/V¿{o‹ºì:]T/ë}ä]¬7qyݱ´ëM”¥žþ¦êS¥y‶­õóQu<Ë×›Àk›u¸÷:S~ů.Ñc/›J÷­ªÞvFuÚáÒpî1ªb€é+·Öµü=´UÕ"Þgž?uƒ£½—·5Â˦lžÖÿ¹ÿ70½ ‚m¶Û1{7¸¬º#l"O5b怜Êü_xbÕ*·Aš®6a²M“˜ÏÛùžß7;ß÷>ª/Ä&#³½YnÒ±\à2¾ƒÇøAÌlÁUµ@,Á»£–Í(„‘N#à“i;Ãóðô`€_Âñ¸Þ ¥CDâaÙ›gƒ/ÚœQނɶ~*‚ ûµ*-£¤'ƒ«J™7:‡5e^„ô–—ñ6=3#¼_ð¬Ò -W¿òs‚ºœ?Õ[R«| Æên~ï­V"•놕÷; ËKF‹ ?€*i‘›ˆœ$ÛZ[>VúB^x¸Ü½×Ý‹í´¼…ê@ïAÓe©= Rø‰§0èaäõVÔfÎüUY üm>ŠÀ‰Q9E‚jb ˜ª¯¼òÊ…¬7öjÍ6Z¶ éS¶sʚŀF‹R¸“W‰%XœP PæÁNÓikÇÆ¹óŒ¶}ÕY†—‚êÉ€ÀËvl2gÎb×æÐšZ5¹vd)A–+A š¿dì*GúŽ¥vÚx@aúÞs‰DãhdghŠz»Þ¤~ìýØk$g\$™Ði:ƒ?/‚DÆ1š}ÑO’ŒÁq±Œ2¢é®ƒ²c›ï@¾^Æ.GV+#|-»¸¢…ˆ´‘ç)%>* -v—¡/Q–‡ôŒ‰0†«jÍ Âyn^øÃßùVËÚx T4Ÿn÷WæiŃ[2$<n÷ÛèÌ 8ÐÍ.Œ¼û#P+<㔇5J ¥ä8×Ĥ‹bâ@ÄO呈<&¬¤± ·ÏP{R^"±jú|âV´ß‰]¦3»„Y |Ÿt7ì„(œ]Î&’Æ£‰L°ÔíÌâöÜ´dí0! T„÷Òø»÷€—T¤=ueM=©˜š.Èq\^ÉŠ7‡˜ ÀÑ(ÞÆYââDê„;ï§æˆ†Y0%k°Eqý0½á@%j2O9c¸ÛFI$=høÊH±qO‚š -¾I’íáR/‡9â¤*k -VˆÁùK“œá;º^ÜÛÒ¹êÜ¥&ôÙç^ -±5²gÑ&ˆ%ÁˆCP졲G÷ùîÇë;^g´‹OÒ äℾ€œ“ƒçÔ†ó"¼ Þ1Æò4Ыí‹çä^ ‹æÌ4s—µXóùd+˜ƒ(6àÈ8 ˆWþ§Ür`ärK2»…½¤ÐÇïÀÔ'Þ×Rñ`0§%‰ ºÇι‚$ã$ö>¦ÀiŽ@—zÀðÈûÎÀ)Á´(­‚8^ÈÒý|÷þúÓÕ‡Ÿyæ®þðéî#æÛ_àùXñ -²×õ©“ XN³ËhÙø µ%o’…³øò­ÂçTW³H(/pü ½ ´1­± ¦‚ÙT† -Ë'UQ¬1ø€mq^‚»D[:¸°ûÔÃHŠS~:£Aâú9¹ø¤xò´(ÊÀ5mSÁäeÉ ÷’Dâ©o{;M9sum·ÃÑý6 3>::š8Îð¿ðH$ï|¢<¥”§à`ÛʨiAI O*I*ž¢Å!«óPº¸+ùá+ö‹CK‰žÅ{0O9 Jâ -[?ŽÈúiôå[y·¬ w†=dÊA”Âk4NAÓAA̪³*„Ô%U÷‚Á(Ë+…Î+/ˆw8Ó‡0‡‘¾É%Áx¸g¨Ñ#T.pX®sÌÂh :HÎ"ij¯Ýå‘ç$*ØÝõ¦‘£©Köò¤ -.ê€IÍ…ÒêªeÎŽó¶¯k¬d¹å xA*/ˆ<ìhDŽ–a5ÀOšáB -€™½¼ Ï)L&Ñ4c‰]áÎ ¤x¾p¶×H:‹GCìH¦$Àû¦Ðr™jØ\–"êaVµÆ“FÊÐ8€Ü  8açÝË«0šäpA¼Íâx^\EéÙ™iÚ‡£à´÷j°!4÷.Ì%VQéÙ!Œ¥~üJçÇR_ÌMU®4K½»ý l˜œYKàï1ðpÔZŒ÷fÞžAÖ{ÇÚ¤Ý4ävh¶îx$•˜Ð_§þoˆÞ^p–õÕ¼O”Kæ•N»3®-Ÿwfà¹.¯+‹MJä§çõEàƒ›Ã^Ì­Þ@Úésg þ¿Ha€{ -$Þ%d3V_0ÊwM¸Êâ[žS”²‡Í+@l·=U»==ˆ¼¦47]nùéDVDèQ`Œ¡te¸l““m°ª(J}Yïß“Œ]Ë«rüM’óäw,;~0Óñã!ZâØå<0YÁ™ô?|çÉq4ÁA‘O~¹”ó,­óK öóípì¦êR—ðËQ ",·q‚!ˆGFŸ*• 9Ô.º-îgàò˱bÒÑ®–ÿ¥¼j­ËC&?xƒxv¦ÔÜ$ñÞ»Âq+Èó¶>©®|,«1 ôƒAZd+mGχðA -ž]ßü`©É½—¬g!¶ýIº‰¦;·^X2gúŠÀA*—}NÒgo!/ô‘Z+,0‡«XLˆˆ:j’#û‘Ç_¼â•-¹Êä¥×ŒÌÕmê³\M ‘Ù¹?—M½Ë±ÊYkóƒàú¨H õsþœ ÿÔ»%V˜;'sRø¯+³ÿJã"¤sq…>äý;v(¿J_eç}êkt*HD¡ç€wôfèsL÷§®æAšý”¿¿¹å• -¿:iAr%9é À°(õžù˜þ>®°ÿÀ:"ÐRØÂ÷§õö -¹ ÜÍJ|Xzw^âGXcœä„Ñ—äÔ§¨¥*ÛòìKÃT5> endobj -1147 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [292.573 579.007 315.044 590.962] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.3) >> ->> endobj -1151 0 obj << -/D [1149 0 R /XYZ 72 720 null] ->> endobj -1152 0 obj << -/D [1149 0 R /XYZ 72 686.832 null] ->> endobj -1153 0 obj << -/D [1149 0 R /XYZ 72 665.821 null] ->> endobj -1154 0 obj << -/D [1149 0 R /XYZ 72 646.193 null] ->> endobj -106 0 obj << -/D [1149 0 R /XYZ 72 543.072 null] ->> endobj -110 0 obj << -/D [1149 0 R /XYZ 72 265.317 null] ->> endobj -114 0 obj << -/D [1149 0 R /XYZ 72 158.191 null] ->> endobj -1148 0 obj << -/Font << /F8 826 0 R /F16 823 0 R /F23 825 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1159 0 obj << -/Length 3225 -/Filter /FlateDecode ->> -stream -xÚÛrÛºñ=_¡ÉK¨ÖRx¿ô-¶OÒÓišLìLgzÒZ„$LxQA2ŽûõÝ@J¦3}‘‹ÅXìþê°òW^ùò}ÿêíû|Ul‹4LW÷ûU®²ÀßúQ¶º¯VxÃQ­7Q\xwþçÞÃ:̽§A°CÇØ~½ ``ݪ¯½2Œj×aæ ®~Xoà×N<UËÄ%#¾ùA\ËzÝ3®;ñšVUÛõ&.|ïn|èÕFE|‡uàÕOë<ò®€>‰<…g*+€záßV <=(áÌ7€›í^óýwe»þ÷ýß@V› ØIÂR‘M˜zMY”yz8vãÀè]Y׺=ðÌ=LŠ\úæ'þ~lwƒîZ¦BÀv6ˆM?àãÐ{·xY6 D·ÀZv)§EµBI„ö)ðÂrö€€Õr =ôŒxÓ7׌}ÔuÍh¼qæÉ¢^ KR!QF‘lÅr7=£åÎ-ëL|úò¦bEÉPîÿuëvË·EXðnÿº»ýtrñá‘O§ZïJaϘ¦Ä-žx0”ß×ü\±‚FüX')(â†ò èn/Ĥµê‘)Ò©|Ië$6cÝñ¿ªu£ÛrfM×<ñA ·G6FNŒªˆÀݳùÁ¢*õ izïJQÙ—úsñXDV„ò…yA"ÏŸ‹hEä³õ$ò+Ç©ežq"xDî;s±£3€IGAi ½ ?òîráŠ5_+é!ðÿìz0n•ŠÉú`Pu-A°] .€Y´;™=MwÍã™aN£wåØ ±½Ø´9DŠx+E·ÜôZ|˜&^]Ôã0M—iP®HpóùíGÆœ› b¾QlÔȪøšq"Š7=/w>çx‡^Ÿ®I84 $ÜÕª”­I;‡>ˆvFõ'D¸ì^ÙE¡lƒ€\ä­>衬ñEõÀ{‡TGÆTºjß «¦ç؜Ѣл¡¢àk¾÷Pîð%¿?"£ÒT¼b×5'É[zŽ–Žh±b©zá~2ÝÁ”M*$^ß52Áª´p5ëêñjpÑY€ŒêÅ\v6NXÉá4¿Î\óÌäO"zôIäÔaôˆ3GrÚ VVÍTÆ0l:zËJˆŽ¥œPôœÜ Áõƒ(F¿ïãø¾Ì <ê‚(Ú/ œ€' -0ŽÜÑ©-¤’ƒ™9ÂŒÍ)Â%]ïy£>› ?Ùh)ì4{8ö>ºØ€tn"kËæ9ú7Sö—ØØ»9–íaѯ½#óŒ~AŸ³q5ÊØ â#í‘ürø‰ýHÁ   -ݯ8Ñ·ïƒtÅç 1·…ÓFñ6O#>m¸ B}&ô”°>K¼[ð°ýP6'ÖÀܧ5¸¹Îóeà&ÛÈò¼îÐK„ynß&Ì1ïÔ­ àªŠçøäˆ²‘±˜ÏêC =9Lª³ó!mOçÔР²ºcZôô[FÝSVƒHþ‡ÌÛöM}Tõ Î"4‹I/ŠÉ„à£LI>ø;)pÿ#_0Ð1ßšÕħä€ÐÖx~cÄìÕ ãý=£AÝ:TÿGÚ·™/8I¶9]£ÿÉêq!f„É<#\¸=…O| þ›ÞÍéhiÜ‘7Ñá•<à,d„…èvW•<&¬„Àµƒ:J^e4V6zЊ*,Y„ÞMâ;Òe’¡¢Ö”ÕtÇ´ê’—ÛUÔ)³J·”sb4bŠp>ÄÞãQ»è‹Ó½$üîâb°¶"@íbŠÎÊVÿWY›n$=\H{¦p ›5åO݈BŸ¨Ÿ6RcNΉQ“Ù²/tö‡`k#%Œi1¹ÏŽe÷ãŧ5…yNŽB©ÃY­¤sE•‚mv -äcºÍR*øCWÈ7D÷óénS«¸—ªÅoOÚuá´9Õªq™#¢± -‰øi¨¨ÁÉ™¿¼ì TRÐxÊZ–ZÿKàÆÈ}v2JÿqêÌÇòÇö)wS?wê4ðxWsjàà*£9)|‡éG4d6x„á„[†¾¶µvV c:ý•À"wdÎûÙ󴼫dY&¾ ¡™»ÑÆžb9¡¶Aá{µÚ ‘r”œãVËσÿ™„p¤$AtãÐkÊf‹¤Âò½k©¾|¯Q y -Þä`5 ­ ö®ÉämySø—ŽÔÄzÓÅÛ‘ @'r~LŒ êç L zá -’bö¦HS>ÔƒÓRÈr…Ĺú\– ¢ïðQ6=çé6xN4¿°É…û9­èCIlEJt„¯ºâ¼ïÜ6x!eñÉÒ a†=Ãhn¸âŸ>³þïÁù3òò’h²ÿÃ(4Ëú¨ÀyÙz•4þ鑹GÇe<¸Uv‹H$ÁP*YˆÆ9ý’šû¼Z¾¸!î"ëvDÒ©Õ„èÆ5z4xnS>¢mÂÀwŠ{+k¼¦µƒ`®û‚àS@iak*ZÁHµÄðTXç…%™Q&™+°ºSœ´ÂQ^pe+¾|xµúƒD[*h]UÐÒ'Ì-R€HÙŠ)Ó)že:·‰–bó3'¹’k¤lj!–Rnf"k~³rùšHÖ((ô™gÏxúŠ¡)Œq¥µø,²±'š"I$E»’OÄßSò SG]UX›!¼7]Ãw `êS¬mÎ>Â¥P$±ºâÞS¯¥Î}K”A¨žÈÏ,™çlrÆÓRòçUPÐ'® óg•Ïë4œ·ÕO‰š€ˆ”:ˆÙ¶®®á¢Hò}/ðmSØÇ„w u|ë¬üÙxHqÃç CW N†àû³†˜ï2Èv%éÝÄZŽÏÀ£éˆóú_ï¿xu×.Ž3˜GåØƒÂ®žá‰ó¶b –m+®6ƒsUJˆ]G!µíÿlæó3ëëe»ž)YÀJÈí¾øÕ`àB:¹8•†Ð‚‹:köÒ#Ls.uÓ¶NrT+)öp„]¸±µ9Q_Ö¯™ïÂÑ6J¢ÕfF†7× NmÖYÃý¹Ms› ³¹&Î4RäInÊŸ²\ -ÜÌÖ˲’7ºÛX)mÂR€ð\V¨µ¤eÔ÷ü©’9öþ‰¾Mñ´jwÝhè›Tdm²’Ké³ÖE´Ôº 4›ý˜…¬à¡ÛŠºŒ#,?LÙî‚ËÂQ{åZ #·c‘Ù8Uÿ0Ù/‡c°aóC,=rÕUìÍåÎt½À®–Æ/!ÝÉv"og@ÏYeªù‡E;?¨Zro Õ¶’zFÇ€Z?˜Ò<Í·¥äøÿìFÒ5ü2¶.¼±OxÓµÈê0—¢ü²U8¯_CÈ/!ñ¬)qÇ'·uªË{º‹ï*\¤˜+4ŽŸ¨“1ò€J.äÞJ† (MsÂ6¬DO<Ú«rà!ň„ÚÚO}`ûåé5ÃdòKŸ„Ù«¢#¹ùô÷¿à‘äYh vI@»æÓøÕ€éK $ˆÄÄSZ -´ˆ¾çÚ9j·™Ò¥™<±/û£4SŽéŽSJYJ„ºiJþf"†’N݉Ŭsþ¥ƒ¢‡Àè¼ c°û ™…ÅxÖ㈹_×Hg›Òa6 8›Õà~gôiè_nš¹ç£þœäChKR›™Nzè6.ψ²ö¿œ‡Ì0,¶~P€1DÛØÅ’3¢ßî_ýpÕG -endstream -endobj -1158 0 obj << -/Type /Page -/Contents 1159 0 R -/Resources 1157 0 R -/MediaBox [0 0 612 792] -/Parent 1161 0 R -/Annots [ 1155 0 R 1156 0 R ] ->> endobj -1155 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [351.55 350.988 366.272 361.836] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.2) >> ->> endobj -1156 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [372.374 260.328 381.562 271.176] -/Subtype /Link -/A << /S /GoTo /D (appendix.C) >> ->> endobj -1160 0 obj << -/D [1158 0 R /XYZ 72 720 null] ->> endobj -118 0 obj << -/D [1158 0 R /XYZ 72 536.75 null] ->> endobj -122 0 obj << -/D [1158 0 R /XYZ 72 192.589 null] ->> endobj -1157 0 obj << -/Font << /F8 826 0 R /F16 823 0 R /F7 1089 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1166 0 obj << -/Length 2790 -/Filter /FlateDecode ->> -stream -xÚµZKsÛ8¾ûWèª*¢ ¾¹·ØŽ³ÙZO²¶3ÙJv4 É,S¤’qòï§_(Yò¬¦œºÑ_£»Ñ€äMoòîÄÛùžÝžœ^úÁ$s³Ø'·óI»YNå¹^LnËÉWçžJ¦ÜþkÍvz™ŽX°æ~îꪘ΂ @¾°ÖØe;ù‰SjwGÒÖê3–5S |£ãWÿÔi^ºó²yÃ}ý£×¦Ékî­òþþÿ×#þV˜ú©‹ðryQŽî:î“-R°…5Sä••ÑEßšŸ¢¾aõÙ‚0AýRuotÏëŽõE‹`kOß…à¾eÚµÎËÓÏÓ4pLÕë1CèyɽMýsš†Î/u‚KÔ$ïúþв~Yu¬»Ñu»XTÍâ—-3BN+ÿŽ Íæ~7t}^5¿T˪–})ó^ÃzË•…>™ù¡›y |7Ëførsñá¼4Jœ¼îÐ_£Ô©àlÐEzƒƒFw+ræ¶);žÕ·¨³0ùr‹Y~ò0oå5ä<»††Ì¸Çs †4déT9-ï¥6´=Ò­K@sèÀ{¸É›‰ Í×Tß+¯Ô]aª;Z²8ÚÍ1ãHîG†¶Ôæ•H¸Z›ã52ú}Eìt~WïEÕéU4&›€“Í饊'<ÇÇðŽ t=•1‡ïª,©üÈùš¡Ù’ȹ©M… ¤5ЙÉopÏB/5}§ïXþ8ø@º¹AØ4ÐQ†bçÂL•S}G‡B7˜þ)e M!» Ô Á¬Ïí¢5p:àF÷Àܱ ²ŽÞ !-'dòT$O…¡ó§WLÉúr vwyøª¥t ÔÕz :™ßuÃ’’x¹ÏÔ¨}Õ°†¬Òè—“H©¦$ƒѪZ5Vã5·wÍ€xú#k‡Z˜({óˆØ2›žçC-kJ¢r5gJ5åý³ÂòŽ;x hÛ½»¤¨$¢64Hmn–UÙ¼êBšÂn“¤ìÖ¯x†Ð:‡°j)Cçlß -ØÙRëáÈ0GybR˜1ÚߎG;ý}Ê[3¡@DzÉ sÓ.Ÿ{àú>xAYâ\ä›¶ž½åAJMðmZþÖ-ˆ6Üä~ÓëRdÜÞ[–•¡“óBTü¹¢rPÏZSAA³§M€9óvªY»;[yÙ¡FJ M£±É©lŠ)·Œ¡ÊAÙ†]ù×iM-@ ¾ç×èv·¯Ö•K,<š|Å­" -›H©-+}b–JbE|1vº|©møHޏþëòØ­^¢Y„áRÃOîÜç"Yr¨–pÞ50ù~Ï ŒJ°áŽŒÝBÈ‹¾ãV]=ÿpï,§þЭòBHxä‹óJQøŽf/ƒÍiéÀ1†ž‚E8ä,7°¢6h¿Ø·£A¾¶Y¯ÉËä"Ùä hd4pÖež€›œ%7´J.³) Û´B7úÛPaÉ€¸ -°’Œ(„G6ç,ôºA@S/êgŒ×Ö”7}Žðâ ¶gX·«MÑ.—t”5xšËêT?{7&„…<ç‹0@a¦÷tZÖ°›MÚX‚ò^‰ aVµTË<§‹—Ót³„öì­u@C¨Ô:_Ïéj(¼oBÝp’QxR@öÔÜÞM’a \ŽàÂÌ1\…E×râ@ƒ÷žZxÆÞ7«Aê µ§ò܃LqÌù™Tî™=ˆ±ÕP†Íví„C Šï|[ÈØ)“¦˜I‘‚é¿ãTpÎ$zQÈÍ’{gü€Ôö#…„×ÞZðºG×  ÝÉ•Ûä -.·?5›3Ö¥` Mš½®­OC¯k:l¯£UÅ£˜€ähê|¥ÐËëšc³ãþ²úAfA–9ìÉhrB¹æÀ$Ó©ðÄ".Š¡ - t#€¯œd‘ˆ/xøDÆÝ¾íaLÞŸ ¾®èrÅowt¼R b—7åá g¦*¹,âU%'ª®å¹m¾yê€Z»ë9 -ŸK|ŸÛ\©°Ü›oÑ°Š 5ú‘+GžoñáÀ½\y¯qpÙÕZL^RrÇ&‚Á¯õä  - ‰xμ#a§«~ðpnd¸‚ SYñ“åÒ‹ÁJ5{M­á£3ØÅfûR&hpj°d5C¯!²I°ú?èaáííÉ7yP“ÄŸøQäª(Ë“¯x“è°‚déä‘f-'~ºA”@»žÜœüg‡? \Ï žã÷ä.-ìôŽ<¾'‰›%)HŠÝ(=Ëmî6 È`+87®)9ZŸ—ªËJžíBˆ5~¶ œ·‹J&þNî@ïhOŒ(àdÛr½0} C¡Ñ!K„‘Xbý+fÀç)ˆpñ„’œ±/«›WäÃðÖ¾Ê\/{?ð}7N:B˜<çtÄcËIL¿¸z#Ïù| ­ì!üŒAŽF´m/qUð"þ -%~xÐ és±¥Íú1ÙtÂ:¿ tËúã9SeË*ƒ“ú/` -•¥nô åy` ß– [øéu?ÊÝa˜Çë¹ 3 \ßO^f»© -ÃTóæoÁN›ï¼ì;R‚ôV ò9¾§£Ë?Ÿä»EÍ5.•ÓÛY~°?àØŠieðI}[[Wgº“ƒƒMâ˲B0öçÏùæ]àÙ:B…‘øÑs^¡²ÐUI´¿ŽPAƒê%‚'ˆÝ$JOfÓå:Eœ×l7¾°AØ9q#¿Ê]àKÌè°kêxý·áûÊõUôðýÐM=ÿ ül·zØ¿?þÑúoÃ÷2P¼zå»i˜Μþî!ñ´ùÕó"·¿Ks^8ŒùX¥· gþ¼ÙpÏsÓÌ? 9Èü«;>“÷zë:÷{øWØÖ~»òâcrÅÖŸPÆF> endobj -1162 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [264.13 563.362 283.834 574.21] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -1163 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [473.63 163.9 488.353 175.855] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.2) >> ->> endobj -1167 0 obj << -/D [1165 0 R /XYZ 72 720 null] ->> endobj -126 0 obj << -/D [1165 0 R /XYZ 72 527.351 null] ->> endobj -1164 0 obj << -/Font << /F23 825 0 R /F8 826 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1170 0 obj << -/Length 668 -/Filter /FlateDecode ->> -stream -xÚ•TMoÜ ½çWø,u]üµ6×U›J½TJ,UJÓñ²k$\À‰òï;0x?ª½ôäÌ<ÞÌL“cB“ow4~wÝÝç‡6aÛÛ¤;$M‘49ÍhÙ$Ý>ùEÒ¶$‹êÔʦ›²¤$§…9áj §%ýBóR\ÌF Ÿ&a좶½é&'*-Zâð||½CVa…y“êˆkȬFØÉI\ ¡dÏ]ܲŽO³ÍÒMUU¤€%ýÝ}‡š7yž±ºÆê•1Â-F!^R'ÿ,—Àç–Öëtª÷"®Ú X ;åyldx—n@ƒêr¯÷•x„ײÂÓ¢!ož7¿ B¹%é}3¹ÈÐÖ€e?n ºåQ‰Ð²’8í¿È×òÒW8ÍÜÉWlu¹j¤Ý€þVd÷åÇÓ½ÅíZÓ÷ò‚Fm¢cy~„°È©‘°× -zUËÞY ãFZh_g'ÉmÆ -†’ŸŸ¤#–y¥kra‹#‚õ.€yÖxPû^B/B{|K[<è!Í[P³Æ[`Ø(þ!\ÂŒ‹Æµ«ë×·¢AÆFï Çë¸áN,cç¶£g(öù ŒV#Z,GC¼†Óß:) -–Ñœ%Ж•eWÍUÔ×îî/¡§‹‘ -endstream -endobj -1169 0 obj << -/Type /Page -/Contents 1170 0 R -/Resources 1168 0 R -/MediaBox [0 0 612 792] -/Parent 1161 0 R ->> endobj -1171 0 obj << -/D [1169 0 R /XYZ 72 720 null] ->> endobj -1168 0 obj << -/Font << /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1187 0 obj << -/Length 2103 -/Filter /FlateDecode ->> -stream -xÚ¥ÙrÛ6ð=_¡·R3Í[Rßb§ö¤SǙȽœô! cŠT ²®ûõÝ )3WûB.‹Åîb±‚ÉvL®_ò¿¸{q~f“0ñã$‹&w›É<šÌÃÀâùä.Ÿ¼÷âé, £Ô{]ÚF…)·ÓYP Š—˜(’Ä!Ä!ÛÅ“¦”x -ÝhžÓgâè°SV&Ð?ðÏQ Ó· ms¨Å®ÚZ¦‘AfYÄ$s Ñ9BdY°>qVDa&½þ·%e‹´;q°ShFŽrŒQüãôT?°ÅÓ.°#h%„I²tÈrO,Ÿ„ dh쎡F0˜ÁÀKJzIiXŒ>-M¼{e±RQó™I¢%duösôbâs°<ÝzDëdùÍÂ+5FDU ! ük½UF–´¥+­ :‚ÎÏxiU›­á ‰QÓ)†oøßs§ˆ‹±1ÕT£|îi°)¢™Hºš8ñY/swE¬=˜¤1OtIpÇ$ý¼gJý8“žéNJ‹Ø•@z½Ä ‘ªàYåËÛ®xùb}2 ü4M$9†šßV¢t1®_Þ½~³ºCO|ùçáo* -ÂÏ—(_%À›ûÙåíÍ×n·Žÿ÷Ö?êæ§WïþƒÖÉÿÞú·‹×R÷ôOVø†škì!j­rêÂj¨¢,÷¥Ö¹›Ý¸ž†o0"ñb"æ‹)‰ŸûMÌ… Dö±Jé8POЀ¸Ã˜i]Ý=,¨+íâs÷;÷MúMžÖv8ÉI *ØgCO‚vtUãÈ_Ìû± DMOîÏâXš-:¶À“\ØÙ± ÙXEQ÷4 ǽ˜FrTÛTPŠ™5uå„ªŽµx](òNË3Çž(Š»ê;™íwÝ«­ÈÂ¥–‡IН-RÔÒæ–9ÝÜ"òü\¾½ñ%Lžž)¾÷\¾=¿á÷ž8]ð›Ù²þ~õûŠÓ$’Ócš£_:Í¥]àÕ ïåG[m£yä´ ¾’åuáXòKÎ!{ío}b– ÜY‚›w£C{î‘·©Pަ…{BµWá²ë½òK_Ä(þ•ú‘' 2XW\»C‰bðžm™„¶:ïqG§‡PË‹¨I —½ce™\ƒ#y§CÞéF -é“W;¸![¯ÄƒZŸ¸aGÝà BR2Xû84Bduì¥ÔˆàX6 -;cq%y|IkSµ2ÑÝkð|§¯¥Dmí¬E[ç‘ó¶Î -†­3bкX‘œl÷šÑÁ‹Uï :öè%aGQrK¦“Ç"ØØ=_ÓjWoݯ.oß\½¾îCGô‡a4Š–~.'P’û‰(-4?ܽø^¢+¢ -endstream -endobj -1186 0 obj << -/Type /Page -/Contents 1187 0 R -/Resources 1185 0 R -/MediaBox [0 0 612 792] -/Parent 1161 0 R -/Annots [ 1172 0 R 1173 0 R 1174 0 R 1175 0 R 1176 0 R 1177 0 R 1178 0 R 1179 0 R 1180 0 R 1181 0 R 1182 0 R 1183 0 R ] ->> endobj -1172 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [78.199 584.605 92.922 593.018] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.1) >> ->> endobj -1173 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [78.199 564.68 92.922 573.093] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.2) >> ->> endobj -1174 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [78.199 544.754 92.922 553.167] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.3) >> ->> endobj -1175 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [424.077 501.97 438.799 512.819] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.4) >> ->> endobj -1176 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [70.45 336.086 92.922 344.498] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.1) >> ->> endobj -1177 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [70.45 316.16 92.922 324.573] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.2) >> ->> endobj -1178 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [70.45 296.235 92.922 304.648] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.3) >> ->> endobj -1179 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [70.45 276.31 92.922 284.723] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.4) >> ->> endobj -1180 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [243.277 245.481 265.749 256.329] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.1) >> ->> endobj -1181 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [389.724 233.526 412.196 244.374] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.2) >> ->> endobj -1182 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [416.104 233.526 438.575 244.374] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.3) >> ->> endobj -1183 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [461.621 233.526 484.092 244.374] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.4) >> ->> endobj -1188 0 obj << -/D [1186 0 R /XYZ 72 720 null] ->> endobj -130 0 obj << -/D [1186 0 R /XYZ 72 720 null] ->> endobj -134 0 obj << -/D [1186 0 R /XYZ 72 412.258 null] ->> endobj -138 0 obj << -/D [1186 0 R /XYZ 72 208.626 null] ->> endobj -1185 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1191 0 obj << -/Length 1648 -/Filter /FlateDecode ->> -stream -xÚµXÝoÛ6Ï_áíIlEß–3졉ӮC¶Û¡Ùö@ÛT,T=}¬õ¿;ÞQ–\om¢ãñHÞÇïŽG;ƒ§3xuåð÷v}uý2LíiäEƒu2˜xƒ‰ëØŽ?¬wƒß­×«õ0ö­o«áØw]+­ðëY;Y¥O…Ü·VÄÍÅÇ¡[’Fõž‰´¨j‘e¢NUA %¬É­¬xCQьձËñ¬HN,…‚pþfèZ™DÒŽbý–Ö{Zú¥¶Ç!®lh i)±þ¹þü0v]{†dñŽdOv|+)UŽT`öÄÚ•éßÚDÅŽˆ¦’%Ë–Rœm:97¨®C®Æ[ß½ÑÖ}Yª’·—µÜ¢qì*`¥¼—ü\Ë¢âÓGh…s:}%·zXtå‚MΠ|±|u5ø] ù¶ ¾2à)•Ð>õŽ»à–\xn#2ŠIÒd‡I~>d"ÌAËX‚‚´ÁA6qaO²Òˆ­—i!p?׆EÝÀy:p±ÅÇU"‘æh±!h”u÷L¿s¦à™Bв]*^0ñ ©Rmhæø¾µ1'C˜%hO4s§H°TÙøÎn7Œí©7¥ oe¢JIÒYô3"ĵ1’õ^ë¬)IÓ‰]K¡O>µ -œê·@á#j¥š’ø«™v³´ªËtÓ0²@8iN˜ÓÑFI†ÝôprýÒó;… ìi Àcv<õÚÔ™œ­éÖ¤|àkY­—ý¸|cl  Ðêq6[€µíl`¥ IÉÛè8ÉÝN4LÔrU‹œ(y›”=ƒ…ª”;8Áý/ƒÆ¤ÞØ…¯>ß .ôì»Å\b웜IßMë=ûÃjb -3<.†Õ7 Áa½{{='ªõÚ² ôêXÕ2oƒþ‘´ïšŠ±%²JŸRˆ‘&¶XÓM&¿=úîó5_ 2ïñßÝÛ¹vרB 4 ƒ5"ŠN¬÷«+ðQ_ôq‰•rüŪ³D!·$ºõЯs(9f5:™èD±l¥e+4[f‹à1€Ûº~ñU$“¯CNÃ(:o´"4-Òun¹É.„˜†{a]¡ãô‰Äwi}n*Þ¶æ*¨ø¦-ÁÀÙˆ¢ ÐFÜ“¢†ò¯FVu§tÒ)"¿^•ô×°¨nžãZ.&eÂ6e4™¤SèJüD½Ý‰×ÊL&¢ÉêŸç‹÷œ"ºyÐó7_OÊÕq)3~âˆZlŒ%m¸óSÿ3§¸¢J]3çJgȹ%'Ì“%nß’Œ°Pºa@]èy?è‹s$M@JaiŒ£Nªh> tðažPŒ´€{9×/ÆŸ ùº™O©Y®Á’™•´½XŽÄÌSÓºÇdºæõúñ|Âìj³~_&@ û˜ ÔèÒå7݈ž¢XJx½vèkÑ4Ðõ3 g ÕO˜»0p¡x¥51—÷ëwˇ ú&ë5ðŽÙâ&{lq¥Ö§¶MY²{‰±ƒ¾w[«’HŒvíŠÁãR2¶×Mµ}SÈ·°:£žp¯P‡Ñ)a5BrŽÝšnéú݈šÍûhµ‰ù‹,yºPU©ÜPÐüg‹ -> endobj -1184 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [480.602 695.149 510.822 705.997] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.1.1.3) >> ->> endobj -1192 0 obj << -/D [1190 0 R /XYZ 72 720 null] ->> endobj -142 0 obj << -/D [1190 0 R /XYZ 72 502.821 null] ->> endobj -1189 0 obj << -/Font << /F8 826 0 R /F23 825 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1196 0 obj << -/Length 1875 -/Filter /FlateDecode ->> -stream -xÚÕXYoÛF~÷¯úDÃûP ¶'nm+„qÒkjeá¡TlÿûÎìÌR¤B'F€>TÚÝÙkŽoŽ¥5ºY£×'ÖíÙêäŹkb3œ`´ÚŒBgÚ–i¹áhµ}4–u#óñÔw|ã"w’º›4ã^SR»M²¥î'Ë·ær#öYóëÕâýìí•9[\Õ¦ù—ÔØÖK˜½Y~XŽÿZýþâ<ê°a¦NdF±Í\ÈL&M=žº®k\-ÆNh¨x.Ë‚Úf+©“Œ§¶±ÛFUÉ74D_Wé×±rBã}-+ìyÀ‰Œ|£¤# iÖœÿ\A3Ô¹¸œ?­çiý¨=Ý´¢“¼Ÿl×›ýÂjHö¤§ˆôäµzq QI¡4ƒ·Ú‘;1ݺ(<*´‹ëåj¹ÆéåbI”O–íò‹uMc² t*ùe/AeëúLÙ"²´!â×±"K×¢‘¼ÿY+÷ÊÝxŠ‚T¢I‹;¢Õlì§h´è‡ÆÅ戃Ùì-ò:¡ÑÙ\³\V­¶û> yv¡æƒÀ ;˪I˹ -B£ÜÐ $2ÔºŠH§·u™í›o‡Æ(«T¬eF$R m1U6j¤„ðõÌV´²aNEAtYUÃræ²®¿ŽoÃê5u¾ìS<ÁñC4Dj¶iM=V_êöìÐXµÓ¹@ú# H¶$A â8Ý蛨=hïÒšÁV#vïñ@Áüd¥XƒÒ$ú9s{»gI냷†¸u@r­R”å3.“ê¸À¸O›mIG²‰±óâ”Úz -”Ø‘BRoI'Í–†¹„#Ȭ5QJ^˜ˆ,SØÅAß~HÙˆ4ã:ì"UÍlÈ¢ÞWR³$˜zðÅjÕ’ÓXyÃäK'p;Y(WÂ@ã]UÞU"§2'´Ç>Ç 55{D…£6›´ó¨ÎrO…aì°«% •Q»r+Z‹ðBG(«Ï-ë"ã=þAôˆ˜ &=±ƒƒØ®u½Ñ‹+¶“ÆTF‹Z/„>±‹‹ûCJ"Š¢lh]7~¡‡úùpþ>Í2ÚUèÛT<Ä+Jj“’’–HøÌN„}È%ÜS\ -È/yê~[vnÄ{Ú¤¢á< p<ƒ ¯nÇlPB6H8c²9€Éo3™&2»¢gÔEàh/k§µ¼BLR -»È -ÚhŽ«µ °ŸCÅÍ[Z&x¯J÷*«àªøÊFVµò¡˜ðãòò\T4(™[ðÐZÒql¸¿5Ñ×i½Ë8œ!(׿bU¦q;¨ÇAÍ’¤(†2³«ðŒM›@÷:]¹Åœêû–4ïÌ ­ê^— “^ñãõø%. e|7…(^Y§yš ¶mS¾ü‰ -èt½® y Î°jAc[w -£ôP¡<‚—ÖRòâ}±Ær»óùª[ ¡žÀ´}§¯lÌâÝbÉŠ#ë FË2®ÄŽˆ¿Qã6ÌáIžmFÞÑIXè’ÔþÎ!¡>d BÐûÏ¿³?šÓþ~%7 B3޽¾JW[Jâ [‚Ѩ÷»:Ç‘Hy¥¸Í9: Ö\ÉaS•¹Ž_²ÖIåJœÆLŒ“Ì¥â„Ƽ¨ÃÍzˆ¬P!‹b]ëâ¸U.™Q ~o&ƒ>Ó¯\„,Ô! -)©ªå!)Tp{‡šŸk9ŒRZ‹àÍ‘¤ÃDOÄ›%Èǧx”(`þf¤'#Þs]žéd¸âÜ6Élrô˜Ñþj>(©ãÍn×›½ÿµ7ŸÍ¬çyì̳~è•sÇz¶çò#J°;0æÂö½ØÚ¤ëš íƒE:¾¨L×ú"ŒØhUÖAbZAS>ˆ|—éï·©Ny8IO}$QL¯+& ,Fd_€‚à+0:@ª$ñq‚Ä’JQôÄT!_‰¤Tü„aÛÆ9>5ô>%mL‹Õ£^nè4HCÏo01Ó‡ú€Þ«ÒÌqÄâG«ò\ˆú3Õ¸4d~}ŽN@) ´|MnzáhžÂAа8þZÓ«|»å. ¥þ™¤u,)¼"ÚùŽ>Äu¿ºnÞ]¾smùŽ›– ¦1]‹¿MºVoÇ«ÕÉ¿4t™ -endstream -endobj -1195 0 obj << -/Type /Page -/Contents 1196 0 R -/Resources 1194 0 R -/MediaBox [0 0 612 792] -/Parent 1161 0 R -/Annots [ 1193 0 R ] ->> endobj -1193 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [514.331 156.17 529.054 167.018] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.4) >> ->> endobj -1197 0 obj << -/D [1195 0 R /XYZ 72 720 null] ->> endobj -1194 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1201 0 obj << -/Length 1854 -/Filter /FlateDecode ->> -stream -xÚ­koÛFì{~…‘O2`+zX~7/dKì"öÚ&m1œ¥³-DÒ:9iöëG)[ò”´ öÅâ‘<òÈ#y¤Öªå´.þ¾Ÿ\ [#{Ô÷ú­ù²5ðZ×±КG­/Ö|-Û]ÏY‘\ŠmRàbh}uÜ^„¢í ­ç ,†–$²(˜´Ž5AHX*Ι©%íþöºCû[&)—‹¶¸ÖŠÐúY2åm@0›nâ0W3µä­·çׄ_ª<-¢·!*^ÓJhâˆb]ä1(UÖþ6ÿ<Òu]{dûcÛœAvøŽg©%~]8òÙtF(‘K‰˜\Kñ* 妑Ýîöüž5fbAŽhÃ‰ï ˆ µ%®TŸ’¤\jò†Ê""?ÅÅšµb¹MB¨œ0‘±`dy[H`Y2Œ -c;Éñ N¸šÌæí¡o¯Å¾ê6€Œ`÷¬®)#Pdåñ'µŽ³3Ñõ‘c@†Rw!†X¸œ‡[-ó±ûJÍ2©´w‡Ú#oD‡žf¡<~ò5­׊p3YUÙ|`>íRm÷«—*IZú´³ÉUºaĆõˆ\¿ÃCî’®üž\øN%õÀoh;Al¸ŸAŒÙínàÖ,þG4ýÓ¶mõ(óD<͈|ÌvÓžiœÉ“ÓµÈV,ÂÈ&"¼X@˜Óú«8_î¾Lp'Ü;úüâëåâàÌcNoX&¿?Z¾œüp“=Çç¸ê•qDéNMë}J 4E²B̶×tÀ  ù톰Zb*… ÊË3ÉKzˆ‹½`hL ÙÚwëjyhB\?SÞäè8‹9çF.,à@IRæ×È!õ@1Z;?µ©h"œËP¥©4aìÅ‹ö~€ÅÊ&pBŸ¥É ØñÕõ{uLXã/ø.¨:‹r›ìðs}LX׊ˆA?Ä›’U6™ÙöC«\lÖÉh¼éUKœ7²$ƒÌ‰¶/@£Z 2Ã]ÁaÇdMˆ]1!ëКBûzâÑ ƒ•æ6Uµg'r$“E¸¥Á9¦£Àf-¹Igxßëà$ó0ÂMán¼õ*+fQ,`¼Ð*ÙŒ½Q摬^ò-SÅD”‰X&’ŒÉä£*ï æÖ5R¿ÝL?ÒTr:½yCZ©üWìÿ¾ŸÍîföÍÙõN;^‰˜ZJ¯s@×éŽÌt>09 ‹ƒéÜsÊÁ A,<‚I§2ÃïÒÉLœ°|a@÷®ŒNFgR‘f`·ìqjsíTæqXÐ<ÞÔlÔ ®g~¥›l9ÃÝt È> V§ónàx4€ Q¥ªASY9} ç‘b]âŠe@šÕ4ÓÎßØâ› €LS è}6>·ó K4nBÊ÷ûŸ¾ô°ÅÉyؾ÷aLÑ i>þ©œÄÑ^Š™`N(šF€wq`åÌ]*×»¿#•¿#ú`94n†ÊÁ•e@%Õ²©Káï sè3—©¥PY¡*ýÚ_œ³¶=»¿&ªU£Ýõ Eá!—м‰ÂÌU-õ¼ô¼‘í¸#P1²‡Ã!ÏnmÇùüè_êxW­ -endstream -endobj -1200 0 obj << -/Type /Page -/Contents 1201 0 R -/Resources 1199 0 R -/MediaBox [0 0 612 792] -/Parent 1203 0 R -/Annots [ 1198 0 R ] ->> endobj -1198 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [509.769 317.928 529.473 328.776] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -1202 0 obj << -/D [1200 0 R /XYZ 72 720 null] ->> endobj -1199 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1207 0 obj << -/Length 2353 -/Filter /FlateDecode ->> -stream -xÚ•ÙrÛ8ò=_¡y*ËSÚ„¨‹‰ìíû§ë…ý„s=çqîÇNÕòŠªµe§¶(óìÌÊ ÷]¤QÄÒ6xÃÄu2¼¾FØ£ËjCb°0¤ÀmQD”U%Jߨ¢d­ÁêÝúêf½àõ9ã‘ -ÅBdkð¶ˆnöZ®ŽG0£Ê¹çleïHqHu~!Û*¦(JÓ¨Ãap,ƒ*ÕJ†6^¯ÆÎúÑ4úÈðÇ£Úi{}‚C€¬BüuýáÝõâòfÅs´Ž|ô_mñ}ï4+E*ïë¢R+*€[¸oQë /ßæhÀÑ®Ž½ÛÔ*Ã+~3"K>ºå’o):G9ƒà¹‡vC…aä\WõTù8OB¯„r4êêDû´ðBk©rË“Âüp ³.9RóÔ¥ŽúyD¶Üïu-â°}hÉYÆwòöKUþd‰÷òbï“°ðïÖ4ŒæËÝÍž¡¡7.:u'‹ÔOYBruw9`ëÆÖÕÍ"Ð+Ö™kh}ÜÃYïÛ0±`%)#fkFñ°ºÁ•/¸rùÛJˆëÑÚ(žO9§ÕÕ®VG4¶ç¥>â2;¨Áštå¦}¾BÆÄ¹è’b»xÅÞ·Õ¦ìŒk¢h€DQ@2Þàu¾t×OÐQj¦£u‚lÑ™ƒ¥³.(ûޏåÀ­-³¦¨Ju˜º»xU#€QJÞã/ÝA á¬Ô÷ t¢à÷[ ~0c‘Á1„B‹" ‰‚@U»¤ÕûqÈ)fDpÔÍ^tÅ,ôÃé)– <¬œ̲å-+VR ;L\¸’h;DÀÏŽÊIíQ’™b½P4U<ît©k¶òc°z€„EIM)Å„Î-òy<¡b0ÏœgÁIŽSË/?œ[V7rL.eÉãë¿É.yu8P`ÝÛ·o´!<»]|yÇÇ><ð(Kz:^Ãõxïï’æàqCÙé‘3£·ÒsLñ(½ÁØ/ÙhøO7r›‘Ê ½ yÌÉüÀ×"¾‡ŠoÜŒ¸`äIIPÊÓŒëeó^–m ¶d‚ Gå…ØëóBì‘«1<φQ,E,§Ãøô–€Úœ"e÷'²yÆs„û“ !œ„58mÅRÇ!¾Ï0Ù*7ÆôωÈãÅ  }zë.3úîX^J¶ë†HH¾Û‹°²úPÀëu<4c̤ŒÎöé¥í泡8‡ÑV.°ÝfâÁ*ÖÈ]0„'Ì5KÂ5Ëàiþÿª’ªiôäË{‘7ô.c¶W¢K~—}¹˜gü'Õ,Ê#´´ÕÞ&€§X× /Åñ|[Ê`zñ‹œL> -ˆS­a+ -p€ÒÂnÓ6MUâ9qÄ  ÛºœRáXU’-Oí“,Nd¡‚ø ÌmŽW¬ô¼KÎ*÷­é -=É챑0*e]òý¦–ÎüéÄKwk8ýJ*¢­`ØhÒhQá“.máÖ»º&i£ÄYÎ(ÞŸwY©·H¿ë²²LzÑ)ð¡ŽyRPæ¨8Ó¤0¦%w…’óDΣò!†hä—k@g¤y’ãGfs¶‡†ãìžUéÛêÙ·%§áIמáÄHUHC¹°ÛŠÇ’ü8¥°x]8 Á°"ý™QP'K~¯éF!”Q!%“ˆ\Ð|bfâ7Ý8—úAǼn']ðIOB¼ƒÂ„š%¹Pì3fEþˆ½ yL˜Nt´ˆ=r©±•)½Ðªò„2žÐ”vGÒíà6 òV‘é3iùÈzŠñ˜Iⵦú^t®æÎêÝŒÏ^Íþ "öSoôìSÝy‹É×K•ÖÁ Ò~¢ Àˆÿ|_ØŠ^Œúûœ×Õ‘¡­Â†Tzq!rϨk4žµ“\džŸLùÊí ÛË¡n]ÎZ7œ0ö†0ÔBÀCPKû -‹ÒÑB߈ªa'pmPpùÛùŠ!nQ¾Å4i€ÎTkžo·±  UYhcKðÔX›¦.6ÖËÉ© —®Ú–e—äž(Ó(:û‹ÝŸŸÆµlPóJÖ§•‰Wñ¹*oºØz>EGÄkWPpÛ°Â%[ñ!Üeœti'ƒÏ4Œ(Ê~éuq¿/(õïy:N£ÄB•˜‘&¾3€­«] …ú'Ô¤Š(î &œŒ &Ä\ßAmó†á_uóéê³Lè+W´tþùöãÍZpMý(‹¥l¯äÖo„U@ W"]´½(`½•a xpnÒ«xÒ3Ps¡'¥nådj°p@{à²áƒ±ºŒÒE8l¯‘3<Ž”á@åÄrÓåÜ\åÝÑFÖ¥HÅÐ ƒÁg¸¬W3µÄmc¢’µ¼šþDf P*¨~'ÝýÖölù@ Ýø“Œ”¦…¦-HU…~üqc2ÌlxÃVû4÷½bÑ­( U»Ò5¦²_8j*¸ÉÆ~ó©õQo L¥?ÚÕ½~ýš›¹õÍçÏ_²ŸŸI±rjG¨*±AQA }â2Ð<ž4C–pà¹æ§¿éQm‚Lm@Ñ ÇЦ ÌŸúö† û ;vZ㜉Ó;èš @rÔ:kíFÎÃÐ}Hˆ³ºÍ$Ó¦ o4mÏÆã–C8Lxð#súÎõúò,q]1îGáGøšÇ\-C@ÚO öë /®çCpñˆIñÁÜnnöÖA± -.ì— üÄ¿×d#œÈštD#Ô2Wå`'ä±Í|?]¸^ -æL¡~L¤ öGDïn_ýÒã -endstream -endobj -1206 0 obj << -/Type /Page -/Contents 1207 0 R -/Resources 1205 0 R -/MediaBox [0 0 612 792] -/Parent 1203 0 R -/Annots [ 1204 0 R ] ->> endobj -1204 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [504.134 273.345 534.354 285.3] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.1.1.1) >> ->> endobj -1208 0 obj << -/D [1206 0 R /XYZ 72 720 null] ->> endobj -146 0 obj << -/D [1206 0 R /XYZ 72 667.56 null] ->> endobj -150 0 obj << -/D [1206 0 R /XYZ 72 317.734 null] ->> endobj -1205 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1213 0 obj << -/Length 2266 -/Filter /FlateDecode ->> -stream -xÚ­ËvÛ¶rï¯`V¥R‹"AR¤ºsr“ßS'm¬öœÖÍ’ ‰'|¨$_÷ë;/P¤L7Í­7"0Ìóä;;Çw¾¿ðŸø¾Z^ÌÞ†¾³ðs5w–['QNøž&Îrãܹ/_¾œLc»?—z•·«ƒ)yt·ÍrSêÂxíÃáãäãò¿³·i¬ïLUꥋ€©^¿»]NÒнúáýídÆ©»žLW—“À-«A 7. -VtkPÕò=ÐòÆ­í^Ö›‡¦5÷ƒ(øÃ°«£ Éæu†(fã¡û6«›öPæ1n޵ìm÷ºµ#ó˜tÖð—‘z²lÌVóO•oǬ<©¡æ,Ir’„¡›:ûŒòšÙ±1‚y:‰¬*Aà( -Üë-¯”ƒÉ^ãŒ÷÷˜¤C&±ˆ Ë.\WhƒLP2G›?ðÊêØ2z»'…dêÚê!ê&kÚ”ªV­ÎJFÕŒ¶­M³œÇœÏc öÈ+ŒÜ -õ -C«Wͳδ€ÑÉ p]nxÐÖ²_‡|yû™«Ÿùdçé¯uùMËÃm†ô øúÇÙ«ÿ¼¿½ºF—E¤¦)t-ˆyÅfjxúâÅ‹§£A1ç%ZC̓αk Pîf5Ws'Uâ©àÑ¢%q¿§ãBÄÓ¦ ;.Ânxã à ÇZøtZà ´½éóG§ƒ(¹nؤPcâÁý>[#Ê~,PŒÈ8Ôq`þ§×äm8Qüù”åÕŠ£5‚ŸWåî’%Ñ A“ðèĦÏ"ôâÂ=A+2KÕîáæñœbá8*LÓèSVĪº¦èð9ƒ`œ5eS§¤ã‡6éøƒ(ðOfÅ•. -`¼× 8w&Kl(E|£ s]!B©ãD\h·Yž3Âßd]!y2a zŠ&ƒD"²A¶Mv¥D*Çu$©C7oM]‚§wœþÔê<§bü´{N>1æjÌÆnáï­$-À¢ðà €8¾Sï|øþ¹#¡xj$h!ÄÒö7CÚ=ÞqV„.4Ö-Ë:Ld¼Î ¡VõW%)Iß~ËiåíÉÃ_̺Eæ8ÞTFòy -Ý®÷6±åëcÞÏN@îKÉé¬T'¡»­Ž”u“ 62Öí™óŠ­‰(±–G °Î‹Œ`4‰'P$V¼÷æ=rú^ÿx3m'Pl¤öIbY‡RN®žD=WOÐ">҈Ϣ+O£`Îã`v…_(kvL„ÝïŒêcY’œ8éŸ×%ƒ:æ8)´;¤·²‚ã¤Å”ð „j²pƒ­ Û -× ^ÔÂÙä½BÈ0€Âßm5–VM•[ ¿îì¢(vAȵe•uv<ï© ÀÛ^íeJ÷¤2sÀGEÑÕë3·Èìêÿ ˆ~Õî|þT¶s³CÄácK3Ï_e‚}£_Ù°ªX¹÷xè˜wUºGiŽqŒvC„AûŠ šáŸ'1ô9ú NÁ„ýîŽQW(®úÀƒn1¼xBEVéhð8*RŽ -ò Äèº<— uA6Ò˜1›”NΊhõLÜB²2¹K°pßUå´×DÀ¾zd_j£I°P Ãu-¢UêîL ­Pθ|A8Úª)0(dS&t(óˆLW "[Uõ§ Ôn]Súz¢+ÁÞ ˆ +³§ÐP §:€^ 7ör^·Ç•IFuŸ¯Šôš”pÝ,²Ql”íï~ìÏ®à7à9Ù"1¤û.E“ýhM¾Äü@…^øúXœN§£½óðrèy ­¡;i.Tè×ÙÝ»¬‚¾ûbPRߦذr½6…á2ÄÀ®´Ð8ö±5…£½d7Ž8¢2…hìåDa6r9èZ’ ŽW6¼p’³0ØéF¹Ý7¶¡K»†.µÙÝ=ZÄ®ÜöR¾ÓŒX­íÁÔ”[ÛwÔзµÿ*‡¾á¢ÃL²¤÷áÍrÍÉþ¤Ú4~Ýw¹7ÔPd 'ɹÚkUnOÊÇÖZ}Ù®0¥í'p(G½>‚ÂmŽ5_˜`ÌéV`•úƒ›U%$±#Åï0èh¥ò]:Z~û €SÅ™–_Æ/ÐæÇf´ï8y”’®IEîM¶®«ÛjÛ2øqNE$HƒÐçÉËÀ;°Ë†±_W&Ë‚xµÙÙ ixg%¼ÂþŒ[„‹7Ë‹?¤œp‘zAš:*LF¥)¦Oq¢´Y:ÚØ”ß~Ÿ’^"5!Ô›ÁwWM5ŸÉéòŒ°<_bƒœå'Êͪ»P²[ ´»lG îͥqì+?Jy¶¢›"쾇šH„n'”£G’1ꈟ´¤o€Y§Ž|·÷l„ Ô‰"¼Ûˆê£x _ò#JÔÕ2âm0¡§O˜Ô¦Á'cÂ!êS“3ÇÃ>sHþNo|´SžI"û”ñ+!R;Ô]!dÀ©ºŒW±Å\ÊË%?‘u¡aA qQóg >^à3^î,kdþõ¹ü¥ä4ÑVvXoöÕ1—ý¥ùL*ÜÄßÖGAåFWØyÔ=­p…‡¥ßnÁÖÞ'û)‰~=L\¹³’¥àÛ=Ò››> ¦¹» ½ø“ z~C|®N ÿdé¯ïžê¿z úÁ­Ôr-äÂl ÷º0ì€$ýþ"˜q -endstream -endobj -1212 0 obj << -/Type /Page -/Contents 1213 0 R -/Resources 1211 0 R -/MediaBox [0 0 612 792] -/Parent 1203 0 R -/Annots [ 1209 0 R 1210 0 R ] ->> endobj -1209 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [336.924 560.653 359.395 571.501] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.2) >> ->> endobj -1210 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [372.9 560.653 395.371 571.501] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.4) >> ->> endobj -1214 0 obj << -/D [1212 0 R /XYZ 72 720 null] ->> endobj -1211 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1219 0 obj << -/Length 2027 -/Filter /FlateDecode ->> -stream -xÚ­XK“Û¸¾ûW¨rYʵ¢ù(29¤ì±½™ÔìLjF‡x¼>`DHB™"T 4cýûô %˵ÙM.B£Ñl _JFëQ2úåU"ã»Å«7ËQWEVŒ«Ñ<ÍÓ$NòùhQ>G×·‹q™GooîÆ“<Ï£¥Ý75“­õHL#»O²y¤[žúfùe¤—æ·$jùÌ鯩¼zjD%'Óé,úÐv{' ~£N#ÔÿeñÏÞü0¾ù˜''$#8]\Ì2öÁëׯǓY§rÎ:&Vµi×<ù+ŸW¦Ñ­ÚêØv_p£Sßž©ýÞµµöC“Ä›šwEÖˆ]œ÷gƒmZÜòg]g™FîÀZœ^BLAþ ›äÇ †¯þ?Ž4-1Å -)ôâ‰_ÛöǾÌYó[Ð’UEðUVÍ£<¾ê˜¿²û¶fÒ´¼®xú½gXh·÷L²¹¢sc‚„ò^owžÜƒsoƒ¾]£–"O>CîÕÕ¿0Ô?óìÝ{Œ8Rá°ï®‡Ãg7¶íÐn45Mãj6cSí -â•¥¡Ϭ„Ý)>òºCg„ðΓHLÓñ¨pÈ"Éœ4ú„ª‰\š­jXjɾ©Y -?,qç le‰èì:Óy–3²ywŽÞ•se}º"½TûN‹ b9 -f|ÉW¶Åm½ZÒnå‰3æQ §pæiï­ãe³â…@Ùj¬dot³Á–9Nw¶y–—TŠÈ–ôB–•~Ã}Êf!÷Åø sÆ–½7Eˆ7+ƒÁAý{·ºëÔúOÕÜd2á*ZŒž˜jG<ÑßÀm¤KšÌ’èîY»g¼Hùö7Xûôæóí Ò¿ÿn].4ªY_EHa&ÞÒmÔõ-&߸k‹$£gÈê À €JÀˆ"«¢ëU¿á¼ßPsêh'Kóé§¿0½ÑNC‰NÓäœqwÓ4¢Á©.œì»¯ÓÏÆî»pcîÆ”|ë‚ÉK8ºÔVÌZAÞm†(+°6™1–F|#ºéº wæÑ0X¹ضÃëòä²lCí¿ uý°~ky|oàþ€â“ÄzØ RêØÿƒwåCƒ‘)¸Žê@Эݯ7L×ÇíqÚñöH®Àb‹c§‚ϸ`÷žéàyâ·<ö‚Ç®ƒwê¾b®Ueô Ûú¿TŠ!ÁQ]Jïí¬åhr¤j7ϘE’O»¸ºƒEÇÈ­¡)€Ùú¬ãÝÑݼÀðÔ§tµ—'M쵤ēæI³ãR¼Å¨é“Dãë@µk}¶+z‡)sÞלìý‡r/ÿqK8Ñ÷f˜g± `HHµV¡í`Ori£EýàI_òûùJZäºq2öÝ^5ÍW Ö÷±•³[¦ÐD`¸¿ò oÅ¥E²µb’"‹½[œF³ÈðW\lÉq{ -fƒƒp]…¨ÊÎû‘ϰJ}!ëÓƒ` í% f/fgn̳¸Ì*ÖÇiœ¾.¤ë¶óà<îG¡U}| .*–têöñêî×ËÑ™Å`FˆŽj¿bg8ãbÌfsþò'aª'ÓÀÇ%6”j¬ª™sÞpá*7\¼ÞéõV<"Jë YRH/8Ç>éhJ‰Y¨ŽÍBfoÖ¹ó©÷HgÑÚ…U¾!܃"6Û]#QF*Kˆ8ŽúŸ4\h()ð´á@.$~¼¿á%ØïOØ -ñF¾¦cR£û7ZÄÿøðo^áôÆÏpc†h`czL­7V¶†œúÒ?~ÛºpRßŠŽ…Øü&• ®Ž¹!N¡ÎR.ëïðg”Mã*™ŸÖ7é‹%(ß‚ÆUq™…oÞÝ“á“Kú$¹výp´¬€¦¡í¸ÁÅòÀ4aA†/ Ì'rÌÑÂ)ÂÕ4.aÄÀ>XESoÉpEÚ(¸}<ù˜ý„ç÷fž5¸Û…à ?/ù……ãÑnš†*-BûRÇh‘d|É«t0xÃT•„Äj½R€•<ákÐuìªRRGDè›5`*xlÁ¯\wÃÃ|x.éi*O–4ä‡,êòõxOª‘Åop¤z\ÅÉ¿Ûø×3o¿ã‘Áš>ay„B fÐ1Ú'x~Xˆ{œÐ ‡{† `EÝž±iàyÉ—^;~XNrh@œ–IºŒ´ŠÈõ¼‚NáÔJ}þÆ´„¤±rk;ÏËZu†òÛ›%µQˆeSè°k^ìû—_ÞÖSÄ¿«»Û׿È&­èýàV6ÚöO© FQ@€ã¼rCCýOcT€d–tZ€æº> endobj -1215 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [265.22 141.24 284.924 153.196] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -1220 0 obj << -/D [1218 0 R /XYZ 72 720 null] ->> endobj -154 0 obj << -/D [1218 0 R /XYZ 72 335.947 null] ->> endobj -1217 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1224 0 obj << -/Length 2369 -/Filter /FlateDecode ->> -stream -xÚ•X[sÛ¶~÷¯PÎÃ)u&fH‚Å“'Û²SgìÈc)3ŽÛ>Ð,a‹JBUÜ_ß½¢¦>ØZ,–‹ÝÅâÛ‚Áz >œ?ø=_œ¼»RÁ õÓq4,žI4HÂÀT2X¬¿x·7³³éðt¼O³[þÞuw¶ð¾|þ¶øøîjÒQ N£‰ÆcְؘfxG‰—­VB5U¡™ZVCöV2´ÿÒ -HŽ=»É¬|µÛ’°®ÿ0Us›[Ñ_®˜¸ÈYërÿ¾2oZ›?†ô±|¸ßšßðp“áDOly0Ð%ó*[iYÀ”( Æ‚óèoúéhÄþ’é?á"iä}†ßÖäÑ­.ªú…é³ZãTæOÓ(ä¯î†åá?- .³;›*ð× óélÎdUóüã´eØ]®ÅS²Ýhf€ÞºÏƒBÌŒÆÓZgLáÖDã±÷\å^P½g¾˜$š"b}ßð¯±ü[TfØ ™ZíjS®ùËæ¥±—‚ÇË!mM9 ½5ñ›·èVàmkVdhOP”ó„,E‘ yYv©ÇYvPM"o‹pÐÐ2䔕E"lÍ@pܘ?5¢Ò˜“y¼>~Fë#‹¢@Ú¶-'”¬Ö]*tKEœ³íR‘÷k0 -´¿†4MRïl¬«‚§$ò´x%,Œ<|úÌ_lPÝ¢Öu}ÜÉT—s±Ë¹(sS˜2³´E©‹(¥¦p§’ð[ïJ$ÆÞÍtt}ËÃýF—,ñ‚&T;à)b*s÷LTîpg–Ó”ÐéÁ”(Xfoì†g zöãÕh žRÞ\/Qƒ…¨™ªDñ“>õzÀÄý‡“Á/ {ÊHÀa#±¤{ͺ Hkì&â€Ç׈pÂèªÈOâMS~è+°'ÞuÙØ,ÏÉSÁo÷R‰“H}Ôöfzß°#_ë=¯ÍjMŒ½[c9[už -Oô gbaMç1JI‚1ûˆÄ#FëâDDºÈà- Šž†À>"ÌìoaUgµÉE7o8)¼ -(ˆ%x$§ÄõlíãÅÝ=Gž`¢€ã‘·À ®x‚² Zì­H›b‹æàÞiFn¾ïêá«bè*™Ô— -#CÒï?Þßücý{œ_Ì>]]€õC@Pò0Ù–Î Rm¸qÀá&Šë¥eÚeÕÖBª7G«)Ùb}÷ÅòUµ$“Õ£¬&\Æ{6¥ƒcÑdÄ8AB/WÊ‘™ñÏg¹UÙì)—éÆp W¦ù*‰ÆcXFÎõ§9íùÙÍlþžWÐØèkC:‚‘\VEA1@™3~׈}lŒXÐf¡22×àÈhWz|ï `•Íj˼àJÕ®æ±ÝY²NÊÓMåoÈGÙʧp žûTpæã›-þÃcé Ø¢¾26avCŒÝê°H¾qÜb :•BòJº*%-]QÈn¢:pÝ–ÞhÂ瘔nD;µ\ü(ñ]qYS×`©äÆݵ¹ÇE\þ¨ú|^Ë,,ÐØÒ†ã9ÜŽýDÅ·#Dm@-z~Røjÿ°¡† -Çù -Ä•¡â ”¼\!)8Ÿ¹Âò· >+—R’¥IäAû€ÕVìŒk3ãPý•«ÈqsÁ ÑŠÃèXÝÞä9SrOЬ¿8~³‘ž¢býR3¾ÓÍ7g 8†Ò»ÀNdüÄC- å÷mË¢EÏ8î<ŸÈƒI, ÇåÀk#vfˆ`ªÙmÝåÔRu‹UÛ5Ðtƒó¾$x#@)8¡à^!¶X±3ãáÞ¬t.zk½¬Ö¥ùS¯ú¼cËUVc?£Fr Wc¸¿»e–ó¹]ïàL&£Ð›kÞéO"Å*Žƒ‚Š/x 3¸½Ù®=Ú2»m¯€¹ØôvE¯-Á.%¢ðM!ßýïŽÞWëg¾¹‚Äœû zÞË[1ò^6Ò’1Ã4î™M‹¿ÇŶuÇ'eü¶OqŠLwÑáá®± I–¥@õÞs¹šÐ£UtOEªM@ ±Ô¬˜|óæ Ü.ÿëOqQyÔå)é€â¨á‘ 7OדžòãÌá½D;yM#±èç>,¿¦iví¤ÃÖ*pŸTÇïƒ(Jý LhR2™¢Ž„.'ñïE\ -endstream -endobj -1223 0 obj << -/Type /Page -/Contents 1224 0 R -/Resources 1222 0 R -/MediaBox [0 0 612 792] -/Parent 1203 0 R -/Annots [ 1216 0 R 1221 0 R ] ->> endobj -1216 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [125.854 618.628 140.576 630.584] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.2) >> ->> endobj -1221 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.873 376.208 125.577 388.163] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -1225 0 obj << -/D [1223 0 R /XYZ 72 720 null] ->> endobj -158 0 obj << -/D [1223 0 R /XYZ 72 605.812 null] ->> endobj -162 0 obj << -/D [1223 0 R /XYZ 72 363.392 null] ->> endobj -1226 0 obj << -/D [1223 0 R /XYZ 72 295.343 null] ->> endobj -1227 0 obj << -/D [1223 0 R /XYZ 72 275.716 null] ->> endobj -166 0 obj << -/D [1223 0 R /XYZ 72 195.993 null] ->> endobj -1222 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1233 0 obj << -/Length 2766 -/Filter /FlateDecode ->> -stream -xÚ­YKsÛ8¾ûW¨æ2TULó)‘Ù“c9SÞØ±7RI&µE‹°Å2E*|Œ×ûë÷ktƒ"e:»ÞÊE  »Ñ3¹Ÿ8“?Žù¾[¼&±ϼÙdu7™{“¹ëØŽ?Ÿ¬ÒÉ7ëOÇ r5=ÜÈ:«TÒdeñ]?¶.“ºá«rzìEVš÷ºÏ“)³æØ:]¯U]Žo“)Vxâέ^Nvmk%»9¹âVšÕ´Œj™|WVÛ¤±§Ç³8¶.Šé÷Õß¡÷±ëÚq²†Išf"±ïûV³QÜX$´ˆk-§®Õ$[jî ×ÜR1Ö®*›RSÖeΤ¬æ¹u»Ûiʪ!é‰v+ -_Â$ˆÖV²]­+.·;˜ò6†¶Érªj»Ó"²c/f-Øþܵnò¶>nôf;cG¢§Ð§†"»¬¸gŠ–ß$¯Kn=f©ÊŸ¸Ív×3[Y¢¶&ÙMôܵyReÑZ|Ù}Ö$9w>©Z%ÕšØ6¿ËöCÑÇŽ¨E*ØC “­ŸêFmq²Aà˜%@Õ^gü˜x,Á>Fç[s]@ûS¥ÖMY=ñµî¦Rˆ û~x¿Gm³§ŸŽjG<g]ÔêG«Šµ¢ÀÜΩãQhÎ~棒˜ˆ{ÎDGGø´¼DÿÑfú$èȉpÛÅ`LÞ}_%[¨gݶÌû˜%2Ù¼(Ç´ã ÷çsë}¦ ƒ‡?·µø°O8Ÿ£HrEbdŽlURÜK“j¾î"̹Ñl2!=‹€ýdc5jv¶ -µòl›qÐêõj·P]g¬+¥‹%-,® -fo6Ì6›òºãÍ0ž&ÏÙÑï\í7õBpóÈéV¶²GMŸž’‘MIÇ–§² Z#¾¹ý¸á³ßpw«š$ñ±ƒ¬Û¬‘ÔöD^¦7Ð9M+[7£9és‘óQqO®é[«j[C%׺çÞ×Åâz)Tˆ–ä(:éS7ºHü5•#¥aøº”™±µÎÅÞ$ç§UÆ“*æÑv}«¶Ü%ˆÐQö½Mv ½Ž¥gj0½»¸^‚Ñ}3³Øc–SÊs«PÚ™ŸS(÷ª T¦˜ª2Š'I˜ÔyH=@oËÊ¥­&±Ù51O›äã1CN¸Ë–‰,Žy¦ ,Ö­8Á ë/{ýIÜbÔ[ò2IM1M¤ª Aƒj 9_ „1U$]Ùëlv?"F=nÅáïI%FÈß|]®¸‡ --+f…ÄöêÓ/¯?0‘]’ueý^pŠè •Ƭ(@Ä¿‡3„LV¶5ž¹¸÷R˜²b·)ƒG 1åAäsÍ@ Ê©Jé&¡ÕO8ÌÞ6ªú]¶Ú$UúHˆkmߺF%LÓð œcµÚÔ±«Ÿ -Ç3ÝÁ³×Š•3ãrN#½óÂ\mñØ@dX¨‚&6ó`¤V9j¼poÔáò„#QìÖΦe) 2W—UǪC®ÉDz)/O$bÉÎsÊÎÔMKɳÜ-J”9ÊÔ¹m^`Mè\11Y“ªu&×íš©ãP‹d«.«‹+nRøƒ,ÒQ0ÃþϬË2YP uq¥(aå|×ú2|ŒÁÀóW­4ào.ûÂÌHAM®öÆ31Ug @–ªiw²^¶•©|Ð3“ˆâ°ïÀ ›ÀÀ³¤ˆáARDÿ…4—¬›Œc³‘œöÊ\¥¥eØXh€ŒJùŽ[!ðgʽ[vAqlÆÏ-(­ÕpJ÷DÅu«“™|õ…‰)àT’gÿÖ·7}\‘µP*E*+£ô<á‘RûTàsb¸'·™y/£Ý¿…ô:) pHªTƒB¿—BÁ-EvÞÙ¹Ô|;…dž`”¯Í":Ë¥«Ä Þ|^-–öÙõwáÙ#º^|¼X-.> ÛÉ)ùþ>ÛFXwmsXÛ‚œ§1mg¾nGý炘î¯}…e‚¶¾7 ÷´EÇg‘Ü”~Œìo˜*Ø9ÁP¡Adaï&F|’L$›9"}]ê„o®yèŽb$W– -y² ßž -–'¦8åQäFwÙ¡ŽÞÐq%}ƒP'[i‰·“l¢Qžã1£†ªZ¢Tʸ®9ƒJO<…ÕUœ±„Á÷l*ƒ¹õxðæ Ûû=`v"‚hw Åç·ðÀÔ“ÞÃK-óU½®2ÉtØ‚È2q«¥ÄÙ?“€Öóó7Éàyµoó=yï;Fv{ÃÂ:® 1ºýkR¸¯¬ètÈä:»/¸ÅP³ô!?§p›»R‹A C¶ --¤*~OåÖ‚¡­âD@›±F[ñ{‘ køû@yƒa]-’ðóW(=ø¦%E[W^àË#îK»ï«nVÿf>ÿWS%ô¢z!ùÔú›|ÜÔêjua~ûòýä#cL"½åÏ?_>(¯PT,Ô]ÒæÚå<¾¾iŠ"_Þµ£™¿ËÆ–™þWO&š±?]?ÐϪþíoõôØÇò7)Ϊ–ÿ¢ŠZu&Ó|œd$ºjnþh#€}œ*N¹ù¯)å©ÃX1 ¶Hûgrxn{ì-ëDòtïR¬Áõ“ä‚äŽbwZôm‘êì‰æiú×4¤÷ɵÙçb˜ä@Ñ©@ñc‘‘OÑí7¤.G€IrZeAÆÃîÚŒujž¹âÇþlÀ¨óVüÈ -endstream -endobj -1232 0 obj << -/Type /Page -/Contents 1233 0 R -/Resources 1231 0 R -/MediaBox [0 0 612 792] -/Parent 1203 0 R -/Annots [ 1228 0 R 1229 0 R 1230 0 R ] ->> endobj -1228 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [386.765 408.667 409.236 420.623] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.1) >> ->> endobj -1229 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [247.37 311.344 269.842 322.192] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1230 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [163.136 113.634 177.859 124.482] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.4) >> ->> endobj -1234 0 obj << -/D [1232 0 R /XYZ 72 720 null] ->> endobj -170 0 obj << -/D [1232 0 R /XYZ 72 298.399 null] ->> endobj -1231 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1239 0 obj << -/Length 1891 -/Filter /FlateDecode ->> -stream -xÚXÝsÛ6 Ï_¡Û“|+"©ÏìöÐ&i›niºØ½Þ­í퉎u‘%WÍòß Ùr”®ë‹E‚?|Юug¹Öë#÷™ïËåÑÉ+åZ±2°–++”V(\ÇU¡µÌ¬OöEÙêz6÷¥oŸUzOÃó:ÿÖ“ºÐi›W%MOéó÷ìËòíÉ«hO´kÍeäD± É/f2²ÛÙ\žݮóGž½Á&»ÊK³z<›{µqRu´w“àì‘&9œX"¥Eed¤¸íž–2Чz6vM´Û=1šŽÓu^Þ„z·Áß[#U×´”+\ë¦a6ß¾¹X~¸yçÐÒ媿& -4ÒB”fBËáľO–I«„²%Ê -£”ÝVô­J”¦<»Zñ‚¼Eh·u®›c¢,/˳?®§YQ%$ÌÛñ –©iN÷‚YÞl 25+é&­óm;˜·å媪7 úßÁ»<ØÅòèë‘€¡k Kø¾#ci^ì)¬tsôé‹ke°VpTYfëÆR®p<À¸°GñE~¤`Gô=!®øŽïz,cþ·DèHá{R ‘/¬@yŽ€`0ù8®g¿¸ywùîõS\Ï…« Ï\‚A!ÃsnÜ%Áç®Zë¶ ¢|ÃÃa? .sØÙ®igWÞ—nx(‰@¨Õ¡}OþvÓó•)Ž4QÙ¡½(€h–§mr[è)¸Öº¢Q š&% 8ˆÒ®þä¸!AW -4- ³d“Üð–}Ö¹ ¾õHŽ š|ÊÝiÓm™RóîžÝ<6­Þ±Ö_»œ£¦]ó\ŒÀeuKk·]Ûö¨¡ÔóMü{Št”!EünPs²ïGŽZ¯f¤XÄ€©d³-ô1ÚVÚùЍž /¦U³«Op:#ªç'·Âà*Oëê*ïa‰¤ÅK¹è"׸ëNê–WÒþB{Æé–Õ„®ªÖáÜ‹*í2ÆXÇf͈?L$…J GE’K -Ç)ë‹õ‡t5¡‚„0“PÍ>åô•híååõ‚F뜦¦øMÀò³ë»;®oô‘Ž˜K'<¦ÙÛJÓàcß­Û“7IÁ§Uºâùb)\®˜Z×m’—<Ùß$)÷?ìÁèÐ †8Î’,ËÑú¨…èH {Y|îy®}Éâ¹2Ãh4< !b¦W $ž$­&‘«^Õ¦+vÛ)Ãå\VJ­3ýÏŒ²4º¡!ÁY4Bwœ“R¿¹â1.$hßí“(šRf'jS•˜„Ÿ•µ×ã¸ñ÷EeÉã÷”òÃA’øoXB‰Ììa¨äEA´!µâDv…ž¬/Ôfïr€Y6Á‰ƒ!ž#›sñA÷„¬JÓYW°¬^8Ç«æÄîBgرù‚Ú¤Ýòµƒ#}MF6šUþɾ¨ƒ¾hW6U8Èå9UNhyγë+nf¸Û¡Î…ÏÌhÍÄ|ܼ"ü(y×w n^YŸŒÏ Fø4dµW]z0oÓƒuIá 7ˆœXÆÜH(ØIQÐàÛÌÇÄ'Íׯ`C‹Ö»çÜKåÇmûÁÀ -GzÀUãîi>w~؃bÈ«ˆÚÕ§\{4в’EÏH‚r>­4mòU›-ä’gÚ r• lëChëkš!W×2%$ƒÔmbj¹ CF;w½ ÍÑϸcgCm¡=ض¼ÖVDÍtk^ Hã3ÀÐÐ×yR¦š(ôž™® -ÇImh¡ÃŽ Mñ ¦›¸i‰- dõuRÞišSê–½¡K3K QHKö°¹(²<Ã#ÙÑØMæähÙÃ_`ÿ΋uM90 ”äN/ƒ¨þP.Í—fdÚëùiO^BãAÖL]/!È7]šjÓˆ6«´,(枀ã ù3‰þ=¾±(S&%çÔ{Ít,~¡l‡Âz/5*ñBôÕ-gÜ -áú&:{–3JÃh>ÈpOî4B¨òeÿ¼£I·¥ü †Ìh£N4ktZ•¼’ôƒ^œTÑ»ŽZ³ŽÏ7ÏAøŽ}æË³8gLä"¤Á¨#rÎ -ïžØ¨¼!ïû „JÑ"=Î"Ï>žŒì]߯b}?„®yÖú˜Ýa"`Ha_›ØÃEÎ -4Á -C/mj9€É€ŒÞ;-梪ä×·šxúËñöp¨ìétLÓ¼Pg´ kâ‚ühëáÓÿ ìÞÐÊÞÖ¬î«=⽩:ʆ—ƒ#§êÇáëpåAó ¤ñŸ8$®âcc=YQÍÀ“gh3|`Δ46‹ÌNLö€ñ¢…¼G[¯t»¦ÍÙt»â;*P'¦aí«{×—ÜœTà'À®z}J™Êà aÌ<¨ÚðæÛvÀ‘ñ¿)Yå™4Åþbùáý_‹e¯G ìØÿègRÔ yŸul!)cÇ…§ Þ̧¼Cÿ„µõ´ -endstream -endobj -1238 0 obj << -/Type /Page -/Contents 1239 0 R -/Resources 1237 0 R -/MediaBox [0 0 612 792] -/Parent 1241 0 R -/Annots [ 1235 0 R 1236 0 R ] ->> endobj -1235 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [298.263 357.919 312.986 366.83] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.6) >> ->> endobj -1236 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [237.38 195.583 259.851 206.431] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1240 0 obj << -/D [1238 0 R /XYZ 72 720 null] ->> endobj -174 0 obj << -/D [1238 0 R /XYZ 72 182.639 null] ->> endobj -1237 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F15 1136 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1248 0 obj << -/Length 2260 -/Filter /FlateDecode ->> -stream -xÚ­XKsÛ8¾çWè´EUY2 R””Ë–í<*»qìŠ45“d²[I(S„† Ç£ýõÛ/P”ÃlÆS{4€Я»¶ƒpðöE(íõòÅå›Ù`>ž§*,7ƒ©L£pÆÓÁr=ø,^/ºÿ¼XGq•v‡áHÍ[®“M½Ã^˜ZH¦4µÉ -ìu9„ ¯ÉÜËá×å?Úó}{ù&;·ˆ&ãt à¤ñ ZºI4MÔ$qóV—ºÊjÍ£ú‘;K³Ò¢ÎöîÞWv[e{<EÑx>™0SuÆôõÙÞ”úòÖ®ÍæèiÆÕ¦Ü>“ÊüyÂßÔÜ«-·¯î´mä_ܽÜë²Ö•œ¦ ׯ–<|ÉÍ¿qï¹þÂs¡½ÎâÀ“xYÉíI?4puV2¿Ž’pF—ëLÉfnÖæ×0ŠuÅZ­‘˜@ý#ZÆ4ÐL²Y:r(*¡°÷×yö1yaéˆ|ÂÍ‘dúdo,°x’Ñ$¦Á]K‹Q÷8e·Àh3ÒЬÌj[Qr85Á­y‹-‹#¯Îñ^»¬ÜjÙ~ÈÀ4(LÆFNÖ­ýÐ*6÷”±¿ÄZ»¼2+ò1½î³Xâ ~µ{@oŠ`Q8¨¶î||ûbð…Ü-'cø¹ð·Œg㹚{k#QëŠ/³.€IÄ£qÏÖmé¸JÇÑD‹óU íô~÷k8 ë=üG?F{…ÞÜn»¹¿¼•‰¢qÜËíþž¶*ô÷XÆg,?êlýÛ]0áçÊx8¼¶ˆÉ½ÛþÖ½kÏùÉwΧ ÿד&g'}~Õ -聆ùw "à&Ë5ƒä™ÅËovÖäú$“Ýœ°Ö‘”Ÿ‡˜ïÀž’8 -ŽhÕ¶áAViéˆäȃƑa·}=xÅT+­XF‡Ë  ° ¾#ŽN0 -,œ°ë†"l$“ôün±{.«lU ñò<…N˜ „ö¨€XYòáš Ÿ7EväÚ°NέdWSuñ9‚P_ï,Ý~Í+Vô ž$fŘ]thX Ix+Àë4š ^;žŒyŽAÆ áÙxÎïf-gt•+S˜º½„Â÷ -yþïCR>f: ƒi÷#Íh¼êÔƒ,9ÍY&¸tp]GŽ)zÞô„(\ºá”nK$‚_Àú¡;:t:²0Ëjnm™kŒné,¸ÖÒBßÈ-wÚTý‘$cv¥BTÍ]yIô‹T°ƒKZ¼"‹AÄ$“¶U°ˆ¹‹‹ášpSé߃NCÞ[îMAD{Œ´ÔwôsêÖ;JU`)ËHgçD<Ɇc´–$†èç|TìÁ›|g+‰#Ü Å8 º=g @Ù£9ÑX7…æùÇáˆÏÔC²i NOfœ<0³ueD^¼†<Z;\b6.`C©Á‰åÜóýÉÒ ´µìò€„³ÈÏõ÷Ýݧ½Å¦öL¼~G‚B”Ó²äO¤1¥êI’!éAÅl¾‘ & -‚t9æzIN(¡aozrµ¡dXÍÃüá`—¡i²˜Â!šug1mžfªHB?Á…˜©^Ö”@—SÒªæs_Ò—¼-sΟ'*” lߨû­äŸ5fô_îäP|qåúµäþJrôÞúHI®‘I­ðq!EÈJVÊ$²Šµ7÷?ÅÎO—_>|}N̔ïÈ/#^a¼û%#@ÈÕ{²* ˆ³‚ü^/–7ïïþy!t¦~âÞ∠-Õ‘HFk>œÖ”ÖOƒ&J÷ØúŒÉG`äòb`` šä,á·»K¦¯ªŒë š¬]Ë»/Ž’ZÁ¤×z“5E̓N±ì¡“(Âz,¡÷àÔêÖË<8«ÇÔä¼êæE,h+”›òކO(uíä¸å…ôì)Ní±yÿjùîv|sw+l[”ëydF¡gÖͦó³ç+Û@”×<@*eÓ$„΃-dåÝïYA0€¢šC;g)Ú€?UzÝäí1Âe¯¡ðpn -O “V `ó?@ÑïTv^˜rlyO&,–ÄS>”øÜÔRÍî*ÂLêÚÆI–’Ȧšt’ª$øyg -Y˜[WG_Ëf]Q„‡.×ÐÉ)J »¯ÒI·Hëæ]=/”ØKhÈ“{%«¤Ðë­ffcØvA3ÆÒ¶æfìyŒ·‡–¸àŒ¹ê̆©Ô%/]ózÎWé4Ÿ-ÓwžCÙÉaÝ»¯¼G¥Qϧ‚0Ùü‡ò˜ç ‡ÒŸ¨Ô‡œhö) íÀFfCIÚ"L^päNåIHã/_@is(£éÝ)f> hSç7eû­Jh˜ƒTå¶ôßßHümEþÄAñ£œ˜ ä7²×ç;³ÝùwbumŸÀcDN@ïð±<Ã,´/n;×ìù`…°Ki«Ré™?€fHi@ȸùÄk½¯²t.øRçë$¬.[ˆQTì¤ÕU5̰ä”ÐñÉI&õ,"ß뮑xv{¿¿BnW8\öùÆöBÿµ î¯Ðý²±Xò©WKo?°÷å:|ù®ž>§À%‰ -°vE>ØÏ³ª2ÙVF•®›ªÄ><_…còIÖ8B‹ÀVDgx¸JÕ‹ú%FsÆóßù+t‹I$Ð ŸŒ@™zèpØiÓâqŸ(Ry K(ϸ5‡ŒÙYž¢rÊõ’Ižaþ”"â°Ð5×^> endobj -1242 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [117.496 591.482 147.716 600.282] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.3.4) >> ->> endobj -1243 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [214.936 380.772 237.408 392.727] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.4.2) >> ->> endobj -1244 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [526.274 232.882 540.996 243.73] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.4) >> ->> endobj -1249 0 obj << -/D [1247 0 R /XYZ 72 720 null] ->> endobj -1246 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1254 0 obj << -/Length 2374 -/Filter /FlateDecode ->> -stream -xÚYísÛ6ÿž¿Âßå.Qôf½ìvÛ¥n²vKÒ\í]×v½ç‹¶y‘¥Œ”šäùë€eÙQwݾX$’ üÐÁd= &¿ßø¾Z]ÆÁ¤ð‹4J'‹Õ$‹&YøAœMåä³çûO­ËVÕëãÓi4õVª’†›ºÙRk¾8¿¾û¯Ï¾üeñ+¬~Å~Ò*¼ñΪfy¸À•ºÓB?SçÏ`|þøåì!‘~ Ïqñ³Ë| 1î”û±øü8Ê=Ø)¯Ý(C­‡c`òUÛÑ$æÞübñûí§ù‚X6‚y—ZŠV–¼Nx<Ž2¯a‚ÜâbÐ'y‘ög&V)Ø=hK-„­j˜°j45î:U•VŸØ»z½x{íÏÞ]ŸP_Ô¼5ÈΚ C¿˜Né|ZþÕIC×O>˪±G\¢¼÷D+µúŠ]©©ÿ¨Ú ·6Ê2r·mx‘fûPÉV2uÃݬµØúpAê]*mÚÓVmy´3RjšMÓU%µ%©Úí-l÷™÷A}nšŒ²½qbQ€¢¦~“ ðnx ¡¯t¶…c‚h/´´¡6•l¶Ô¨œb‡..% SovõnöØ7.p~œÇÞÂ'®…51\OKÓU­!²r2ÓØ–´Ñ±Yž9v†—Ÿ†^@íR‡ 󬺑F'ÀÖà>±‹ªÁ/ÑH‘ ršMÈáP,ì9ª*ùîÔRTû ZM%aè5µd¹”y¨Ý-Š^ùŽoÛ‹‹ùô÷ÚøØÁÑÛÏÈCe]ª'd: --˜èõ„ï9š|>ãØ»´ÃÁ˜¸æ»EáIÐçN+¹¢f‰.‚«P&;fœà}Øq)z§ˆGed¬÷¼BoCˆL Ï$™‚@9¬QUöÉ1cç>0©RÆ"4ˆÂܳ¬VwMÇA¸æ‡½SºïX@ßEmÝíc_ƒÌŽ<—•\ÒÁÿ¨¾E Ñ@NèlÄÎb‰R7í€OrGw55œ!œPW>)æg碂Ð^f +è¿EóoªÓ^à q´æ…-àwÃËÜ‘1­U]Ó}{Ãg˜³¾mdÀû‘í›[€1ãUoߦ@ø$0’e§)J€ïây4µAANLF·éa Nâì`ìQUÍÆ€±õÙ­Ž:”¯ÂmIÁ1$$Ô ^ æÈ‡q#NÜÆ`ÀÖ04»‰s,6MTŒ.XhŸ „¹_DÅÀÂòt`ayvha0l¸ƒC,­'KcV]U=Ó 4††]I&d# -tIø˜°1 6"Üâ/›ŽgýBœÁ= ¸ —E 툸Aì}ØH–l~q:¦W‡ -Q -î"—ͺVÿCK‰R‹cH–«â§¦¼éèøµP ¡ؤÃ<¤9A¨ËvC‡iÊð4 -¸ö€%‘(aëe Ü;oJç¥íF«¶•l.ÖwÈ Ù›f6Nºò>éÅgÆà¸(Ì׌¼÷öªZZ^Õm¥Û™Æî#‰a æ$ÖòAoêÒä«F”}ŽÌÀúãrÃ5ÛOÔô)Gþ[Äý`1Ñr…á€-ý<ÛrýørÌϒ¿ȃà”(ÈÈÂIî'q?ñ§— Ãýy¿ð¾Ñ™áö¡oÚ[Ø3Ñ ?t.ùðCD$Óv©Pæõ7ÓçO0‘âu2zº]„6Ö4Y>ÚáiQøaî{_ÝÃv’A´®mT†&#¨¦Þ‹|h[ DDªPVØÏ*Æ\å{LpI-4¹`@ Îy?›d\{j+³ŽÒ,„¶)!7ìY:À1˜Ü´}2de$«Þ_2uÜê±¶"L ~ª§R0éÒ[%9caÍ/;}ràE«ÃT(v"°•—ë ýo²œ+ÐAïhèu.¹¹nÊÁ§€òÈIö&/l ³›ºóÎï]af¹Ý÷&ÿ­‹_ZÌÚSV4µ‰O7kºå’òUqh^4j-`:õì"_ÃʤJqLŒÉÉýÈ@3áwîöqs°·ªM+ªÊ=-Å‘×Õ¥›só ËlÚªîOElRžÜQ7`C§nŒçƒäi9|{+ÅßQDÅXD%‡%§ksU/GaÁ¾õÀÅ‘êaë-]‚gKèÍ0ʸàd (+æ”’ÆEí>.ƒdµ¡y¬èKƒPmš¦âÉ30 R!tnû"Î˜ÆÆ¼¨–óÀbsóΰD.©Ã> µÈVÑJ6¨’ìKÓìö?†à–5i8 ÊR.Â{@"ß85–Ešµ<5X-=à¤Þ§Ùíû˜ÈöHv§Û³k"E>àkDmØŸ÷°–€Œœ”A¾½µh¾Ø­šz¯iYÀï²Ht_@|qW)³±H@<@/NÐ(åJ@B¯6VYÏ°Ë <÷J >n±:°V´=){zëäµ~9vHÂQ¯m೑,ÅŠ§úâ4ðJ6’ŽÖÖù(Œ¹ï3§„TÇjZÁ> endobj -1245 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [120.54 606.483 129.036 618.438] -/Subtype /Link -/A << /S /GoTo /D (appendix.F) >> ->> endobj -1250 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [496.636 550.363 519.108 561.211] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1251 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [496.387 187.067 511.11 197.915] -/Subtype /Link -/A << /S /GoTo /D (subsection.3.4) >> ->> endobj -1255 0 obj << -/D [1253 0 R /XYZ 72 720 null] ->> endobj -1252 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1258 0 obj << -/Length 2561 -/Filter /FlateDecode ->> -stream -xÚ­YYs·~ç¯Øè%³UâpîCq\e‹¢í”(1Z¦\ÑQ)päN8Çf°CŠöŸO_˜c¹´,—÷e€Ðènôñë-nÞâ‡#O¾ß_œe‹ÜÍ“ Y\^/Ò`‘úžë…éâ²X|pþ½ÌB§í—Ç¡9µZ©óÀ¦]™sØÑ vvºã®’ùÚ˜å±ï¨Í„öšÇû-÷w-÷#¿kä²QZ+3Ÿsµ<†AaT”f[‰4H-˜|¿AhöëÓ˟ιY -£vË:µÓ…»<ŽÂÌYõ77Úìʶ1ËO—ÿ›û¾›Ç1kÝ¢B)jöyÇ­²Yú 'hUõÐ*´LØØFYKK„S§Æu È]ô•‡(ÃZú94³|Â'z~T‰ØO¸Šè€Ñò1—;9zÝÏmËnÈ3d W!~ÑïÚZíʵª*‘ÍyóŽg°DÆ…ý -t½x¿º.æÖì¹®â¾ø?´ú¦ÐO¸µhaÙЇ>‡‡ó²>ß6â²¥¹ý#nù†DCÿÃФo¿ÛbÀ`ûº¬dôé¾V}%ô¿óç{ï…ä@?NcÇ}ùöüÓܧ¿è¨ßÔ)‡àÛm°>úvÜä¨3`í Ϧù•¬¬‘Ú[S"¥làð<Ñ8Ó©ƒ!ñ¾4›¿ñ¼hrŽ8ÀÎg¸S6²Ki ù8gˆôS'MX;vIªÕ±†;›ÒP}ˆ9<{ÎÐ ¤=†tŒäçu‰SÈ{ªªN«â;úsiÈb¡—Oý“æU,†™²Æ ìÉ‘GÉG€íNC \ë= i4ÇÀ¤¯´qðØ©°®¶}ǽéš!DB,Ä0êN`Œ)ÉÒ?s´ ÀN¬f5ue#e ­Rîyu4:˜.¸a0ðûÒ?œ(ñçÎîº+u7Cqc?”ȸDZ„þÜ®ûªSfàósÛÝrë ÂÕ¸î¸pîß|ÃÓVRe©­î¨ø^ì9?´m!B=HÜûíCøeÛÜÞé+Åç8ÊSçWü$ö˜¹³±^@u)ÿíÍŽç¯Á‡)cGñÇzÎ,°Š !µq’l[Ër`ÔÖå/–e` c?C2ã‹¿,sŒ»ÝA<6p¥Í®¶pÚ¬»Rܦ¢~&´³p¡a(‡>CvM¬|®+'gÁž5ÃÀõbá¸!¬ñá<¸ŠC½±H3‹œ Qûà©Än˜Ḋ–aNà—DÄFaó9vP6EÀ‘F§Í¦#êxݪSîkýŒ›Ã1`g8Eì\ ØÂ¶ $—»hzY]6ër‹…º}·%PךƒEŸÏÁ“béA"Ÿ`Ôæ F»EsS­¦~§ëvêyH›W¦œÎìqó“7Àad µ`ˆ±Âð÷ýêôíjÁ{´íé)˜ùíÊE’·žˆ3ûD‘:?–4´|£Q˜p_úh°?¹aYo«‡6cÌ6"ŒÐæ_Í·ùC˜—ÝöKùë_¥xÙ£ï¾ÂHûéIìD=‘þþh0ès£¿blŽf9À V4Õƒ]Ÿp”u(©ØÙvÚHi@$’ ™Wð¥ÄF«nôTê»e ²veÛ1ÓÐQøÙx‚ö.©µ¶·T~Z4…ÌOÿùöúçgÖ“lò -°Ør”=t¥× ~ýá - ­«¾¬ŠA’ã;+!î%r7 üÁbDéS›gLY«ÞP†¶ ÔdD©Ô³Æ{,I,È7™¼ÿ@gR6¤Ú{öÒ+»ÐºÑøZ•ô¥ëiØ€$”'¡ó]cî9!±hihLÀÂTðMûŒiCîÆñ+¶NG‹tD©- -°ºÒTYn™'o1ÁÔ(@~T\F>¡X쀒û‰ï—”¬[„‘­Qáäáà`,Œ¯pcY+ÊEP9+Ór«7ZH24=Ö||„óö•ÀøV¥ÙñlIjž-mÐâ÷Boò8ä{ã¡ñ2´æ¬-w'=—ÇHDP…0áÇÛͽʾ\ÐM&²ïM‘ðãvzÝÞ4 nùÚb û˜A8ÿp‘~uyô¿#6ö>>¶úYî¾_¬ë£Ÿ¼EtË ólqO³êEnЮ«£î­Oßÿ­õ0“uäåŸ|S7O3Äscûì{r&Å ¿€H˜ÜìäÖwÕ•úš)?êjkíèn7>Ú ^6¼’¬v˜•EçÃqqínƒŒÆ™áë5ž,‰Ü> endobj -1259 0 obj << -/D [1257 0 R /XYZ 72 720 null] ->> endobj -178 0 obj << -/D [1257 0 R /XYZ 72 435.367 null] ->> endobj -1256 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1263 0 obj << -/Length 2649 -/Filter /FlateDecode ->> -stream -xÚËr£Hò/(¢…)(^së»;¼3ýXK3±½sÀI„x(Ôýýæ«ÙxcwOdeeeeeå³ðã;¯|ù¾__]R'ó²8ˆõÖI'Q¾ç‡‰³.œïnèž^,•Š|÷kW>å]ÕìË0 Ý@»•y4<ܶàó¾\õùá †[V»ÿò#ÿëoë›jñÇúïצûúÎ2ˆ¼0y[¢„…qà>Ñ® å–¸n+ঢöéi¤î™É -‡eß—†Q¸% pÝîªM^óꢫ~­¶ ÷yWr#œ9›¾<’š|N é÷%c&F¦vz$îq‰+„íÖ -¦t]¢ðÜJyYñ¹ ²1Þb©“ÐýVõûöØÃÂn•aˆ’÷UÛ¼ELä6-ÏÌت‘DψMN@à>0c»rÓvEYÈæë}ùb;YÞ6¦2½™“ŸNi7/ -¶“(=Òˆ\›Š."ÒVDöæÍ›õݧ[¸è¿y7¨»w 0›µðhyÁÀK.¦ª†1GCLÞ•9ã|8Lä§îº:Ⱥ¼)„èÊ2˜ê¦ø†‘¸®™„åœ?1. -C‘,$]|MßveÁ³Õ@ng™·‡¼¿´ßÛõÕŸW -@ßQŽŠ"/È'}/Ngs¸úþ‡ï0 Rya–:'"=8¡¯<­b€kguõgLt¦*/Hÿ# ×™§€˜™øsÁCEŽJ¼@E½8ˆ#/”«ÈK !ßÊ×î»ûÏwŸ?¾tü¥òCZ³ @«*å5÷Ǧ! -bßQÛøÍùúFŒ=ºÏ«qÝEÃV…° n¾kw³Ë1|ªàÆg.y“ƒu_ø1cB[ǯðEÐòEذ#"xaaˆ C€¬Æ®ìLƒÄ}'ØSø0´f$wJ]æšXf)©,?ŽðˆÈ-£sÔ¾u‚({šDN“ާI'{$ãiÒéiÞΉÖQž8´÷†`ÛÔg„4 ˜‚3‚§}µA©öL±å,™ãÎXÙbë5öîx‹9a@'Œ’xBôjß—í܇—Ûçp8õ­•P4Ïý†š,ycåáPR,xbXÆÆ6{%Æ›©X1‹u÷ùn}swœƒŒUß-0é8Ëík€Ï‚&m÷ApH ‡:oLe3Ð4H -‡ÖQàžÝÞfOI£HŠ9Ï)ìÛ¤ -g~² L¾-ë3-N -Ôlê’2Ea@¶òå$Óö{ |Ä^2áe”5†Phƒ&gÂE½‘òÝßéR:Cž)åÏ`xEDÕlêc’"öT¡ˆ'gAàŸ«ÐÊ—žr2ÅÇæ‘„åe–ÄîM;'GÓ¢¿Båà@[x|Ù H2#“[þZ·ÅÑš¤ø²ò»Æ«!h¸ ”]nf‹Éœ”6SL›!¥ÍA¡’hȪ« -Ðü Wäš.g ‹Œ££Ø‹üìÿI/Ó2ñÓôI[³å)XµçGÙ¤<õ”-PÅï n¸kP|ö ³MÅ¢\~j©,-Ê—©H¥¡‚úÌš Lã F‹•Ä ˜8´dÅE9M÷àœ‰ÊÁ=&%æúþ‰®r)›Â>ÙeõDœ‘Ê Þß#ØãËŸ¡¢Å!$)¬‚;1§[+ÏÅŠdá”_0ˆ„3Ã2ºôvÞ[žz¥°Çð h<<«±"‹¸Õ–‰Î”|Žr4²=ާÑ'çŠâ˺1L/,~R(†Ù$„¤\4n,sÔŽ¸•õ/×PÏД<ÑïóžÑr:À‘Ó[®3 ÀOµ8+îUX{óoœÂzˆæÂ‹2"!›àå0¶csƒ -žQÄ‚"HÈÇݮĂ"(@£†£’‰áþ£åª7‘€ƒsÔæ3ðÜR÷®•v`Ëx(Phó–™Ìî›LrH”pâÉMUËØ”r‚IÚÇ¡ä01%'cJŒ\aÙÌ%Ó1™ÔVAÝ7Èá{·ešAZœ*³çh0ˆa±òfWò˜‹u„jàÙQ=!?"?ÜýzkmP¹ë{fv쫺êEHV”fÓUrÛ$^•ª1sàìv÷¯œïD¬½ð¢K˜m¾&½…FƒBŽlp¶ó ähRI™Á´“Øöš‡i¶ãpâ@- Éô2” Z>²:ñ`=5êA’½L`´Îä†ÉY×I6š!b‡2>á"ê‚íé-*;Ã@%70Uþý«ŒÒ1IÒ†è)$m~p"DSnJcòn¶n¢`{m;²ï4“Ž0ÈŒiª[òÍ UÒX®Cù±¶k^Ééé$ZÜ•«Ž<Œöy½e(Ìnð²‹í ”:å%¹¸EgI¡Ì…ÖõŒ÷1>Psä -• -®V—”%9¼šr<7pˆÎåûîÓ×{Üõ‹L ³Õ{•ú jÙw¶*#¢¢=>ÔåÒTTÖñ&t*u¡ Ô¿0–B ”|YrÆ‹çܧÇ0ªÏöµj¼žHO-‰7³NÓ÷°‚®bIùkÖß5&O[߸Ú»RÞÆ°•çógô<†:“ÒR§ö^ _  -ƱC]DáhÑ™-ŒÚ¤Î&õ€¶‘›X72¦ ‰[µ<ÎAµÜ@j2nÙ/¯kŠà'î°_°Î…?ÐAJÔxí¡2ž!(±õÒ¸6’Ñ=n‚goÕaà¥Ór/xÖ‚dʽý˾€÷Œ ÖCÍ·±öâHÛÞc2ÆZ -ãGM•@cõ zqA€_³‹z’ue#ÅдØ¶/mTÉwòK³ïš=«½‘VE„¼PäXâ†öÉoiî5óúCè?{òO½šŸ‹®:ƒëëùH­†î ŸJtF‘Š~O¹WC=Õ>aR5?-–I»Ë&àg7nl·…‘»üýAÎy^`e·ä ²0‡]Gµ­'hjË_°¿ñ#»ðË Ì,W"pË_*½ð6ÿëæ^ë„d«·…¶[&iâþÜ’ °à6¤›t®8Q‹¦H€ Ål5Ã'Š0H7:œp0´oˆ¡ãÀ~`xéH ,“œ ÉØØ7q|S‹íA­üÔÛô±†AGìê·÷Ÿî^¾tèáé‰%ß«8|„ö9rR͘²/Oößþg¬”tùlïAæù*s–qäZލÕÑíúêß -endstream -endobj -1262 0 obj << -/Type /Page -/Contents 1263 0 R -/Resources 1261 0 R -/MediaBox [0 0 612 792] -/Parent 1241 0 R -/Annots [ 1260 0 R ] ->> endobj -1260 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [526.274 394.331 540.996 405.179] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.3) >> ->> endobj -1264 0 obj << -/D [1262 0 R /XYZ 72 720 null] ->> endobj -182 0 obj << -/D [1262 0 R /XYZ 72 720 null] ->> endobj -186 0 obj << -/D [1262 0 R /XYZ 72 466.948 null] ->> endobj -190 0 obj << -/D [1262 0 R /XYZ 72 249.824 null] ->> endobj -1261 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F15 1136 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1267 0 obj << -/Length 1858 -/Filter /FlateDecode ->> -stream -xÚWKsÛ6¾ûW09´ÔLD ÁÇÑ;u×MÔé!É– ›cŠTI*¶ûë»/>d+©“—‹Åb±øöÃ"ôn¼Ðûõ$”ï/˓ӷ:óò Otâ-7^ª½T…A¥Þrí}ô£@f6WÊ„þUãv¶)ª›Ù<Ê"ÿÔ~ÑÞµü»©®ôùPŒýÝîdüShÂÅåby¾x¢š}^þvúvºtè͵ ¢$â•Å&'ÆßÑÒ3å;\=&±¿–Åaœ->ïf:ów³9|[| -U\²üm12ØJ0››(ó«×5ÌI}'n»ÛBÖºžú‘eˆ¥´+ι/¸škdtSï›îV†*êxÈø¬_õžf7­TÛÆ-ýŒK¦ È[u5MNaFcWmþï Z -ºbëDQ­Ùfm;QM#ßûÛb… -ñPˆOH3æéÁ­ÅìéíŽó³*lÉvc!¸Î5¬Â“¾uv f[°;²O­˜ü<ö/ж`5Ý6übà)^8ÁQQñ3(À“„ƒÌG^·EWÔbg7L¨–ím±éh¨®ŸøÃ 4mw¸üãW¯ÜƒX–õM±:¾Û–6fQ$gÅâ"BŸ­-‹)¢è0`ȳ[™ÞȬû¦è:Ú˜\[:†;¢Ñ -‚÷ˆk%À؆Úï¿Ë“Nˆ¡§'–¹ -#š3×p(*{Â/: õ¾„ôë$÷«ºcåuÏøƒä³¯X®å+„âªæ³pšˆdtôefŒ+~Ï¡‰Ùms )ÄRxd*cŠÂcW©ßÕJÔEǪÆÙ¦±Õ Õ觨a(} õG¹¿œ”/^Æk#õ[Ó.ÒÇÃG£1cGòtõ×òs™åü€0 (ð¥êéØÚ;–np•ÉоåÒ¡ÃY&yæŸ×ƒBpÍÑÓº/Úž% -:h8…‚ð L’|1€Þ’þ‘ÍÝÈħɴDˆB -9 ŒØ$ ó¨öç´ƒ>t’|ímaâ<‡X&L ¤‡» -¸Õ,Ò>Ü[py_PV‡Õ¢ýµ{N&*W°ÝÖgá²ï]H¿yÝÖtœëžä…¿å>qMOöדôwÔd@[¸¼9JÖ§o£ð€Ù$@l`òôÙŽvX»ß‹; X'C÷ Ë#7&©`աе[¤a“u3ìµ¥ƒ«©AöѰÏA/†ã~œÇ†¬Äºœ fO>gØtb[ô¡áå‡ßñV=V!Ü/ê±YÕzä^MÛÃ8VþbÃêáFù“öÕ«WËÅ»‹Ÿ‚s öl([òÈÔ=¡¾k×g êXtß\è(#m&¸âm÷C# ÿö( `¶©†r:Ëm3¢rÃßG^½Π‰œli$jÙ5 ê•ëÑÛw5tg¢)ö~­Ð/à àZ⟋¦aëØçÚÖÂÅõ¦/Ê`Yã’÷ÜvõðF:HâéÃ$ÐÏÊ:UÐOî¨|^-¨øV9§*Èâx(ç1Í‘¿µ}mÂ-Ûš³=´¨¦kÎDoUo·œiP–E%vS: òœÙõÂ'Æû¼ïàh9B…ÏžR²F…²fí@) [þ´;ËýƒôC±_’:v×ß…¨^ÕMãZé§«5dz ÊHAXÃLªTº3Qóˆëšàç š&&J+rMÂ@_“júL;‚ð3¼ 6 ¬=ÂJn+×®šb'Ÿ‚ÑxÆ^†wp_}••¥¥y+‡Çéxn ŽOO_ -íèØuÉæ:ÊÆ:ziPÐ9'±@hì1,[B;¹–Ÿéƒä+¯ô¬¥/ûWLëJ·"$Ϙönšd |€7„2‹°‘?îûi›žSzàˆú·àG’_–îߪ¸1¼Q‹•ݺÿ½ ‡ÍÑÃ{òÈ•‹</òX€Þð¡<§¯=jÙ…<µŸTŸ½°Ý6Bè½zý#{¾ÄÅq“®ª÷7·²÷ÃB@ „-Ú»—¥DgáÔþÒ“¾|#gŠñ@X`kºŸAB,àwKm.O±Ã䯹9¿çÅl³/KlJrðX³Šßg ôÛCYöƒ+÷+رá-J{]Êp'nÚýŽ;ý®‰c­|¿ÉÕÝC±g¤ï<˜'E‡%'E5=uxxZçA¨rð–Y&ØXÌ€¦ü?6’ -endstream -endobj -1266 0 obj << -/Type /Page -/Contents 1267 0 R -/Resources 1265 0 R -/MediaBox [0 0 612 792] -/Parent 1241 0 R ->> endobj -1268 0 obj << -/D [1266 0 R /XYZ 72 720 null] ->> endobj -194 0 obj << -/D [1266 0 R /XYZ 72 720 null] ->> endobj -198 0 obj << -/D [1266 0 R /XYZ 72 514.349 null] ->> endobj -202 0 obj << -/D [1266 0 R /XYZ 72 404.147 null] ->> endobj -206 0 obj << -/D [1266 0 R /XYZ 72 321.654 null] ->> endobj -1265 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F15 1136 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1271 0 obj << -/Length 2280 -/Filter /FlateDecode ->> -stream -xÚ¥XKsÛF¾ëWÀ— ˜a`ðNe·JmY[«Hkq³‰ Q­pý~=Ý>㊓ ÙÓÓÓÓïîk=Y®u}æÊÿåôìõÛÄJ4R‘5[±²bÏu\?¶¦¹õѾXŽÆ¾ïÛEÛ6-ý2R‰u‚_Κõ’0}Ñ9S”r¨-²¼\>ñ¢_¼›—Ý3£ò²-f}ÓnF‰o;£OÓ‚™ÿ×o}wG<׫؉’„¥› Æ¡ -í—¶ì Y^pÜWïàü íš(ìÙlÝê¼,ʪ`BºáX£r ìȳ³ªüPžé@¿q„öM/œÊªâÓ+œl›Çì±Ú0¢-ºu%dÆ”UÓu"àœ1¿¸^`Äʳ>û3öÿÁæšd}ñÐgõªhñêÕ«éÍ훿9“‹)cÞj#hÏü~<¦k­Às’À·Æžç¤aÄÌïÛfVB˜-7/™¸é7t~ýñ‡OU/‡£Õ‹,–]IjùM|LJ–bûf MªŠËFÚ—Ùlä{öóuKy¤%ö† ¥±˜7‚ýð0¹{8™Øo¦g¿žy]˳¼0tTª¬ò$~dÍ곟\+Ç&Lìøib½hÒÚò]Ï ¹kUÖÃÙ¿˜©g~ì¸*þ׊¡ª› -£.âEÅ*•ZPY n„˜èÒF%àGjEÛé(Õ4ä¬uMQõÈ!Óò% -ý_R]—%¯6DÞ¬y¡“€r0<";Š|ûjÝŽOE][p«t#:§ÓÆôc?õ¤B“0ŸËœ2ÂO)çx³¡£ŸGZÆ*£Å†7؉ ü×®=–™q?zè±rúËŒÎ/x Q|BFÄ]ß–k}*p%„UàÙ—Ú„Wϧ4FêéZ…ÝÁ6D°È¶Ò2&cª¼Dêù…±#?sʰ[ˆ¸™oop>ážá8pžµ p6à5‚V[ò|Þ3Bk¼¥ðT¢.úE£M˜kÕÑË¥R2GƒŸ6!$þPñRñÀ1)'?·…Žù»Þ wª,ÊV éºãÊ4ÿ|*P¿9µ Ö™º]êvì EÌaÞ65C;OO.½jŸY¾J×R‚ù`æ$ÃÛK¾¢è¦œf0²»¬>ùýõK‚ÓìàSCÞ–&/4…Tºí”@¶uxó¿Ò^ƒ£²M'g4Ε(…Ò— óaöàjfë¿û_ qíÅ„¿Ùtyýîÿ;ÃžÃÆ: ÔADøÊ‰LDP* AùN2Z°h¨û(Ä.¨’¤˜í¤ùÈ Ö%›¸è€Ù³[¥pØZ±KÃs r'†n¡0Ç©çÑ?æ€P ¼‘óÞãÉ1!L2=‡(ÊåÀÐ<.‘øÔ‡AÓy¼œh)•:®—Â8©“çþªÕÿý8 o -endstream -endobj -1270 0 obj << -/Type /Page -/Contents 1271 0 R -/Resources 1269 0 R -/MediaBox [0 0 612 792] -/Parent 1273 0 R ->> endobj -1272 0 obj << -/D [1270 0 R /XYZ 72 720 null] ->> endobj -210 0 obj << -/D [1270 0 R /XYZ 72 547.748 null] ->> endobj -214 0 obj << -/D [1270 0 R /XYZ 72 251.764 null] ->> endobj -218 0 obj << -/D [1270 0 R /XYZ 72 156.752 null] ->> endobj -1269 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F16 823 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1278 0 obj << -/Length 1507 -/Filter /FlateDecode ->> -stream -xÚWÝoÛ8 ï_á·9@ãÙ–½µišå®kŠ&†n÷àØJ"œmõd§]ïpÿû‘"•&Y¶a‡MQ"ùã—zk/ô&gáwÖËÅÙÛkzÃ`Ø‹{Þbåõc¯…A(úÞ¢ð>ûWW‹N7Sÿfvqu9 F³?¿½½ì -½n<ÃhïŒÂVe‰Tâ׺ügbªy,3d¼Ðn£+I[•¬´qÜ6kUÓª¼y‡*¿1þÈrgD|døÇñýœ¨8ˆñ"”Œ¢`˜¦$y;þ¢Q˜†þÝ蔀…!ÝF@è~6ç–8'×ZIÀˆW¬ZM[FfqTMëåä®3þþ[ŒÞïÇŸh#kh]鲤ëÿRÝ)h¸p7Ÿòîþ§î‘iêB;’öÈàXG’GÎi'+ -U¯‰n7’ŽY›«–¹lšÌ&|®´!âf†^C^Bøü ×N}®×µú[ÒçÃüj6ge5ÛõpÕ=å.ì­üÚrÄäWÕEìYµ›_›ˣ;ÙåP,‚aÄìkUgeùrN™ÖdO’(‹F6Û²µ8᧪²µÑ´f´¬TÉhâÑ-¹®*@àÝ dÁ—H$K¹Võ?OÒ,¡øªOá3¿ø8¦»Òá~oxøqsàL¹Æè]†{}!ñu}NÜdê-}4½- ’Ø6Ü'v‘Ÿ<ÐäXä7˜í®€ôŠKkç4îTk›N¾^uXˆÐ~ ‡ü2ËQæÏ‰ÑÛº†ëSämÔóŸ˜ýI0豿"H@k(]O^ é—K4°ŸúÓ””% ­kâ,:Cȵ¼#"S«¿¶²!ñ1¢i zb§!ˆP4°{ 5§ZœG£;$Îyà\Nm çnNoç ·ç_ÜÀÞÉø¡¶„´Mk‚K–íÆ†¶ë^¯ú‘MÈCéSõë±Óû¾6îlÊaJ0{-î/M++¢¿„QRJ.Ak&6ÂwWžÕûjY+u§ß4ô5Òu£Ké>ª“µ_Y b\‚ cçÁ~ƒ¼/0#RX"bì¤/³FåDNëÇmKälÛîè9»åîÁ@¼^ôhu1*œÈЄ’¨ç[Ÿ5‰íüÄð³a²‘ëJÖ˜£­= -ˆÅ½žÀ4lÖÎ PMzˤï—ÚP\†ö­†—×r«ˆMhÓ;™`-d“µ´!—(]¬°?—¹õ›h–…žY{DÜOμÏVH + -àï Ù‚ívzX ø>[¦ -œnØýȹtDúWÔ€€qà~ä¿9n[ûþv¿SˆýìKö±®±õîqÎà‰ãÉ¿»F]s9Eðf`à<8ÝD ú{ýàdGH]/Lɲoj½a.´7]ØŒù°UCÔ³Q8…ü(>ÎØwrµæ£ÙÒæ^¢Y„Ÿ»™wkùLÄÃèîž(Û=‘`s!0lâA„Š-\‘Äԇ캱Œæv+ëF=¡',c‡îaãAÆmVaGFúB…áA:Œ\›ä -Gñ”âm2)¼ÓíG}z ‰ÙÈã.‡u¯>‘Ûls̤ «jNåÝ£‘OJoù•ç\  Ff¹fa3‹§ƒ‡ 9-7ЪJɃ±V¹,_ˆ~„>†<¡‹Å®FíÔÌÚ£ù¹sÅj—ûi®Ž^ ¨b?¿’`˜$‡èý£3û)‰”p yËWff-›1×S&¢°ÁÆ¿S{E™¥ý±ÑJ†Þ@ÈXªZòÃb4óø§I‰ï<`?r¦K¦u#Xãô×™²ÙP -u‘VûAåFÏõª%ÃîÇ7î‘oøÍ4»Ç€M\0]”€ -$ŒÃþ!Æcc´q- ^ÒkÉIã~¡ i›¦üö¶îâ›ÝˆÕ4Î¥É^ßÙÒx‡®Z¹ó»}b7öyŒÙkeÓ²a+HÇL•›äiØH–úùÐX“81ÄñÄÀ”8 ªÇà Œ†^·"ä§p’gÿ›üÏý -endstream -endobj -1277 0 obj << -/Type /Page -/Contents 1278 0 R -/Resources 1276 0 R -/MediaBox [0 0 612 792] -/Parent 1273 0 R -/Annots [ 1274 0 R 1275 0 R ] ->> endobj -1274 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [333.993 275.812 364.213 286.66] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.1.1.1) >> ->> endobj -1275 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [497.682 128.814 527.902 140.769] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.1.1.3) >> ->> endobj -1279 0 obj << -/D [1277 0 R /XYZ 72 720 null] ->> endobj -222 0 obj << -/D [1277 0 R /XYZ 72 372.366 null] ->> endobj -226 0 obj << -/D [1277 0 R /XYZ 72 344.623 null] ->> endobj -230 0 obj << -/D [1277 0 R /XYZ 72 250.912 null] ->> endobj -1276 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F16 823 0 R /F28 879 0 R /F23 825 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1285 0 obj << -/Length 3169 -/Filter /FlateDecode ->> -stream -xÚ­ËrÛ8òî¯Ð-T•…øJÕÙ‰³‰co¤ìÔÌìh –Y¡H AãùúíF7(R’r/"Ðx4ºÑoÈ­FþèÉÏßwó“×ïÃt”‰,ãÑüv”„£$ð…/“Ñ|9úÝ“B‰@„ãID¾÷UoÊ|QT«ñ$’¾×Þij¼ûx5ÿ1ÿ÷ë÷ý½‚(Ò“ÝêjÓu5ž¨8ð$~|¯¾¥îÇ/³ù8UÞÛÏW³WZçEE“Ö€ÜÓÕ8L½-Aò²¬ÇaâÝê?àX½¥…mM߯žUÓ {R„º“Ž&ît@™È¢ˆÎhôjM¨ÚñDúÒžfy9u̓iõšÚÿóUjûJåÍ]P•´ä{UãF÷ ”źhsd¡ñšZ·tk4Ü Ïž[Ó·K/›Zù²ˆwÛYR-ÈQ•UH»?$:oô„wb2!û÷¨D¦Ôh¦"LbZÄ'{kúW-é.žx#¥W¬ó•m*ï¾hïغÑJßÓ\"‹#Q¯‘7E¥—4> ñ¼ZRã @09 ÞIÝšÖm(n¢Há9îø×8н¼(ó›R»uÈÆuÝ< ×ÅS<™…“ q’½ OyUÕ|ÒEMR˜wG¶ýý’¯5S>­×öØ0?ð Í­§ã.,Ä3ÏOþ< ½? -F2–"ŒÒQ,S!“`´XŸüþ‡?Z H‡Y:º·S×£Pdi­r4;ùŒ>Q2ŽE¨»SÆÃç”liæ‹$•/4“"d¤§‡•ï õ"d* á>™Óéõœa$ z œ2Q q¢Ä⌡2õ8#%ßQ‡óìØmª$Yò"t&)´ÕçÓÊ'³PXÓýOµÏ™ÅÖ¼³©³Ê»OÀœ°Ž’:‚#há&ò†•ð²X4õ¬¾eåýzþ™fßÖÍš@W_qÏ΄å<ÓäŒB0±~24±Ñ ÈhçÝìÂF´Ù¹b„³:Š"ò"ÖØñpš€ÌLëLžÚ™Ÿ¨Çå™ímèï`h#Ó«¢ÊKO¯__R+`„Bj_^á¹ÿ‹?S4P×0t)¦W—§4žsEkmŒ=PÃ5älò°scÏÎ#…1[d%¶Áµ®e‡Cæ‚ÞÝ~Ø; îïa£>΂û9}6V°jS´Å_c+bG8²,½À­N #E2¾"w‰ ¢[þs Ó õÀñT³¡@Èg`ÎF;ˆ`u¹¨»»¶Ã(/@| ¾‰'´{4ãz†,¶é6>{€0dèûW¹å‚½b„ èöS–½Lº¸®¦egÄk0è -1ˆ,Kë ³)Ç)ÝVGX€`f—Ý­r‹éç#QôÑáìÉÔê©ûâ%Ÿâ¹ZTþ­zÇ ÓÖ é'ÌqÇ8_ô’l Ðea¾SëŇºêm»Ù¶Ôî×/‘ÓÙk•Aw‘[jƒÚšdn£`§¡8 ïʆ˴M±hËs¡ìß®fØr.‰%Úp è⟆¢Û1Æñf—ðhNŸMSÃ¥­¥ƒ<Ž$C‘€ÉïÒ—Ä|3º™œé¿Æ2ôàJ@ ±ç o -KOA?ðcøA¦¦c6­iÌa®øÀñKpcíVAôTšZ6Õ bÖ+,œ4 ]ß ¶l˜KVi`Iß™6›²À3â;ãðo³3«ûм·^¢ùΠݜع†7äÛö°ñ€ÖÇæOйc­ ËBˆþ±¡Kj -]YCâqL¡Ñ°—ÖrgžÍPkj·lÞ3¼½U“¯AôW§¸°ótaœö­ØÌQcð{ß­¦æŽBœÚ%]8´/ùµ÷Ž“—(`l}kÓC«8–ãà²pf<ëP·Ú´è¸eicöa]óoâYú†×t”å¶Ô† · 3ñ¦Ÿ¯¦Ÿfâ §¿ÅDd~JQ bU»óóÙæ~¢UæÙùüÛõo8ÚÞ"gN4:ç 6X16X±ˆ­vþÌ`¹ˆ!cëúªü~šÂ¡H†il3YjbªÕ/l,yÁÞ%à‚žÔã€güu úF!O¶B¸^³ñÈÀÒr¢,M4`Í*Ë:ç©yïlGݬ¦#ÐyS{ÞPji¨âÞyiÎThktä ¨‹…šFß/Ümi#Ї_oZjßßÙÍÉ ª4·¼šP­Š›&o¨ f¸„—ZÉ…9](‹àÅR†w¢t„3äJüž\¡¸/Êrç‹´•“ §ŠÖ‰ì_6Ìè3oçŒ^½Ýºm+Hq F×nÑò™ïýRŠ×®zéÜ©» Zƞϖl¬ÚGÿEá¨÷b‹æB š‚Õ-VºD{ã7_ÎAnO?óc┦ҙ¡Á|‚\6ïÓ» ey ߢ‚|ÂMìñЧM{Ò‰ƒ ¶{uø°‘z9y,ÖΫʕ r3H#°ZÅ¢e‹4h_¹º\ä¿›žqºW¬ŠÖ¸ªÒ2E¿þÊU´K8ãÉCøl†V<Îç“0ä@ -Ö)~Q³@„ŠE!T“;òç(ÊîR]`!¹~`9b¶k ʧðÙG< P=½üIû&ãúÙ Øß0IEš±9ÿQ´ !úÛ¡ñ .ºRê ÷7ÛÅ‚ Çx{úŸMÇ ±2R/"(q,2Öÿýû‹NÕ{µ[èçE¹môžEµ/zì‚MÝ´»7³i^½bÿmtËîH· aßÈg˳é²”Sf/"‘YÊÒñ Îìx{or5‡îE)ô}o蜮lªß•­U—»reɽ1w9(p!0U ËíÞ„Ø­Üîžß¢'8ül 9 Q‹R/c¡”>WÇ.>8uHzÜ‘®öH—HzGw'€ÔÕÒ |üOdïÙ¤p&Tê9–íPø`›P çLðºÔ¹}’UÕ-·è½A*Å(çâi¿p†ðƒôL©aþ«ÔÑtÓð¶ ï³­Š?·,íŠãPørnc§ÚÀ·Çm$m.]¢ö»'…òJ¹¤ùHv1wJÇ’Èeý kWh´ÙFä“Q@×Ö›’³÷àÄÏAßfç_)—¾ú$æçàíŠjQn)Ïǧ­jð å -¡GŸO° Wçl¹JÞK[rÉ‹åžùÅäÛ¸(Žã6*Eöó.Er`_ðÚÝŸ?î®j˜L'ŸdP{¼˜­vÅlÉÅì©-p“YL!¬lÑ)Ú«ÂîGª,¸`#•væ›-`÷ -æ²s‚à{g,^`3eHÕxßcÉÀæem«éT×<(’£í‰ƒÀ½Â’a‡˜¤Wø…ŽÑ¥^Ðô>è -ý¹¦Þ|ôÂÆÜÍØêä2ñ®] ;Vöéq•ÑÃÿʸgŠ¢-ò²ÿG÷—#gÔŒÖ]y'Xž>¿NáÊD0>xÚ½' ÐîmCöL6ÌY:é;øß gÝXk"ß(¹æe†ÿêÙ½‹Kïå¢÷ê<³ÜO¢Ôëa£©…F¿h^ï±kyOƒÞ›'žßÃòí \™HÓ”p©h°üÂÿñ]t¶ -endstream -endobj -1284 0 obj << -/Type /Page -/Contents 1285 0 R -/Resources 1283 0 R -/MediaBox [0 0 612 792] -/Parent 1273 0 R -/Annots [ 1280 0 R 1281 0 R 1282 0 R ] ->> endobj -1280 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [292.451 385.695 314.923 396.543] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.1) >> ->> endobj -1281 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [335.623 385.695 358.094 396.543] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1282 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [244.077 126.677 266.549 138.632] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1286 0 obj << -/D [1284 0 R /XYZ 72 720 null] ->> endobj -234 0 obj << -/D [1284 0 R /XYZ 72 720 null] ->> endobj -238 0 obj << -/D [1284 0 R /XYZ 72 514.67 null] ->> endobj -242 0 obj << -/D [1284 0 R /XYZ 72 186.411 null] ->> endobj -246 0 obj << -/D [1284 0 R /XYZ 72 159.111 null] ->> endobj -1283 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F23 825 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1293 0 obj << -/Length 3091 -/Filter /FlateDecode ->> -stream -xÚ­Z[wÛÆ~÷¯ÐéC #ÒXÜ™7[vÇ‘­c1Iã¶$—"b`вúë;3ß,.4\ç¡/Âììmvv.ß,å_Ü_ø?<ñõû|ùäé÷¡±˜/’ ¹Xn/ÙÜÄÁEjü¹¦ËÍÅïž¹œÅAìÍðy‘·ö®ÍG[ƒñÁýö@Íå?–?Ѻ3cæ‹8Æä`4ù6xñö®Ÿv}ûôF;ö§Ôº:ó¶Xíí×– GK¾³ùæ›’]ñ[]´äóªÝ}eÚ_‡²Nì}e™ðÝ)íôþE§¼ë}µþ²([[oóµ•fA"ˆe,s½«ŠµíuòÏkÐ/?m#Z–æwøü‹zú}6° -+ˆçA¸Àz¿]f¡Gë‹À«-]ØÁ–»c}¤Þ®¢FêUMQÞ3;ôªã¥ñÚ¢*Ñ4\ÕøølѽÇË óª“öeÑù÷w¢ð›6ßïs^v~9‹Bã-w*×Áªútsdõȵý÷©¨¬+ÞæqJóÕ‘mø©›&^^nÐðÙØ£œ’–6^IÇÛèx9$}[†ˆF®‹¾‰Ö`®÷¬¤Œ–yu ÝÛuk7WÜ“y«S ~Ñ@„–•ûx,ÖtìG•j%«TnhšdèXÉØÖêT¾øÐ÷Ä}óȇUAU‘¤– U4( CoWÜœn³È›w²ù"Póxëte>;k”. ;nGh?û=µøS9ºØfö¬V.è('´è®¶èjØ‘@nò6g¿3 46Þà®(Ëít‘³Én3ãUÊ,š øô’~xÌ_„Õyè#xâÄ~ÂJ¡!n1Ò8Qò”½)Öº’A7«Ušó ~ RÝm ÈF‚þDTà»H#dÏš×ZÜ#„¿€ìn™‰Fê, &<‚Å…{gËǬ—ˆN,i9`&±î>Þšo4 -¼W[ðԎШÊý#¨ÒN‡‡v'Ù)KÏ…žæ¸uÞ…KÖ™rñ‡KdO×á4W§b¿x ÖPëçËW7HäÁ÷u~?W1òßwwñ°+€JÐÜWùF‡jp “¡Ïx|·Ǽ¾¾e=I¤µhÜQºf×¥ O Mñ/êû ï~xrñ;\zÌâ€7­ÇyX\)õ¾gàꌧP¡>ä%¥g«ßõï«ò~FV{@“‚¶ÜlꌞŠô'ëÕÕ*_á «ADÑÎ`J -_‚e¸X œ†¹.Øý­AïøüŒ¢¬Ù¢Wã›Oe¯Î¡›°“š¼ö×àæøˆKçêÿÌ@X&q-Û,!y· Ž($¤â 8‰ÆUãuÍÊ}®F…Áh"_óŠg©@²soÐÍ•NpVê„ä­‘ÑZsÍÉ}i1ûÞ+XâRð¡ùã‚<Ýæ Û} þÂ}E‰ï‚ž™º›|Qd ™q’²3*™r7…N.ÂTõà.þÐņډˆ‘/ò¬‚kAS$<‘3W)b¿‘¦áY¬`?"ðGø†Zů¬Ap -ýæøPÄi¥ŠÑÙêàD"gˆ‡óʪÕ¨< -SWΰ*‡z'Z­\:O^·g#Ò0Ãå^:É?aZ€Ilÿ¾fÀl˜³¸€¹ùæýõÛ›+ÐÇ=£%Œ-,ŽhI¤ßN4–ž§ ‘ÌLI–ô’A´ãWDl3ëœÉ$^[­ÔÞ"¾/Ér 8pgÂÉ4\áYwÃRÍ”øl€G¸Š1”óÄ‚zK.Ûº²%Âh-\ …,Qê}ºŒé4Åžr›²àQ¥NVT?±ºàJþ>ì‹3€¥ Úâ KÁ°¦Ú¶€ ¬ ZGö8àˆŽ•äK,ÊÕüLÁvëÖ0Õ ý"Òò=S.ãšTü‘ª0tc×ÅÆ:Ñ;lÃMq©€ÁvÓN=?ÒÍPu–·ö¬àQá¿  æQâù'ÂÏÎLtSxgÀù+ßo^òÈÍ.Œ‡÷½xÑÍ›…w‡ÂJ[¿ˆçÐPènôÒå©DõÞ¼eÍüÊ"^ßÞ€×a?nÜÛ’ãƒ>pýêÍÝ’ß*žý̹Ÿ9Á±~ä€ÑXIßô× ePgæf -Ô!´%)ïR-ÕZðr°œ!1«*-˜½y^gV¯uÒhj4Ú`ÜÔ ‘1ovªk¶¹T’1pý¦l~A¤¹…¸TV­ó)cÙ"&RwN${ -˜`=‚?¦¯K?LëK ¦” VîáLVœpç…&´H^¬›…[ÅZZE2-o ²ï®2ã¬Ä±¾‹M÷îåò—Û÷wËùøZgd#~¸œ%êϧ¼àýõí;€ñpþYªªx`ïq”h•k,ò] ±Ÿ.5æçÕÛ[.y&ìõ쥘x‚šv°RV/ÁK‰=ŸŠº*ƒB"Õ·"·ˆ@úHP¹<Ùz€>Q8ÞÐLÍôh×bÊ„…ó(¨ƒ·ÀáŒûÆû²n‹AP -1*ˆ$}’ÂdâHòœGeE £$ìý†èÜŽv"24·nô²Ñ‚]15¬À°ò½+&$Ô1 o²aâE¿Í•Ê&¶I ^NÄÖJø“WT'p>™ÈM!úw5šRx=Í^#3GË”.͘áÙ¹)Bñ{¶´–nÕyW³½0"ÜYè¦êÃq<¸ã…ßïÌλ×9Î6% ¦ÞO§éd͹êÞ•‡µµýl×'—ǵ¸ŽÜëóú ‰Æùcg—%iš‹}ZFm[·›‹ C ]CR³³Ÿ/¢§ISžî1åÏEO‹KBø¸ ¢‘÷bà]‰‹¾ºäi iýóe2øñGâ =q(Œ†° ¡‹·›b­"E¶$[]\´Ä!×7#&éá#]øFëÒÓA;êˆüŒ•),2N°ÑôÄ:Éàž ãNüŒ1¸jã~ }ˆx—j´ðd…Ÿ•AW¥¾MùcðÂŒ×: àEªô)Ó§ÊI“›9»îc7µÎÞ |M}ƒGl¸]wY}ˆ$òü@ÔùcŸ[bâ°+TtüÌ¿…tW##sɇa`.Ôt†Ž -æ¹–ÞÑ|á§g?ª%‹D„ÐÆØ€»å7BxÄœŸÑO)Ì4F_­ -#…™Ìââ¤þ65ñÛq•ÿ¢FUU}R±ú!{6Xpc›u]¬úBuïéÒëÛ•pO?—^i&?jZûNˆ6:ägÄÂ}c@èPDés “·ðœ9^Ýîdqô(‰¿¬c­u¡N–¡úGÂÁbî‚RôͲLÿ‰  z¹|ò_ÐoÅa -endstream -endobj -1292 0 obj << -/Type /Page -/Contents 1293 0 R -/Resources 1291 0 R -/MediaBox [0 0 612 792] -/Parent 1273 0 R -/Annots [ 1287 0 R 1288 0 R 1289 0 R 1290 0 R ] ->> endobj -1287 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [151.165 476.081 173.636 488.036] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1288 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [326.641 365.689 356.861 376.537] -/Subtype /Link -/A << /S /GoTo /D (paragraph.3.4.3.3) >> ->> endobj -1289 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [130.153 292.076 152.624 304.031] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.1.1) >> ->> endobj -1290 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.791 98.954 128.262 109.803] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1294 0 obj << -/D [1292 0 R /XYZ 72 720 null] ->> endobj -250 0 obj << -/D [1292 0 R /XYZ 72 409.524 null] ->> endobj -1291 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1301 0 obj << -/Length 2557 -/Filter /FlateDecode ->> -stream -xÚÅËrÛFò®¯`ùÖŠ0Þsq%’kÉ.“©D²][09±Dâßo¿ -r9ºì ==3===ý†3¹Ÿ8“_Oùþ²:y½H&s{yÑdu7‰½Iì:¶ãÇ“ÕfòÑ:L½Ä*›éÌ›ÇÖC¦·%V]2&+tæùétæ;•F§…~˜z±¥*rýàº|ų·Þ*öU¹Û×Lø÷254´¡ÅßË¿øŸÄRy‰¬= h%ÖÙÙû7ötøžµÌе::JøMë¬,¦ŸWÿ!Ì\מ‡!_÷!Ës¸‹ï[…!ïûµÏS$…x"…¸^#¶6M.ˆ¬àÛì~ËÐNíÊê0M|ë”Ë‹Õïo—+¥ú«æ­©œ©ä¼oÍÔµ€¬kiäô'dµ}3ó}½ðÞËÁM¼ØŽ"—orÉ7ÎB/$Öð{};;{wÅð_¡ån÷†áONè|¼ùüú—Q?ñç?ÈÄPYŽŽ¼Á›¢®ø><[EbI@5cDöYqÏweÅ×·ÀÔ)#uɸJé=½s‰:…˜‡¬Þòš´}6/û*kùÔ-z¦5 -S)¡•jžÍdýR­Fœ¸p-gRÝOøðëÉä#-ömÏö/AÂÙˆ2­ó’®°FMú -'%¥éUs9Pd5€h¾NÃÐJï#Ê;þ²Î%!•’¹ÓFõÓ ‡”å@äÓÍpÿ¾‚‹ÂâšeO„ ¥µœ‡Ø´œ88†"ZX-v8¸yÄ7ÏÁŠIÖnòÄ\Çä]2Wc0ÚÊô#¨*œñܾáÀºM¦Á"qÁÒA6„ÓÍ´G+Í‹éJð}ØfôÛ skY§»=ã>” ˆHXãgA‡Ï8òÐçU&ì²?à#dÀka@òx‰ oh~-o=“¼ðgv‹·c\ß민Dæ\°îvsâæóg6oÓâ^NcŸŒÐÏ,ÚÎUܼþxý]Å›õž¸'TÍ8Âg@“ðãpðn0³)ùËþæ×%е±V¸ÆµödÙì `¡8ˆØh7 *¾‚¤.OC€²<ý’ š<|%ÎU<Ò°¤ê^»" oNŠÈqÃçFn`XQln òÑvG^d±Ê<?V±‘âÒ]<Kh,®Ø±ð\C{,!êm¦jE+dµÙ\ôv×ÙN-(Ô½Cu`"·Áü“㨌´³)Ô+s¢»±1 òÐ×ZÐ=PÞ@Z=‚žçŠŒÅcÛÜOÀXÌ~Ì3/ €ñS 0vUõ„N,o £ËwïWÌ:î’ƒ Oo‡a‰ÕrvÙMªEÎpÈÕàâc’¡@¾B…'lP¢ÝZgÂ:›ÈÁMÆ*®?lÕ>ì©}b„@þŸRBþ·Ñ5C$9d+5\ér'P ÇV†EPÏò¾JwrXº'ì·Z>rk<^Ãw¯~‰ž¾=S„YæÐzÏ9€ê±†‹jÜAöÈK/Îç-#k¡¹p‹·§<­ÅÑzÕ‚yg  Z–oË&ßðzêd- -JÉ$,#7”HÚÏcI}üî8HÔ[zvœ8Àä0Æ@¶)»Ûv”cOÿ(äx?rž3[¸Ñ‹BÎÂqó‚77—üs«Ð'º y`<ý Jì}7è6ŽLü oyŠ5@(…K ÷^ó‡\™+i"¸…Œ’ùQ>‰Óm1€ƒui’)ü4ä5]¶[ün”^W™hŒ°œÿdþhÖ –CòóŽè{v&LÜ·Û·}† pÙ˽½¹o^Ù›{Ö¹1±Dd)-gkÚHVøäõ`ÊNBàÎ6;ÃÀºSiÝPÃQÊŸÈÍ6ŠƒÈ†qàˆðáJŒï’ÖLˆdf¼@ É{€)>l)9ó]³]qçØ‚aꇵ|7*ÍdËm Dl¥€Lùcü%ÛºCY’X+ -e¼¢ÑÂ_¢Í"@ Ý^x©iy]‰Œ;|pؽ ŒC‘‚•úÖd•Úa%¯f,[‹grzÌóPe îW¿Ýž]Ù c~†ß®þO¨Â¥ü‚Ê|¤Xò—.@Y䇣ÃnÏÏß-Çj„ãêÈ›;Ö¦ur§ˆ˜Ã»4OUj]VÍL=C×ãÁ¼î¡VšKVDßÍÓâ»qeÉ·&­éå|ÇZfÏP£¤¥ž ¨»O¨ÇL&xÀh)“&à -R-žIŽ4è›^Ī&F -‰©4•6¯4/CÏáÆŠi´„æ` ŸYï=”;‰·n XŸšþHdåiu¯dç.{$ãü'œ!šôò‹ÃØ .¼]×*¤¼’ |á3Wµï€Kðš®ÏŒSfƒk‡¿á-lR!!ôPU…*uR\§OЕ¼ËÌÔ†ªÏ°ŸwÀ’Û%É iü~¾º¼b¬±—g[G”?窪”%x´J“•YÚš°ü)Ê`vN®Á¸-*ö’¨ -‘Ҝֻ  ¾uÝÆ+X Õº©iW …4¼¡©¥Ji7†»^¨”\ž9a‡ÒŒ]ú„?ŒaÚt´8ÿ8Ž8gÚc/ŽzD¹‘Ø+]ºÎ›úØ[öè0!Bá PÛÔ‹#ýK2£ÿCGí¢+è|Ï£€Ÿþhîo"Ø«Y÷¥¹‘ó\GÎi{…°äIpZuý7G,ñÜ‹¤ÿ*¢Ó+râ¶ÿ¸£þ[àGÜK7ý½ñqï­£–ôzoDš*™‘ȰfÁ.SÛ«îÊì5¡“†8gDÜÍw-¸¾œáJ(ÈÓ¥6~÷ôÚpGýë Ç€æ>ÄKZ\W%ß(l«í -gÓrúŽÙR]p¯êÍHWêÇÚPA߀«|—»­CÄ5Ø÷ î‹Ò¯gíTZHÆ8 ãaÑ@äò²¸74À2 -BXaзÂÀ\ Ç.‰,¥Nø€¨ÌÓÔzH.5§W;ÈnG »3“cèîÿ‘'?K¢Ñý·ôÁ´¤ [U ´NêÜ!Üi ŽøwO„Y“„7ÚÙý½éźØÚ2¦­=¢¶öˆ$×¹µ¹üÈdÀÐüX27žéõÜ`$I@ǸúÖŠb¬À‘HàÀ•½¦3¯!å ªéHY°6çSñèGô»¿Ë_ÜÄa°Ñ-ÙÚù]ÇXsù(ÑSü5±ÊjÕ7ñ²–?OO³C -Ï…8I -ш˽ùmÒ›o;”- % þû—ïþÅë‘E—½ÁÄóæ¶ãα¢³“D -Ô ,ºXü?ÀfO -endstream -endobj -1300 0 obj << -/Type /Page -/Contents 1301 0 R -/Resources 1299 0 R -/MediaBox [0 0 612 792] -/Parent 1273 0 R -/Annots [ 1295 0 R 1296 0 R 1297 0 R 1298 0 R ] ->> endobj -1295 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [495.79 639.826 518.262 650.674] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1296 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.873 387.656 128.344 396.457] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1297 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [217.372 269.375 239.843 280.223] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1298 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.617 202.098 128.089 212.946] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1302 0 obj << -/D [1300 0 R /XYZ 72 720 null] ->> endobj -254 0 obj << -/D [1300 0 R /XYZ 72 374.924 null] ->> endobj -1299 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1309 0 obj << -/Length 2819 -/Filter /FlateDecode ->> -stream -xÚµYKsÛF¾ëWЗ-¨Ê‚ñ$€½9–äh˱¼&]Ù²“Ê(ƒ€V´¿~ûën€Em¢÷ ±g¦g¦ß7¹›x“·gÞ¿?ÌÏ^]‡Þ$s³i0Ìד$˜$¾çza2™¯&_œ÷ŸßÜþt~±³ol-©­¨ÉÿmúÅ‹½¼xñÐÚ†&|n÷M« ŠìEÁõç¿Îÿñê:\îM.‚ÔM3_ãÂ$sªz…›Ã$uÚJ¦vuµ;'dÇÖŃ,•YÉb»É¶#­ö…¤û¼ÝÈ’2ÐÈñw~á;zS³3K«÷¯¯Õ›¬i€©Ã2/ÑÒ‹Å9]HüËLm—D½RE©÷#K†˜¿¾ïfq,üÞckµ/ÀF: aƒˆúmŸ×våŠÔ‚#±…›ªÆB7réôcÏy³1å]^Þ_D))®ÄïÔ±¿çMÛϾ»œßüä²80$ÙÞÕfûX=AºÓ(¡ûø¢Û]›W80œ@~r¶ÛMämn -Ì®æŸ>|žÍe´µ%øÝ³$.º³G1EQçŒCçA$6…8 ^ÌV4@“U-¿¬øÄYåë™çø=pŽ½Ì¹,(×.¨G¤ÚÂ.;¼°³(ÚQ)Ó˜]2%íÀ°ˆ¶¡~§ÊNó* |×Î4c–… 4[…`yø5‚ÚiFÐ+ù…Ý»iâ¼^·¶TÌ2ùƒûô=å%²¡R°m•7»Â° 7=öv×ê`a»:eº,oêäÀÐòê£ /ŒëóT5Dgç¾ó/A¬­¢(ô‰é’]‡lÇ -Üù{)JÁªý½haÊÒê¹K£¤,Øt÷äÀ,Ë*œ‚˜¨'¦ šr%À&¿Û\lí¶ªNq< ™|Õ¬V9 ¦Ž1Ý—8›*_²}¡¶ -`åÛyL7å…Yöï8ýìj~öÛ™O—xA8NR7Ì¢Ér{öåWo²¢y"¦ÒÉ=cm'Á4qS/ ¸˜ÌÎþy´:uƒ0ûoû Sø‘íœ †îž$n–¤tRæ¦Át”B?¡`"Lq”ÑHÅ~IseUo;q eÉH"0?b? 3fìù<ŒEGnFE~”¸A4¥£HÔ‰¦%„ñ5…&a­ÝÔÕþn£ƒJØ;â7Tûc{è¢ÿÍé³Isnò¿ ª'á/œüÔüô{øX¸ž§²xÞSž¦„ŸÚ6HFO‹ûÙÄŽyõ¦n4 ¿‹a¡¾ü?ÚÕ³)}Äh0}Và}¬Õ`e¾ë'5ÞØ²‹Êá!!­P¾-lk5³j„MIͲÒðàÛ¹f¹Ãéa_÷æ¿x~dÕHúê'½ve›ek©©ˆ¹;C D™¢ Õw>¾=›|áƒB7pFéš -bøÏU©]:Ïw Ån¦¼ü©ÅÓÔçÙ›Û÷×7oe¤õ;¡¼)k$ýûÚ¼šµf»kºLÄnH6p¸Êõõ²À7-oÛH zZ¸fR ÓøêP Óìø®…±»¤k­‹;Š¡À„%Œf¤LÅÌ@ÐIä¬÷…t/*óäÏÈœö7Þ±È_Š€¤ü!œCùCƒ}#W†]ez¡$Kš¼üŠÚ'áŽÈKe!iš«]ZÕù·sn¼µ fpõ ˜ šìSÁH—Ö½s¹º åèÄùáævvêÀÔ¡tJ’—ÂÏw4>çVúý<»¼¹ÏÙàiSW3&TÚ­@ܶa¦\£éÄz\È•–’rc$S ìIçKÔ¶¦ÖN€¦5ÒÊßpÀM”v®wãĹ-—zÆÀ‰©,Ô°kîHU©ˆh4^ -¸‘Ö‡Ý[Ä+™áôÅ„N$…ÑÆ$TÎiÅœâ—j:r1ˆÕµ0=è1¼ÏQ륬Z™ê[S ¤0¯š&§j]5˜M%kÒ8aïÖ¶J²Ä½ ý*ùÒ¬ÐØ¾Ø^*ò«, M8rvON£ÔíŸhR4xPdû|I6ôR"áý&—`¬e«µ«¦«`C%Æ1w¿SvkMGKeª‹×ÜRÐï=¬./wFb·`×ã .Mk_Íó­FïFBÙ8-¨˜þì U‘ðf;Ž]–#€ÏÑöqó=ÚBIYCج³8Ú÷†Úkt¦KEôÁKù«’ELBÝÓÌY Ðñ’¤ÇˆxÚüYô&ªšöÆíäx'R\!áCŒ‰Ã\Ç×ÈI"*«=$bLÍïWº·%äÅäÐÓ(цå‹#²°•ÉQ¸§…G[Caxj ‡·³>Ì‹ï ¬ÐuÞm½\r¨š<$)sö* äÍ©‡†jÝZNh±†·Hžð(çŽ4åÅd¹­­·y©Ù.:ð„¡F×4jᙌE®§®ô¬}Ýcdûº¬ÞÖ‰.Wk"Ž?íØ'eŸ ž}¼3µzäÖ«JÝ…‡À™ràL4pFH²K<‚„‹?MAÅ60[+~4KÝ}ÛÕ_Ø›÷o¸Åüà‰Ñ}·Š#I€8:ˆà·V¦ÇBHˆ}HÁ-zùÏh'¸ñâEë«¿¹— í5žXð•,1LIS¦q´¢¤"†#TN€);)´S4ÿTÊ,Í2§/óÕha3®FSõYÎ_•L,LC–Å O÷ïL˜áœ•ÂÐWû¥V0Ír‚}1DJ6X¦FÎGJ£¢ÑíHÝŒzO=¢nZb)¢àÈ!‹YÊâAµÅò: àúæÝ•ˆyþQf8äÓï@³Ÿ¯®>È,k¿ûºT|ýæx¯(Åî’¦m©Dß·V—XTô»Æ£°¼¢¶ÅÉG*õLr0õb°ID³ï=œÖÐ à—Š"ï,Ú14;Y&ÕÖp^FR’†Ðá¡ÚÊ@ã*Aên Ó+ˆ¤WöOÅþÀxâZIHŠŠTx‚Ç#)µL™oi&û4#&Lã±ÐX"«`ñ[,º•õM`ÿ€,Î ö¦ènÓRýܶâE±£¡ÞR±ØB|ÂgVOü㟢£H™&¨43 å©Dpd«ü`%À#c%È•%I/|ͰhİC¥fQ¨›jKZ&Rf¤OEhZ¡ö…‹Ll?|ÿHã'kºuWoÔ„šz’¶kgQöu-­Ñ¯){dàÃë 5Î1l”©­è*?Ó½ê î ‡wFï 5Ö‡f\Ê[’PUŸŒK7­|6ê²)šîë×°âÖo^cE1:©ª ˆT‹uÐøP™ð‡­¢­îHÕ]ï¾² $Œ÷»þ’¯º“Ul•Â{yçè)äѪ“N+Ïj¡ä¢ì6ßãCLD)û2g_5 Ò—Úá ÞA‚A§‹Ã–ü~’7QEÐ×$¸â¸Uò‘š|g-0wJõÞÒ¥9åæýlyýN_+ýý¥u‚Õ¶¯íåÞ c– ±³ÂðÐ!ýÙ=Id–´¶4=èdô±Á•uÝ‘‘Ô;aŒÃOj2–#[–wì`ø R>4vBjö­TùµÙå+ÄÅ`ÚGqÌKyOsÌfÐûà¥{Åüé8Ú‚ñ¾J¦Fµ3ψmGJÌ!àpdod¬__ùëX(ñþ0þbï‰7Þ,Ÿë ºÙäÅéú[=ßôæ §Ñ™A¹žŸM.Ò©›%Ú¿Eééj~ö`g -endstream -endobj -1308 0 obj << -/Type /Page -/Contents 1309 0 R -/Resources 1307 0 R -/MediaBox [0 0 612 792] -/Parent 1273 0 R -/Annots [ 1303 0 R 1304 0 R 1305 0 R 1306 0 R ] ->> endobj -1303 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [477.868 488.243 500.339 499.091] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.2.2) >> ->> endobj -1304 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [450.078 430.01 469.782 440.858] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -1305 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [478.435 246.704 485.409 257.552] -/Subtype /Link -/A << /S /GoTo /D (section.4) >> ->> endobj -1306 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [475.73 167.999 495.434 178.848] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.10) >> ->> endobj -1310 0 obj << -/D [1308 0 R /XYZ 72 720 null] ->> endobj -258 0 obj << -/D [1308 0 R /XYZ 72 653.313 null] ->> endobj -262 0 obj << -/D [1308 0 R /XYZ 72 475.298 null] ->> endobj -266 0 obj << -/D [1308 0 R /XYZ 72 449.382 null] ->> endobj -270 0 obj << -/D [1308 0 R /XYZ 72 368.691 null] ->> endobj -1307 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1316 0 obj << -/Length 2852 -/Filter /FlateDecode ->> -stream -xÚµ]sÛ6ò=¿Bs/¥fNŒø%’÷æ(vÚ›¸öØîôêö`¶8¡HHÆVïÏß~e5½i&¶€ÝØ/ì.—³§ÙröáÍR~ßݽy{¬fAìGñ*œÝ=ÎÒp–K¥³»rö«ÏA&Þýíû«Ûù"Jï§¾ª«¾ÒÝüßwÿ|{‘Ír?_…+\½œ-ÂÌOó˜ßmªÖ¬B¯ÓE_µ N"¯}dà~f^;†ÞßΙÀì§N›ïdñ¥jrP5ãJݦz˜/ÂÔÓÃúfâÏó$ñ”©Ú¶äδOFme»²êzX>ôºdÀsÕoìäÜTrÝà-ñbAàçÉŠ/¦ rËC¯i{”•+Ö{žmShÓƒ<ðžAˆ^ç!>€¯š®Wu­P&þ|± -— +ÙÒ9,ÌŒjžñhÚ­ŒTe,«®ÚîjÍ| -$¼­jJ`¶Àq ƒª‘JS}Æ;iÄ4“‹%|±aÔí"ÌW^ßòo×î@•}U(Z˜§ÞoË F¾ˆF~4Ф¨Ï•i›-{Fй@ðOÑj·«qsGòˆ£Ð;«kÆ¡µÐY6Âí XPz¼Æ &8ŠAÄë«ë_^Ç›(ò£4¶4GñÀÁùÇ(Ž P"ÈoO -Dß™` 8¸»]À9Ú¨èO°Ä8²«I{¡C`ci ‰ëh±ÑìñݦÚÙMÈ'JÆwÃÎ.ï)¸ÎrÁ‰VÇ-I^þnçI –è"Èý8ˆÿ‚ÞÏÑ1çàcw·?ŸŸ_¿VÈ*ñÃ8p¤¢ÖP× ˆÜZ7 /HˆY #\eÄáDд%Ftñ{X… |µÓCÁ w5ºQ[R*ìɼ;9 ¸åøq?™v؉oPœˆX« òšB1B]#ô²©aDñAÊnÕ¶²Ú$ëêÕÖ²“e°¾§ _fùÿëù¯8ÛÅÏYÍw7¯uœd~„§KÙéÒc¿Ê¦~duM¡ñ¹ã¹\xÜ;Žw©ÑÔûÏÀ+?ÑK‡kI@Û©GmîyÐÊrˆé Êß6‹¼¿Æ—ŠŸ«ïO¨(ó“0<2è#[¹‰ºÞÛÀð[M©1'€¹Æ±ê7£›¿µfz¿¾¾ašµ}ÇlÈ*Éüv˜_°ÿ‰g~œ%_#¦ÛõÕ?œ0â$÷Ótòfdøhò¯S“ïQe@%"ãéÚð+ö¢æî@\³²ÌÛÁÒ1^dÓTÉ÷Nc]H©X†™×ÓPcËSÇÌ`1¿á|ö‰ÅŽ•è¡(wíUIDš†ß¢©ÕrDþ¶IÖý¿N<:aìǮⵣ _zˆ™÷âp’[!r:‰d‘¼¯íÓo \b¨”†;±a$>ý·V:¦A‘!Ææ¶ÄÜ)*hË–á¶‹©àdíð•&iïXiaÕo‰òe*µ|ÈT—£²m;…ú!igPØp³ƒáN›Åíêä`<Îv¼X–PR´­~ç>Ô¡çÒ UÏCH ¼êzÛæ‘<¯¼Às|ÄA8­„þÐhöå© 5K 7œ¡Aaù»œ™§n>¼™ýJD±ŸM,ÖûsHˆBïgîK%öY…~)ôN’¬DžÝ$„N}6Ïb[‚gE áWh¸;™p³—}[þå,1‘ü7™tCé0²ÈEdYý–ÞÆ®?ÕÄý#êmÚ7ŸóÓWy˜Ó¶j”MÌ:ñl§-u¨³,ÕíùÝÝùÍå4—~9ð³}­NûìµØâ&¥…Ò¤Žb¨$Ätc?7õ˜¨Åý_þY·»y˜]Tõõ¼?ZE‡F•¿¾‚SÆÁ’, 1Ťã1ÇRƒ¦¶-Å4cr†“R»½Ú’ÜÆç 0À×+âá%ŸŸÐœ–¶5OŸMÕ÷äëÀôÁaySÙlA8¬Û†ÒpÝúSÿ€¹`wÔ‘Ý:Þ3f^R},M]Æ<8TïÌPÈòËÖ<áé&­dÊrd]%ÈKÝåqƒë_âŒÁÖ­WP˜Î{¹½QM¡m§ùh/<ü©–é®2Hb c±½grWñ©N75®2&ç©)þJ÷8–ð2í÷q8‹Ù]&L±mÆ ùàmºq¡vêÁù8s|9§/MŸ>–£FpL·óy|Æ?ƒmqk³(5ê“ÊejS#þ· ŠÏ_Šü—?î,éñúùãÏÒk8æÉñ¥£Dbø -=@Û üºgdÑâÜþm" {ÜmÒŒ)äTÒ8©(öÇæŒ¹uƒ8–Þ”ÿ¡}à¨eÐ2`LÆ#ù0åðŽ©N¿ÞñAqAÈ! “ïÖgpp&ééèåH÷PõŒÝÈw‹ZÙðFÉYN ðGq{…é+‡/´q9¥ª»ö”lÝi¦§¦4ް’N”ãæ&ÙP -6D¼%÷ภˆCè´16òóE5ËdLáÆæ¦´þ(ÿÓ¥•?<óó0w¾ÀÕ@) ËÜï3”9ˆ^å<³ÂΜÌ&å{Xæ½w3Þ<ëȼó»gÏ€­´a4‰:÷΄‘Õ«ÃÊÞy6ù°Ó‰÷ýáÇ©0[±'b£.³B§:Bÿt›ŠÃïu½ãu[Ýuô­ ÁÏНÙJʺuû‰2±’éÜeײÀÏ]­:‹0OƒóÝ!/Ö/p²ªùBŽåøŸçH=u"G’M¼ßGãq¥âîSË3°Æz(¹”à†ü`lb4×áñç7éé#æàîHV·l¶Çßr×Ûsa|ŒtÑËúG¦×êP¸¬ˆ“2¢ã–ÓÞdá¤R¨ÑGŸƒNtÜfa˜ûKl5Áo–e’æä¢ó»7ÿ,FJÄ -endstream -endobj -1315 0 obj << -/Type /Page -/Contents 1316 0 R -/Resources 1314 0 R -/MediaBox [0 0 612 792] -/Parent 1318 0 R -/Annots [ 1311 0 R 1312 0 R ] ->> endobj -1311 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [117.884 285.485 132.607 296.333] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8) >> ->> endobj -1312 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [117.463 110.91 132.186 121.758] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1317 0 obj << -/D [1315 0 R /XYZ 72 720 null] ->> endobj -274 0 obj << -/D [1315 0 R /XYZ 72 720 null] ->> endobj -278 0 obj << -/D [1315 0 R /XYZ 72 260.806 null] ->> endobj -1314 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F23 825 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1322 0 obj << -/Length 2546 -/Filter /FlateDecode ->> -stream -xÚ­X[oÛ8~ï¯0ú¤‰¢›e©À.°M¦Eètf’În›é#ѶPYòÒ¦Þ_?çF]\u‘‡}±É#òðð\¿Ã`µ[«·/ù}ÿâúM¶Êý<ÒÕývµ‰V›0ðƒx³º/WÞ¿öU­/®âlíÝ|øå*ËÿF«òÄîRßðà©êömßñÄ/®¢§‹JÕ¢±ªkÕU­l8`e^¡ËÞh{ Ô<óN@j{^rP8;¹ì~~vqgìUsz;’9õ:ïEþRoU_w_îÿ w¿ -C?_¯ù–GeÔAwÚÀÅ’|C8½èmתÿj&WÝü³g˜ÚI~màRÍŽi¶#‰kí_\åñÆ{ׇ}%GTÓh·]ÇÄpC·Å/…’Ňª©F!º½æÓdÝð÷QNA¶KwüŠ õÉv¦å!q‚ÿì+£Kž‘.×` á¸mÍAÖ*Á U£y>½nÛXÞöˆ8ñ˜ŒõRÑÅUèU°¿$Åàv˜€œaa_{Â) éÖH(Ú,ikÆ_ºìýEã±IœzVw< )j™mSVt¨?I#tJp=þØí•,¿‡MŸü›ï/ -Lß Ìo™BáàóÍÏLÇågßD!¨šªV5ÄîË'ꥫX0™>`8Ä1óŠãÄÓßtÑwš©Ã¡üMY&—Ú¦ß(™V5¼æNzpà‹Ž Vf·âÁoo_¬hqâg´Àe †´}ý&šæ 8ŽüL2Fâ‡~×÷Ql Æ ìA{϶Fk?Nc1Z9Ê#ïQÙªà¡=‘stêÏÁ#yÀù(ÊC Õu‹ž÷dùSÇ|ÀaMµ«L:´ã—ë÷“Ú—ÎßÃq]YÞ — TÉUȶ49¶FǾFŸ²8¢8ŽƒÀS o„Ђ³—ŒZí\ :‚SÐ&I*>ž@Ö€œRÈx8꺷฽>þ„I- È`e’,ñþ! U ) ävl'šÄ¹*Kr Xét€äצw‡¿oÍÎIGžƒ4Ô{’Ín•J•Œp¨:4D’qâÏ0ñoO¬W vF5vKɧȘȤnüÆÉ©àêvÔüKþÈ G̺=öµ2Ë9·÷wW·î|ž¼ލäЉj×Ë%Cõ'X“ºÅš¤žfe’M— `0Ö”˜4Ñ~›Ñ~°„í' k–CgCHÌ㨊ä‹£Œg¥sÇÄ/ßyËô4N¬Ë9J‚>”$º.iSCÊàS!-ØÓ¤è´u»;I¾©,LŽ„Yº‰Ÿ—nB?=O7—ß=qaøPIª³=TñÊ“öÕŒ•û¿~gé'ó³ßAiaÚü0€ÇuÅÚCê3°û0ZdÒ -SÀ€­9c¬ŠÉJR&¥ïŠ‹“…KÁìwÛ5å·\©`(É4]>ŽG—€1‚ Ug~I -ù„—"4"w¤‡ 4O{nß0à Ç<|pµÞpK”1òaò„®¡db4(¥¡H†ÙÖ´æÅF4‡³÷¬\A­#ÆzWš'œì`MÓò‚i,EÈYÙL’œsüC>iw —–ðÅ3!)öp<ô%¸§¦. GÊìú«ƒ`ê36>jÇT£›B˾Q70 ’eƒqq2¤Ä„‰Na& Î:û^ÍŠ+³¯\dD9«ÉÐ,qåe ѧ†ÿŽÐi«R&JHšÅŸögŸI‚÷ó¡7ÿ‘PÛ`Ýí¼‘üú’ÉñB v 0‚N¡ƒ0¤ÒAgÔ»OðõagµY!Ô/z¸òøâ“1Æ`Â:RÍŽ"Œ¾Ž+‡ƒnÚmºëúî,å¼I›ÈëPM°¯ŠÿGèc”yO˜s ÃĈãͤ™†‰¢üS8HË©h±{•Àᬠâ,B`Ùàê8¶µ²û){#ÅRT#â…€&†¿0WÀäô6S*ªÏ’¡‹¿Ÿòž¼ w{ƒl ·Ÿe‚œ¢ ü_Ñá""¼~.ü¯â´=IŠ çÜI€81b ,,>4©Jry„™„_žŽÝ -æyz8œ¼cá2©(¸¦eŠíñm )ã›K1Ó¢µ“7­$Y{o. ålÍRÊÑßÔáXS'ÕÚvPÂé]'Ç<֊ЙP(=À¿VCaFê앉icP®ó.Æi×8Â¥†¡—åG­\œhQý‡9‚‹_ûJw/…¡8 šò£•6ÁŠÉÁü&„#IÂ?l¤,÷ÊÕ1øáéÐà…Œ»øu@bOÞñ­a-ìs¥º•Ò–g“‡Á c >Q“¿ -É]Ž -hCËŸM”˜ jPXD(‚K'°¼FT®Jy»ÐÁOzvH1ç,(uy§@ {Ãÿ-¿OÀˆñçfíÝW!Ýuà@ìyéöp!¤Å¡ À¼o¨ìàÐA3àÒ:Ò-.yÌšÃÓG ¸c䌆߆~€¸(cÍtF%ÐÁ®ÖP¹ÂÍÞ2q‚ˆ±+„Ùä)Kž¡2DvZt³‘1:3¥m¤K°ˆ™ñÓLç¸ uN¥ø,ªðÝlé©J›AרŠKJÕTŒroCùƒ5KÊà–(Nf “áÝ ½1\ Bn&%%M‹~ìÜè­ƒ´PØÔ\¼ñÅ€C> øçr¾=ñÂÀN=×~ -IüEáó¿oùÍ'a@4éöľËÿ¼%„ ÷~‡~ˆ @{ü€˜(e[th -Û…üzÓYɸò&z2€1S˜Œ¢ F賓iíGñÜÄW®0Ùîû¾Ža˜–œ>œèÕöDk–nü ³’év^#ÐË&ËWWqîg®ÍX³?Ý¿ø À x -endstream -endobj -1321 0 obj << -/Type /Page -/Contents 1322 0 R -/Resources 1320 0 R -/MediaBox [0 0 612 792] -/Parent 1318 0 R -/Annots [ 1313 0 R 1319 0 R ] ->> endobj -1313 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [302.815 659.283 317.538 670.131] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8) >> ->> endobj -1319 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [298.484 553.23 313.207 564.078] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1323 0 obj << -/D [1321 0 R /XYZ 72 720 null] ->> endobj -282 0 obj << -/D [1321 0 R /XYZ 72 646.339 null] ->> endobj -1320 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1327 0 obj << -/Length 2311 -/Filter /FlateDecode ->> -stream -xÚµXmoÛHþÞ_aô“¼¨U½Ù– -Ü-Út»èâšuº¸v÷>L¬q2¨,’Ü4÷ë—É‘å¬ö8\€À3$‡Crøªhv;‹f?>‰ô÷Õõ“çoòY«d5»ÞÍÖÉlGa”®g×åì—àm=_¤«(èï\‡UlMgŸa¹êF@¿FqVY!lvþ€dgöºªçq`öóE(­ýæºÞ–‚uõÙÁ((m×»Úô®©…´ÖèÍ7Ç^ˆºÆsß5í~,B¼q^¨MoöWß -ü~žäéæÿ¹þ‰Œ°ˆã°X.E]³íÝW ¡b’çÄŸ~×k‘*Y¯pl·V€ÌVÀ®Æý*,tÉ—È¡ãvk»nw¬ªåךºÛÙ¶…ú 釋æl¬Gç‹,YïÁÕ¶¸ËÁœ·¥óöý#Ý\íHˆ4Í‚{G·Ñ*U£Ó¢¡U+Ëî¡Æm½ù&{zm:z/Gty ‘ó <’n/pãàVþ÷ù›49W¼ WE<£Ca^$"ÕÅÕûOóÅ’t‹£ÿøüï×áÅÕ;áÉÇJy-£àgÛvln>F²ø•PdÙ|Þ¼¾Ú$ž²ÇEsx`ŸåEò‚î&}V´aŒWa4 Ç<–a’ž³YüSïztœeü`•»€bÑà…üôü’}/Oaxõå„|m(.XðAW·{`š MTõÚ¶iÙ­Ïcz!B­¾q5¤Ê–…Z4£(àÒövÛ[xS)㣰Ä1ý@"ô2ÄHô3wZQPer­,%B±:E(h7€rÙªR:Á–ä{ÇCå¶d¤)sl¡ÆÝâðGÄøi–5õàâIÐ4»¤œÄ–æVlg ÛZÙ9¥²D–’až XŒ‡Õ¶Ù G3È4ž’à_¦ëeõŽ<(ì%tIP’ -,Ùiqö†£ª‘ÐŒ‡„nBá³'IŠ\Ÿ¤CÒ À}ãê’M ”ÁOPª3A‘h©„‡–é•Mœfƒ¹A‡KìíS!ñ¹”Ѯ뎶TŽüÈ iíÖ"©ÒK–#r‰ÜêùÖvQ¾î¬ÐPŽ^é 7McIž¨ìù©hj¦ùpùÃ<ÏN£ëàJ\tgwvÈú=‹˜…á4Í-›w|!>V}§Ø+++q× ®d‚8·0®ªRò?1§ÅÓgSï}çäñÈÒ$íÞR-‘egzY8,ÅZS•ìíEr*Ó´æÒ«‡8 -U gJ¾>…÷†[!p£µ¼)³Ë#—|Dcæ©ý™˜ÌX6 iŽ*v;Ò}+©škU#%¨î' Ñe%eh 4Fe«ÏJ]ö¨¿ Ì©²ñˆÄ@ÒpÅ  ó°H -‘ð%‘eT€ÝÞUg2ˆÑrPü”“òà‹`¹¡"ÔÞÀÞX¹`ŒlË!ÉñvPftv×ùI2i ø%ntžr§è» 6Cô>⥖ÈÖ§cï?¾"a¦Þæ%˜ô}ë¨)ƒ§ËàÆõˆ´8 Þîbäçýñ\h}pèƒ_­:¥ì8\R•]ÐãD@;j×–Ã5¢W[KÖKµ»J—'N>¯_Qòsœ6H–?^ÖzxMhÿiž§ÕÀ×pRa×Ü[ᦩ÷ÙÃ)9÷ŽAãÆT÷åN3%Y;ÍXS.®êJ ú–G”» -òPK²á&H°wFo–c­²íl®€H?òbµ•j*4 ÿ´ˆªë>‹u>—ÑÆj(nÈðxB´Œ1ñ‹fííL~|2û…y$a¦g]%]†j1~8Ì~~7Lµ²xþV¦Úá\Òpûÿj¿×¿þÿöH‹ôÄit‹…N¨ÜcuÙœ¤*í¢(fóÅdõÎÂúŽØkÞzõ1^QèÆQ4š´g“ñóÍx6žRtÌäÝç‹¿dr9i-6üÿ(ɘÉç<úK&›ßOèѹ¡iâ–uTg|÷ë´5¾ØüÌ H{#½D§ÍíYÆÇª‹ÇnÜ gT‡öü¬Wδ TÙŒÚ#«î‘0×Îvžº¹¥œÁy>“GJ§TäõCcÆaB¤1–jÒ늫b7m±e˜®Rýžaµ?7»È`:ÊRh+ŠT2 -0ÀRÍþ„ä\ýu¾¤2K½ûM¥`ÎD·=v}³wÿµ²½€>WÄe”«’jdfãB„ì‡oAïNštŽ“&ØÉd7娍’¼9U¢=YŸ0hÒ¦>ëá«HŒqfgÐý¡eÄ~ÛÐ𪌳8 Ž|^‰õ¹»hj<ûíÑw2À~ì]5|&u![êîE–Rˆ\-8ßÊ1o˜ -\©+ù¤cPY‘õѾËcQûJOüL>R< ]SùœÐðd’$¬oJ°ü˜/86qÂõs/+~ÿÄWªdÜ ÐF;D ØUg=;|nª·þF÷ùa+%öÎÐ_m©ž_ãµõ».ˆ~/Ą֧oSé™ûz7ÓÐ/Å⮩ÔêêØ,IŠ0Š‹Ùb]„«\n‘*2Ðüpýä7s;b -endstream -endobj -1326 0 obj << -/Type /Page -/Contents 1327 0 R -/Resources 1325 0 R -/MediaBox [0 0 612 792] -/Parent 1318 0 R -/Annots [ 1324 0 R ] ->> endobj -1324 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [194.485 462.466 216.957 474.421] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.3) >> ->> endobj -1328 0 obj << -/D [1326 0 R /XYZ 72 720 null] ->> endobj -286 0 obj << -/D [1326 0 R /XYZ 72 229.9 null] ->> endobj -1325 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1334 0 obj << -/Length 2787 -/Filter /FlateDecode ->> -stream -xÚ­YKsä6¾ûWtå$W5’H½ŽÎÄ“rª<ÎÄN6ÙItKÝ­µÔ‘Ôñøß/^¤¤vÛkoù$|ð ‚Åz,~< äû÷Iß`.Òh‘†¹Ÿáb¹=ùòW°(€þÓ"ðUž-îiÖvÆ©§ ´ëÅÍÉçƒõAê':yn=Ì ý<Žeù÷·'ï?f‹ÜÏ“(YÜ®iêçiœ„~¤Ôâ¶X|ñÎOÏB•¤Þy·<2oSýƒŸòô¯ÛŸN.n',DQN̽ž™IûI¾Ižû|IŒ C«Ä»=Í”WöÃé™RÊ[µ7>Vu‰-í]|«ú¡l–ÏHøzçfÊOÕ[(*ÉR_E¢¨K0ï²éw§gQê•ËEBáúgÄy5?sqÒÐO³7QXû`j,Έwµ¯‡jÇÚQÞ‡v‡æ÷ðŒ4¯fg.M ^½‰råë0bi>‰}jYŽ®ÜÕfYnËÅ=U«¹1‚¡¢1>§ºWs;V§~–¾…¬qèëX4÷eU¹÷y_•Ã3¼¿öð9ë*öó0~ Þðˆžn€÷8 áâ—õ¾-Ü<"l_æK¯fk.U¤€½·*‚H¡E!¿‰ñývši¯ìªÕsîóZæü‡‘o¢•0öã\´òû1ˆ´sÝÔÿ·ÿ¼šßqCÙÉkBöcy£Eœ'~J úˆªkÁÜt{æÄFâÝuU¹âfÿÀ a¾I¿Ýî¹[cü*¸mî d^‹óí!½jø{1¢jº –«[/¸ñË'‹/4Iû¡Ò›·›ïNÏâHC i÷Ìì=¨É«NC¯®yû¦äÀacÛR?˜¦0]ÁkÛeN8“+§ )ʺÚVCÙÁ‘* <Ÿ4ôúÚô!U=ÓxSc/`sªÜÁ°arßî»eÉCÀ7 -H ªÆ< e±q´ú3õ’Få$ÓÉö¶éxYK""aÙ‚fìuÕ”þ1/Q¯AËѹUrƒ"y6ç€GPd(¯†ë®ˆY`®C‡¹ŒEÞý¦”ÙK ›U³æeCˬ håÊ@¤•N'&Ê,5êbÊDä]¡&‡¶{@€ñOÏ xf‰¶±™Iœ°Ä¢lrQÒ8/h`ÙUw|ã…8´Ìá ¥|­®É˜ïIœ³3Ywf·éérߌ¦Þ«ÈÏ’œFSŽÀ˜›8 8QÁ |PD­½kgˆs? Uè'Y;ÒNÿ¢»Uä¢$X´ ¨–fÀÁZA¿¬ÀCì…^ÇSï8£¡a—ºYWZ±Î”8­²˜€„Ѽ€Šæ%lȾƲ@*8³Ì4!j'? -ÅUyhnè¨s¿©w¹[´lÐŸÚ 3Ť‹UÇÍǘD°ô½„Ô—ƒ=:nJ;q'ÒÕ·§a -§^BlŠU]O±ÀYþ•Xlœ€9¬Ð°8(_xºÜï(²€¡Ïï*òDHÌÇ•o‰· „À×-¼±hå䶈‘p:Ý"nÐò·‚‹Ü(í¶fàUî€é¦Ó“_N ƒ‡¥†JÈS|ç£÷Ö-`Ö¾ç{ -Øná»l›ÿ웥øî+Âä‘›`„!°Ã0”z2ƦtØÚºôüÊàÜeM=ºýhÜõœ?Î?¡½ë8(VEyTfŒ29˜HµåÚ#WÞ¶6-]EÁƒíŠ¿¦c¨«þa_ͧþºØÀíÙ¬íž{à™èì^¥Aöo‰ý|‚ÍØá’5Ww+WÎŒ£×ÀBøR»$âêAdz][“½¥€”‹¹KÈÉNa["B>3lÒ§†Ò€ç…DŸéjþXh¬=˜ãP;ŒrØêJ6½®§Äg¾¢Áû_ï;0Á#òõd-ë1g~I„¸”kî7í¾=Ìi„.ÞD­çtA–IˆÞnwÃï0EÈ­µ¢í€]}gí(&0Pl,èæŽ$£ G£Áèzáo9)›c¯3cPtÃ2ÄYƒ$áÚ»«†ž‡íì£/">ñŽ{ìÍ´±‡‡‡7­¼Ó˜0i但3 ¹ï]_þ½Ÿ”ÑŠøåÙ@$ÙW Z…“' ê>™@ŸdÊf·li<Ú@ª§®&£’BƒŸ¡`;(Œ¬25À@ñpFõ ƒ -Œ:¨Æ3d¦Û2Ø3 õÂÙLÏ.»&xÜuˆÍ±Ñ›­´h!¾Ã}[/žÌ ñm ûNlkvsèH® Ü­÷“G Ìýú`úõ™N-|j5O-†£í¦@ø÷Í×7L+ಠ³X ´¬8©¦^7hÆ:æd >lJr‹¯ÜeÂÄ‹QƒÚ¹€ã·SãÕiN¯ðÔ£aiôÄw÷Â眓]³¤xôõàóç_¿¯!‘£Ȉ  ©çÊf’[ÇäÚ+VünZ!ÏNRDLÜeKSß#Õ ;–æ2âg\4z¨å—MLÕQn­Ry¡æ“^ -8(Êzéy/%c]ïAÛ†Ñ)“,¾ÿ³$ÆIÇJb.N¹€±wʔۄf\òg¬rWãÂg[šF(“ÙµEœç@Í·Ê)|2¯ù0Á_¨ -0ð´û‡ÄËÎM¶¨Œí†‘Z”ñà|3—0‹vns¬7Á>“‰/BÇÁž„ÏtRB¥TBñ›ØDYDÎ%9» |©"ÁFÕ¸ÊY(tÿØsxìYHÅ6–ò虷߸Ê_ê/޹Ėå’ÚÍÁéxÏFÈs¤³çq‹0/Ì{²¡Ð6A@€“\殤ŕƜBGœS€[=pïéxû¹Îâ]’ŽJƒöÖØX1q‚ŽТà_—•PÏð‡5òN¢\ÇÄu×îwrØj:¯ŸïÈ -^ ™ëù›Ò$þå\¢==å°Oµ%GÑ¡æ2hüš‚Ó·æ«$úéáÒL²ä!³©]jc*\,ÏGép…QT„ïÝa<ê+ÆŽàîœIÛÝÀkŽûËZ$E3¥ÇR ¸Ú%¾Ûwê*‰èQnžâ Ù` .†^˜ÇœÉáÐ.ÅÇ@\ë ;ö²x¦˜ÎN –ƒ6ÔìÖ@dŒ1ÍZX%ùŠÁ„”ØjP7O:Q2f -«b¨´b}˜Äñ± Ãˆbqå†gÿ±¼ûÀ×”J‚qÕ_ðdô±ÜyJ@Mìdc–Ç#ÛW‡‡i4û# ý-lÎ@!9àyÎEc¶ ìï©Y6Ë0 HYšeÚbºR®>ya> Dáeipå_Æ_e€Qø“ìiŒJS?Ì^étx¦(èQ›=—ņ»“ú2qõ%Œvøœ€w‚lKyßâB¤m¹™à¿=\0±‰”0ØÂ„qH8›©ÊØçL|ÿD"UãðEv!°À¤IÖE3¸jàŽüúà-^+oïÏÝHøÁâû_û²3̲T^O²œº4 e¡Ø¶ÄݦvB~ PäÁ$-Ì(-$Z߃UJGp!ÀDRÕTC… ‹~ '-œÁ°ŒÄ×?ÿ!sÙœ±¹„+¦>­vs¤:§ÆžÚ™L™¹9­Çž±Éï%–½D·Õðøçoj]®]M~Y¹×mW0ÌrMü}„Ó’Ä×iÈÜÄÑlÒÅíÉÌG½O -endstream -endobj -1333 0 obj << -/Type /Page -/Contents 1334 0 R -/Resources 1332 0 R -/MediaBox [0 0 612 792] -/Parent 1318 0 R -/Annots [ 1329 0 R 1330 0 R 1331 0 R ] ->> endobj -1329 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [333.634 593.784 356.105 604.633] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.1.1) >> ->> endobj -1330 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [426.621 512.541 435.394 524.496] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1331 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [339.103 320.829 361.575 331.677] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.1.1) >> ->> endobj -1335 0 obj << -/D [1333 0 R /XYZ 72 720 null] ->> endobj -290 0 obj << -/D [1333 0 R /XYZ 72 544.974 null] ->> endobj -294 0 obj << -/D [1333 0 R /XYZ 72 409.49 null] ->> endobj -298 0 obj << -/D [1333 0 R /XYZ 72 340.754 null] ->> endobj -302 0 obj << -/D [1333 0 R /XYZ 72 272.019 null] ->> endobj -306 0 obj << -/D [1333 0 R /XYZ 72 191.329 null] ->> endobj -1332 0 obj << -/Font << /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1338 0 obj << -/Length 2861 -/Filter /FlateDecode ->> -stream -xÚYYsÛÈ~ß_ÁÊKÀ”Hã\yS$;µ©ÚHk±¼ñÆy€€‘8kàâ°¢ìŸO_3Ê´k½/DÏÝÝÓýu÷0\=®ÂÕß¿ åû·Ýw¯ÞÄŪܖYœ­v«<^åQ¸ “|µkVÿÔ6ÚÆÛl½‰¢4 ~œžÖ›¤ ƒ›ãdúnýŸÝ?^½ñ7ˆâp›Ä9lOëÚë$e0ºaª§ž"¨¸9>“>0ýd¦=S?_ݾM.€Va0íÍ(KùT¢ë -¶”þŠwô§uœz«–{Lg®7q#•e{µ±¬‚lÛ2M™áþ„ -ÎÔL#LZñüFiõ¸]oT’ß˦I øVõd€gà eÂàêæö=‰.ü}äÓÑN0-{ªøón](¿§yý¨IøðTêCO£F‰Ò’%õ=#kýÌ:lzîìú‰ Ð?þeõ÷1ÓvÉ×î÷É }w»€«’ ÊQ_§·ÖjNGí­£€ˆ7>Ú >U¡g.…UÔŸL‹’ÂÑf¬î[͹ët­Ç±ž¹£î»±·£y$&AG$iÊvœ.¼âDTgRq“l*#Ì­‚ªÓ¨ v{=Èó^B¢:y˜ÅLØœ =šî±•±º"- ‰=h¾[F…\6“x[œ J.¨rg ˃7¦%ýùE„IÓ­Š#‹0;–8òÀhÐÊ0 }+£O{ f5ÈTù²)Gd]ŠOŽ -ņÄÝû;Ðà­(@V£"¸$ûs?O2k`hÏØœŠòàží€-û^ ÜØá]hP(ü~Ë­Ý^ÕòÉ$±Š²ÅXpU‚ß¼QŸzêêvnd‹Tœ -x–;þ½?,,Ãé2±êšsvhQé`ˆ£.äHRõpZŒŠâ`œkØs¯0âf9úÈ®yž'\AåTûÚŒñâqÇyà¥dö¸¤ùÛè±Í12&-¸ ø<] ªG$N¬ôÈg!öYpœh"cMPLBUHüSîzÑ_ª¦!ÝñøøgÇ_C¢Äö¶¦Ó¾£ÛÞqúŠûe¥ï…øß»u™æ„I‚ÐÜqBÕ}!Â'Û°Ìœÿ­ àA°içou3wMÕÕ(L3÷šœð#7?„ixõ;®€Œ¸ó‰R¡¡œ'±°ë pËöN,~ȬU|YaÈ ‡Ì#|Xkí¬enÕÖsËHH{»]P æÑíÏÄØÏC}6©ae¿Jr4\Ǹ@4"8³ÿ‚âPM5ÎÁ5xw¡Ÿ»ÂõËêØwTˆvÅPx¶pŸýS=ð”)Êš§'ASnõ@'ÃS4ITñ"šPK=T!)€*mv¡ŠÅ/”¤-0ºÃD“YĹ= -ú±GA¿®,Þ㨓VaÌ>rU”Ö¾TyrÔâ‚0°¸ .¦M«îQŸG>æ -áÑhO³…Ndžô °ÍÃï­ûoEm½ÀLj\M¿7w*»/‡zÄÁ>°w -º0ø-‚Êì²=˜^1õú¿¤8Ns¿mÅ*Ûf¹Cû›º®F˜‰ß3Bå&±ñâ*ϽÈ'3$Ï‚™Q¹©®pàaпΚó5Ø•PÚ{r‰ÕÀ·,hŠ:Íc/uƒ©¿¤~ Æê ”çi2™ð4g÷©æpl Xs ïP - v3òs ºêÀ÷´gÈŽ 4¢"b#ÊãÅd€žG·Ò1÷}7Jˆª§sVËFB³·Æeü‹?Ö‚bˆÞOˆR˜á`£"ÅYä»Hü2SìÅ8ó8G[Ê)¶üi§'Ù>ðÝ\p…É{Q ƒ=gÔöÂôh·< JW„¯@=Õ_¡-²Â»åsyãt¢ÛSY¹4m‰ -„3G‘‚-(_,ˆŠîÄ+ # å4Õâ%V™YÏ4ÂÒCÆ¡3Ibenòmʈ>ô3Õod]žùÐÆμ錣bŠ =¾Ñ]žz‘X*U…Þ&#Õ²yį5'eoËY=f<)â?ÊÞ¦ÝÃçŒý³· Ú*ïs¡§É¬«@_·LûÆ(WÖV-EvÆ¢QJØqœºñ‘Z9Ä^b84nÞ¼±»ëÎâ?…›GÓušòËÝ([±±Ål wlA;FÀŽÓàz ¥ÅåºTÁîî§×¯oQ#ið®={‚æ§!wòµçCœn“,q‡l#‰ 7†OF?}êv¡â…ר£K„sËSœ¥ìéð­øƒiÜ A£3ì¶iÀÌêËI¸y†s¢û",„CÐâH"<ŽÛ'¤Cÿ8Tldœ_ñá’ï@†q÷PÚÏ “µ4æn„H¢ÿ§/ÎÕ’"`~ Ö`‹÷ñBâù -Œ¼œ) »Â/J¼“€^¯æ5¾Ä^AvOã¿ñmäÑh¶ãŒ3h»—”Ly‰?¦ ¼C@×/³Ëx‹¾“É’^È -9‚|ÎhSÓ>o\Ð1x¬õöxï-ÇÕâv§b[Æå—L†àµ{ É#<çÎü:ÛÜ_oÕ=4Ù2rwµÇ6ë/ì£1Pö5´nÛù/·œ›=`ܤN~CÿÌ­kˆwSu°õ÷Zt¦‚dÚœSá—À(äWizí!ëˆRÆ Ñ-»›ÉÞ¤~” ¾"dž¹ÚDðÓ? Ç‚•¯%™ëøËˆèðH'K> endobj -1339 0 obj << -/D [1337 0 R /XYZ 72 720 null] ->> endobj -310 0 obj << -/D [1337 0 R /XYZ 72 720 null] ->> endobj -314 0 obj << -/D [1337 0 R /XYZ 72 646.339 null] ->> endobj -318 0 obj << -/D [1337 0 R /XYZ 72 577.604 null] ->> endobj -322 0 obj << -/D [1337 0 R /XYZ 72 484.958 null] ->> endobj -326 0 obj << -/D [1337 0 R /XYZ 72 392.312 null] ->> endobj -330 0 obj << -/D [1337 0 R /XYZ 72 364.569 null] ->> endobj -1336 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F16 823 0 R /F23 825 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1344 0 obj << -/Length 2032 -/Filter /FlateDecode ->> -stream -xÚµXÛrÛÈ}÷WÐyHÀª%„ËUµ›¢¹’V±d©$z•d¤@bD¢ 40V.}üö )B¶;|{fzúrºçÌPNoÑsz'¯œ'ßo¦¯Ž=¿7²G¡ö¦·½(´GJõ†®c;þ°7Mz¿YwØÿ×ôoí¶ƒãhk J>Ì“îiž¤wiRÇYöÐø¾o}p}eâÅB'≢ÄoE uÞ÷"kg¼©LW¬sŸšeÚw­œ‡ñŽŠ6ö“°vRp`¾½à¿Oe¼íLüS¦³223K9ˆÞÀSöÈÂwdG#OLd¨†V±î¼¡›\«„í1 -„´È+V1ËØ°´*@9²’ô!…[Àê'pæ`4ú‘oýÐ(×·’Øh=TâE% ` Tïð¹¥RçñJƒ1—Í®K´lÔ(æ2]¤yœ5nˆG`0ºñQÕsܸdÕ¸"D€ÞµG@_ê89µÅ0…ÑsùÛýA0t­‹5e­ËØ(ÃÀ*rÖ¾¬gY:ç¹ °—Z„¬*xý¶Î'U½f«EitÒlœJË®±¬khÛß©1\ˆÛé•‹ W'¯z¿Ñ¾£¾¡Éк¥f†ÕUÑÒ„,€u ±á·[•útÄ*?#œc,ïôúæèèLÌi>Ïê„R‡QÌ_ó"ß8O5Ÿ(^û5Õ÷,5=¥yÈqƒ€UIóŒþ]6n0†ÁŒ!4Ëvï=úˆËDÉE˜ÅÔ›e¨¬ò#ë8mMáyî‚ä>¥ÈÈ,ÍáXP§R‰•˜ß-¼,xò¦)(ormb)E©ÎëÕ Øa¯è„aµb>>4h:GI¢Èb‡CL##â˜_Æ`"›+—mïÃx^¬V°‚rÄ3 ¸#áÜSÔL"H‹Ÿê”1lè3“lbfD»L"«kè%]æ»Äº^‚½2®D¬RÖ?°—Ø´L,;ªt•fqɾ5ƒ,|ªµþ¬“¾ýA(¯6â/o‚Üj‰ª³Ÿ§KŒÞqèô]`Û¯›S“†*ÀÁÜÄZ÷¢°AËÚ,x²ÒË Ã—™bu†D@lïÌÒÊp³ƒbq+f*£Wâ—p[² xf ´«ÍNUCNÓijØÏZàÒfþÒ#¤*œòt‘ë¤MJ„x’5Ä¡¤ÜäÀ›À¦-ƒ‰ºÒ¢b–E½XŠAŒ{Ô¤ýajÓþVd>ìÚ Êb%XòEyÓð ‡WÛ]í~jø¢+J¾ z<ÌŠ8leZê¼Â èžÄ;J—%&NtÆôW?R Q+â¼i´ne»9Ö o\ê0¸Zð¨å¼*ùÞuÓ -eZãëæþ„°Êû2%…Ž[vR^Hm^çuž¢ã* Œ‹¦Æ‹R›|Öh0ÚÓ²ÈG„ïˆÁÐó¡[˜ÎP?Î…ÂÈbº’Mg㨥9t@^‹&†TŠjJP‚4z!»´ÍÀx2½:L$ࢠèC0Õ’•YÊ;i^—冎}¿é›Î£ñîbztˆw‡ê8%8»ÂÙšªìTGî¤ye€>°iQs·Æ0QWœ ˆ©ì§~€ñ"0b^x ȫȺÌ4ñ©"–¼Õ¢ƒT„®ù%óü••íÙÁÓG.àéî€2Ñ&N³ªáZÆQÒcƒù=|à6$Lá1¼ý²Û¾gGò¢ÇP\^~®8LÎj8²®á 4P‘cÝ@7}ßC&[Û¦\¥ì`ؼ’; -ä†È=t´)É& -z—Ô8º'Bñ8APÂÎíCU¯yÆ”ò¬`EämÚ°Sø¯hCù—Š·@s øU.Áî‹}Ç—Ùîë5xCÌ›Å$­> -Ÿ¯ãyCèÌv´\BÝ‹ò¡Õ^g|âªÃ:o~løÎnM¶,üç;ºzꎃ D=^Äø€ -¼Àú÷$Îç:ãÁ¤XC6.°—õ3ÕÊ ðé+ œ>Îâ…LŸX4Üövö@\ŽòY±ÕóâNóþÔÃW>lz|&,²X¿«>}–=Í —eš‰÷ -ù±|E?bX¾–çÊÓ¸‰á}nZ™_ø~Cl‡’þ;±€˜tG6Øÿ 2×÷ûMÜÁiíeˆó?þø å¯AçÇU‡®ß]\·¥Ö‡âÃ@‡°â{Ž÷<žèqÜì9Ž ì:ž’ɯš ×nEoe‡7 QFÓƒoù<çÎBЛâ¹ôBó‚›‘K'ôðt£Ñ³UÛ5…»Â‹ z¶ß÷Ó]ÍÁà§U[ s„Îáëׯ§§çG¶“ñ´Q -lÏ¿P"?„Œ¼c³1bW7—"޼¦Žà†QÈúžwè ±?¼¯yò÷<¯Ï¥Höä¢Û†qÜGmüø/õ£öü¼9Á0ÓåÆ7ÁA4mz¨Ü¹ :ÜLÆg™}&#×ßÎ(^ä*ìruñîøô¼üÒ•K ‰—ç -w½ ¿äåüöò$—¨ËËå¹0ŒäC ì|««Q—«ëÓñp++ï[\ac¹N‡¯÷ÿ'_ûçÿÍÙøÝÛ „ï¿›«}vàgvèHêÅ->ñ´Ï“³·_b‡XHRrƒCå½,¥}z ökµí÷íàí3Ääj²Ÿ’ú -Qç—Ýãþ…íy#ÛqGðÜ÷mß•§e vvM_ý@îÌ -endstream -endobj -1343 0 obj << -/Type /Page -/Contents 1344 0 R -/Resources 1342 0 R -/MediaBox [0 0 612 792] -/Parent 1318 0 R -/Annots [ 1340 0 R 1341 0 R ] ->> endobj -1340 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [460.467 645.778 469.24 657.733] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1341 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [502.271 486.93 524.742 497.778] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.5) >> ->> endobj -1345 0 obj << -/D [1343 0 R /XYZ 72 720 null] ->> endobj -334 0 obj << -/D [1343 0 R /XYZ 72 462.03 null] ->> endobj -1342 0 obj << -/Font << /F23 825 0 R /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1348 0 obj << -/Length 2758 -/Filter /FlateDecode ->> -stream -xÚµYIsÜÆ¾ëW°|Uh€‰“¢EÒÅÄŽqÅeçÐzfPÂ,¢éüù¼­±Ì€rrÈAšF/¯_¿å{ ½‹Ý…wñí+O~¿Ù¼z{—\¤nºVë‹Íö"V±ï¹^_lò‹ŸœÍÞ\®Â0qÞÕ‡ƒ®rþøXTy}©çé Lı£;^èìö®>â uêíÉJ›5ÆTr®Ý3™ödÓ±)ºyæÜr}™Îæáãíí<›1C­{¹Š“Ô¹ÕnÛóbÑ^þsó'xâÊ÷Ý4Šø1æ“õÁGDÊy¼T±óÌãÏ>‹j'ßÄHÀ-McZx ì­«\6N £ÒðæL‹N—ů–riºoëLü%žï|Ü›ê„öñÒwšz×è-oxBftÑ —më†Wžq¥î›¥Ç‰<@°Aò%A;Yß´x<^Òµí‹R®ÖÂéx+)~Iò°Ñw -J§­&'¯E‘¬T¤Üp½^” n œJèÚP®æêà Ù:ûb·/áJ½³«?{‘WlyüŒ&„ú`B A`J¾öºe*ºâ‰¢B:Ÿñ?Ó´ÂÄç"75¯oîúÆ}ßœ¸©J'®¨À¸ŸàŒY?äï :˜¼Ð)ŸyRDXÖȬlì,­²h;¡£ª‰_ ÅöäÀ÷¦mõŽòö¯ ‘Þ4tOŠ ß9_ƒ -÷×bõxNϨ/pcþÕ`¢pÒóçàu¥Küíƒx8|±[œ?X~èÐ=ä«!³7¡#‰³ -uiÅ€»rÞóHÎÏä„®7øŽ] ˆw½þŸ\`F Ers¸jª<¼ÅÎë²­ÙšƒõÚ)Š˜ÖL¨o­%v5ÛPcŸšŽ'@š -¤™4õðÃ4MÝ´‹Æöé˜54Òaâ¡pÐni(«`781}M òV©önOñ`_7ů5yA‡jʼ@hø£½ÍÎ>Z÷ãy“ï„™ë”:Å4ËŠîgyÎh½+k’S†úÄ‹c$s—lò¾cIQœŠ)N‘ä5DׯTÂ Š¾+æ–VÙAˆˆÖH „DÖÉppÇØ£‡@A–…Wñ.ˆyĆÔ1ŠNȤ@¿kŠGtÒδ<…b›]5Lüìùa)댻“ë>óž÷UùŒ8Å_l\BtAˆ9€Ñ ²¢˜EÂdiÚBrXxÇ¥ne³Î2p{“'Ó¬„Ç“Q ]¥j˜)»ÎwöLi¶O‘ù¤]RÎMÑ~â)T -àf‘µ¼25¢Uø¤ܘYk/*ÙšDÚ"äg–õngòùÌçMÁÁcIÆùÕ+ºk "GÒ“¨S–ðM*€AŽÖØG®u™Àp#>+T Y'®ÑÃúþÿȘÛðY,Ϻ£~°GÓ -£úP÷ƒáM¶GÉ%9€èˆ­røæ…§³U°lÑR ¤ë ‡±ðט¹KHfQ°õ0ì…Øøö—l,€ r3y%„¥ûÂeG'Ëú#ób#®ñãüpžžï[Ï„‰Ðø›ß ;rGÑKMP.duyÜkјþó -?ö"_R(w3ð²… 7©Äæ!^OÑÓ œjM /&r9Ï0b´¦3‰bÅ©8 VåxcO° ->µÌ"9ˆÿ¦ÊäæûB»I⑹AE²‘±ù­ÃÌ+&2ñB2Âû¤,`x JÁfJ‹ä’CQ8äAd£L¶Sò}—þÌûŽ#tAŠÓCþÂXâÕ`>8UÙ“â‹0f àñÔg#/rî·v¿á‹¦ô9G…I‘’âˆØ«%±hD'¡‚0ÛQÞ<¯lñ¹@¯pÀW0à€£Qž˜!Áå×MEñ'ò]˜HióXÐ?™u: ‘´¯æ_ñr>ÃXJMï€Ê’‚Dà\K êÙÂ#CßÖ=˜+{9SëSªš@Ôò%~ÎÖrE_Ö:Ÿf},¶ƒ®,ìÛRÂpïXg…„#ž>˜Ü# Öˆæ‰I È6”Š8GCþ $V>$eÊÇW’œ ¼½SÓ²ž(7Ž|~Bè*×wˆÆ<ç;pe®ûcϹ¯ø—½D–××)¤‰(Pað¬üP*pC/±wr¼t,‡añ¼·r^èø*t×á@ç÷¿Qè¼û°D#t#•~¡V¥&þ°`¦aXICgƒ¯}I[FA / -æÑkHÛ©ÿªIâ>ZÝàÍ Æéî!ÍW™0Z0GC1e#šŒ8±5{Yø·t9‰ -]–³K?N¯ÌÍV÷ew’Œ,ò7/C¼DØŒˆÍø$0Rœ¥.¥X%1ËñÏ—QB$e'웚ŽU --¼v_/µŒÀèý4üÿš’,U"à{ŠýQbÁ—™dW޶5ž{*º=OjYëÙ(0ðne‰ô7ê!€Rìá&ÔZ¹Jª àÞÓÆ"½(óL7ùÌ$pdWHièÒÚß·w7•¸Ê ¤»I…Zió͵m”â×kwó͹¨NN¿çÌ `û¼Ýг ¡žÓô˜Wòo"Tø|ô$I䱿J 3q 1¨P6)SµãZd½!Á÷¬¦¦ÛþÃ'W¡Û´Æ¥ñ˜ÆÁùN!»õƒðD;_QG) %Ìm†B ŸÁ‹JP(¥ô8Ò;¦‰L¶˜ÕóeCoSXáø¾Z¡Trä;\¨wLolgÂ*XQÉÓÔ6¢¹Aøã#8¢ÑÚ"BP—Þó­>¤É—4ÙêFÚm­pZ>ÿK݈êwêÏI÷ª®°æ–nZeLÎÙ™/u)Ž“ÁîÚëj' Ž-©FîmÍ}ìÑÕÒ(ã¾Ù™aÑ$!&I?Qˆ–1² Φ Cx’0$6a°·}]æ'P,ûŠF’ƒ!r·Ò5MI°„ÖÁ`£ ŠÄ°"Àœ1=Y<©1ø·CK‰ û9"õyqÌb€Ú4·ŸðëÁž |>£ÞÀW¼Ä) n4Wƒ/ÿŒ:A#³4¯´à›¡C´t¡‹7Rëtèæ˜Óº¾¶]}鯋Ûü¤eým;ÛrA€1™{'°2ÁkPía1鞉´µçÌI¥@rpþæÃýßoyø·‡ÛW¹þþÖÝüøÃí˜pš2oçø)˜ëÇñ°Ù˜Æ=?A°ó¦ô­ ƒG>Û¼Ö Ù²}*W¶ÅÂ6?‰SÁnŸuGF&PB©»ÕªEñÝs§|ÙJiÀÑC¸”lM³˜%>BÑT°ÈÈýv!» -Ûï³|¶3ã´Ûýüù›Ô泺´¹Zú•Ø21ßÛ~æh‡oøÔИ2¿h´àÿ*+‰!†´_)A“kïjÿ§x\I¢6¡7«¼Ðõ}ðV•ºI’ð¡(š¸Ý¼ú˜á| -endstream -endobj -1347 0 obj << -/Type /Page -/Contents 1348 0 R -/Resources 1346 0 R -/MediaBox [0 0 612 792] -/Parent 1353 0 R ->> endobj -1349 0 obj << -/D [1347 0 R /XYZ 72 720 null] ->> endobj -338 0 obj << -/D [1347 0 R /XYZ 72 412.778 null] ->> endobj -342 0 obj << -/D [1347 0 R /XYZ 72 251.89 null] ->> endobj -1350 0 obj << -/D [1347 0 R /XYZ 72 190.23 null] ->> endobj -1351 0 obj << -/D [1347 0 R /XYZ 72 170.58 null] ->> endobj -1352 0 obj << -/D [1347 0 R /XYZ 72 150.93 null] ->> endobj -1346 0 obj << -/Font << /F8 826 0 R /F11 833 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1356 0 obj << -/Length 2445 -/Filter /FlateDecode ->> -stream -xÚ½YÛnÜÈ}×W ü²”¡iñÒ¼9›5d[XkGš1¼û@[#BRasâòó©êªæ°)jlN^fȾ֭Ojú‹ÍÂ_üåÈŸü¿Z¾Í¹È“0Y¬®™Aš.ÒÀ~”.Våâ³'Åñï«¿sŸ—±ï{gÇË(Š<­¶ÕrÝÖmƒïÒû-ˆd£6E¯ô3Q4¥z¼ ¼ú8ðÌú×< ®é¡i›å¶è×ÇaêÝÀ°ªÙð¢~ k¥ÅñRJé½=Î"¯íhŽú£ØÞÕê…#¢ý?}ù#å‚P¤Ñb†B†9évæÿé¹xýá§»–ði`Dã¾VVH­jµîI®Ar^ú›‚ûËÖ*ÖÓÃMqfÞ¿PAE-fsÖ¤W®ÚFOì½d¹ƒ\À8’'žõɯgç¸Xjžz«OÁ’¶µSôÐÞõ°QQ£EãØ;ÓÔ¼Ó»¢>ÁçÌ+ð/ñ ±êªÖ<ðª[Tc§{z»ëÔZ•¼t£†ÏißüØWb#xå‹Ooß½?«¬ #4úÝ5*d]"cRõ÷jwl[4Ý= -…4N ‚‘×d ÂH‚MÌÔŸº5©ÌmÿëË™%)âpòËÃ%@8?TîUÁ!Þ^“ã5K¸Æ@¯À×÷C04ô®èúj½«‹Î !¶÷úÄ9Ò°ª±‘¦8Ð*pAßv÷Ô¾Ö/´GXƒÖëU§Êiˆe©ˆÀ -NŒ%³1¶ºáÕtAVt%I[– çÒœll t8[öæ+£åŒºìy›*¢iªûT‘MS…œ¦ -=—Â*$cJm×=š5ŒB„ÐÔ@(¾ôÆawÖUØTàŸA„]!§ï #'Ñÿh„ì÷À¸B÷sFÁ±íË®'Iélë{Ùnð— qÜ]×nïxèuÛ¹&úR"y±8ül¿$¶ÓÛÐ[¡ÉÖ&SÜ鄼Ä1¸Cºi¬‚“†|’ñ¡n7UÒsYé[zº)4=püf›Wȱ1ìx'¢¬=„>¤<~J†ŒÈÁ8á,fbÉØ00¾ëuÛ•&_Û©à…î—[æÆÊ„ž£qB£l§}µUÌÛ>ÞÆ‰|]  ˆ8DüÔÁˆÕ“ü§€[w -özÆÙí;@¥5w 5¾S…ñnRb=kh¬JÁ-¿ê¯Õ˜EC‹qHÐ[!)]…ã †ýİÏce%˜lö¶Š·Ur­Þaݲðß±6ÜOÂÅzè{ç8ÊDOÄÉ‹`˜rs£†•鯆"”r6¼ø,Í5ϳ‚Îók3´èf[ë,3]1'$×ÈòQ ü=a7å—áê~têç§YL}~øÂ‰ÉÓôÜ>+?[u;§s8XNݤm%2š>[µÐÁ~Îð‰{9ª>Î6EÕœ8Ù8šµÇ¸n{ˆ–*gÿÏkŠ[ãÒû¡XgX*è€Uj_h +ÍõdèTˆQ"E(¾Äú9ˆ­ƒ€­ ðľ÷¶.6-”}ßUÀЕ¶m"¤g©•’Ð'ËrÁ,÷ÖívK„*ˈ'ãCÛ(êF7EmçwÓËu[Œ‚~_ D3‹ Ðç„ - WÛ8¢%ãbäž%uN°MGãk®0ɽKs+„˜Álä™wn±z úÓ [­è¹¬6UO-ªU?Ì0Œ<Þ_Ešq&K’–ËÇÎý O2¥&­X˜³¹ðLc‘í“ùžÙa>~o»YN!¤ÿÝwyW1Jøú|N)YpÛã-e"ÅëáuåúèÂ%Ý`»ì jÖõ®T‡.þ= ¸`cY Å—]ãtððñ5s…‚Ä©÷ûLê—bÌV?C AÃZ­«/µ½WÄ[xˆE=¹Ë hÔÓëîv¬ž½%éx±B[c£¦šä|uôÏ#$Ïþ"X¤á"HrFñb½=úü»¿(¡¤Qž-¾šQÛE˜I!ÍEo½¸:úÛd~œ -? Í÷ìdšþà;HšŠ<Í@_$ óÿ`œ ¤÷Ì%Á4íû¶(÷¶ÛŠË’ºå¬ln„mo7]»kJ{çUÚ²ˆK¤ÆðNýÐ2QœŸ®žk‹´üÖ‘™Hƒé¤kxS’$ÞÇÝ—ºZ‹ùŠ=Y2W±(‚²ù‡¸=JDóç¯ÈUì ^‚dxÛô†k€á˜–móÓ˜Úã½ÌwjþdÑ]Í¡n ƒøGhB†÷Ù¥’éMî¢Ô%kìrøìÁ%ƒÐ1^-Ðõɺºú?$zlf’|e>„ùÞÕ½îÕÖqÚ@‡¯xæ3YÍ챬ô]ÍtëÐröM´ÿD3TóÖyªzŽqòTDþ‰Êõœãà ñ8ñÎ:f‹ã[éo…ö“Eš*øÉS2Á£Ÿ¶#qãªô 5q - þ? ÝƒO -endstream -endobj -1355 0 obj << -/Type /Page -/Contents 1356 0 R -/Resources 1354 0 R -/MediaBox [0 0 612 792] -/Parent 1353 0 R ->> endobj -1357 0 obj << -/D [1355 0 R /XYZ 72 720 null] ->> endobj -1358 0 obj << -/D [1355 0 R /XYZ 72 720 null] ->> endobj -1359 0 obj << -/D [1355 0 R /XYZ 72 661.489 null] ->> endobj -1360 0 obj << -/D [1355 0 R /XYZ 72 628.264 null] ->> endobj -1361 0 obj << -/D [1355 0 R /XYZ 72 574.25 null] ->> endobj -1362 0 obj << -/D [1355 0 R /XYZ 72 431.729 null] ->> endobj -1363 0 obj << -/D [1355 0 R /XYZ 72 330.526 null] ->> endobj -1364 0 obj << -/D [1355 0 R /XYZ 72 299.238 null] ->> endobj -1365 0 obj << -/D [1355 0 R /XYZ 72 267.949 null] ->> endobj -346 0 obj << -/D [1355 0 R /XYZ 72 238.62 null] ->> endobj -1354 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F11 833 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1368 0 obj << -/Length 2223 -/Filter /FlateDecode ->> -stream -xÚ½ksÛ6ò»…¾¥‰h‚ ÒÓ^Çqœt:M.+s—iû¦h‰JTIªŽÿ}w± ¾Ä8ušéLS‹Å¾°/¬½ÙfæÍ^yüû|uvþ2šÅnúálu7ÓþL Ïõ¤ž­Ö³_œ7e“Í—RùN³M\Iç†É~M‹KWÙ¡Êêl?÷#§±g2Ú^³‚@ҹ͛Ú/•ÎeM $R 3MöÿbÖ Âó%ü°\ùÞ6{„gÖÇþÿ–«šÐʹ¯?æD˜I—ô¹Kªô¿­~C-…pã “üê‰ ÙÔÏII5I -†á±nèëX£ˆR9å¾x EÖ4$ìh·æýÉÞ+ Mê ¬då‰ÜØW8IQ—D‘/Kö- `°$A;‰RÜß–ÆHe'0S$]™zC› K˜ï‰ÄW–UÕUEVó]¥Ó²_JvÀb©îˆÐ¯^àý ÿ¥emœÆ ¼ÜÉŠ,ey®ÊÝê dÐz¶ý=)½ž?rÃ@ÿt›~p›OÍwWïþ=_~àð'ÏEpEô%¼ Ï£¥ÁNøÑMŠ‚¾úñòíîêÿ+«™1 -ku×dl,¦(¯“ -ƒA)G¼ƒO×íöbá¦åŽ4œi°Xœ›ÿøëbñUŠýçõ„J%û׺Ê)Æçù×Üù$½‚|ß·ÒÃÝØ‹Y,_%>ÄfE² ¼Ë’u=¥ºð„›¡h^ËùKÄQúnd=\¹¾ëƒýEà9ïë|IçÅ\B¶›Ç¡³ºùßõõÛiÉW†,ù -3‡ -ò™pL89¬Rî²d_ÓƒH ¸ -޼*i W„½@ñ/çÀŸ¹hÎ'ëcñb¾ ½Ày]"®½D܆t-ìšh—9%{4%ÂJ˜ÈŒC¹Ú3æIÜ1Ñ[tíðád*ù¦ì“ÉĘÈC#&é4Iç‡É|_²gç@»RE@‹“»çá?B¢‡¬|¸ Fœð5íjw„AÒ û ÿÆŠWdw  Ölh;™´& Ztp6=V—XôU%iÓ~£ÑᦊìRôœûmnÝIåLšŠ®¶ùf[À?º—ug­’E«Ó*ËÀ¿ÐæËH‚SŠÑ­$‡ä¶È†Y|]’·¨.ÑœÖ.)y¨&-÷lMò±MÒ9IÊ9Ä´¶„šBç×ý˜ôŒ÷mYÝ2µ»²(Œ‡ß·Bß+×Ýíd#Øðí†õv#ø(@(^¯Î~? 7ØjÉ|JÊYº;ûå7o¶8ÈîÊ8šÝ¬ÝL¨Èõ‚ÖÅìæì¿£ó*t==v0é¢èøiçÝ(H»aÈ×ÉUVSQùÖË¿ûBܼÅds‰F¸ºž ™2Ù>SÀN{mн +Û2w‘ï³Sëú¾gìöt -,•+|ù-,,Á2‚ô€ÈÔÚ“Îû—’¿¤É“Ejâû®Ÿì+ƒë²ª@aÒ¶¤N]šp½°õi7‚ªØÝë—ÜèêÝ å~üˆïH Ê„úÎ!Ùú{Iv©BˆÙ`Ô‚ÌØä©À9튇AA¿‡%@{ûˆUް \˜¾R©n‡V;÷fz;Ðhjð¬<Ý‚è§u¢ö®[aø -m5¨sKø 9^Sm:þ‰'‹‘[D†)ü è‹ÈD'­ˆƒAø“ˆ­?¡úäî5–±óªGm"U+uZÿý*ýÕW‹µÚâ+Ã(½IÌót8@ -g¨é˾&q=Œ9 m(GVBÇ0/_ƒš‘œ°z¿ãïRÜd’8}Ã+‡(ôûo•Œ Ü›Éy€fÆá WŒÆ“¼¹0"gBr|`S•Ç?!È0O)“§,¿¨ã×ñHG oué)ŒÇ¶Épæ$aOx+%iT묆Z³&h/ ”=¯FcÙþùVPR´XR×ÚðŽ«2í— /Êvj·pJïkD¸+«>KXª‡´Ý¥bË”¢GIçjª29š5^™(<õ(ÛNÖ—ö>ÔˆøCé{²J¾Rÿ``ò8"Šh¤²eŸ²ôذ¼4_€Ek-ü°ÖÂABÂÞkžoØìÝ££'zÜ6³øÝgŸ¦ÒNàvN ©7}¡!ÜÒh§j,¿ÜŽ%À¢ú3³"Ó½4Ñ…‚肸¯»Î×ý‘™H ð41 ” -®LQÁé‹iÄêÚÁóß:"± ˆñKú­2@"q $•;¦rw¬LpLÄh¾? B(üõ±IB~ÁÁ  mCˆÞ&ß}PAvêÆ€KÁŽ*S¨9¨£–r(P«µ X†‡Ø¡îý©P·É0 Ag^ä&“ s“¡‘±V½YèXå ·yõàO ¨wíßRTk[æiöU ø€äq–ŒŠ·3e³:§ŸU²Ù =Ðû}s -|SØH~ Ï”xÇnEÄ;Ѓð<ú×ι³ -endstream -endobj -1367 0 obj << -/Type /Page -/Contents 1368 0 R -/Resources 1366 0 R -/MediaBox [0 0 612 792] -/Parent 1353 0 R ->> endobj -1369 0 obj << -/D [1367 0 R /XYZ 72 720 null] ->> endobj -350 0 obj << -/D [1367 0 R /XYZ 72 472.463 null] ->> endobj -1366 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R /F23 825 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1372 0 obj << -/Length 2221 -/Filter /FlateDecode ->> -stream -xÚµ]sÛ6ò=¿B“{8ÊgI~i.¹Q$;qíÄžHN:Ó´7ŒDÙœP¤JRqÝó¿]ì‚”L9Ñ][éÀb±ßXb×îÜtìÎëg6¯fϧA'쇞ô:³eÇ—_Ø}Ûñ;³Eç'ëlÙíI7°î»2°ò -*\ܯaX1‚|kvÌ[·1Mæùje Z$%aE›*_EU2Òôž¶Š˜éDUÌØË¼`ô4%È'[¨4.™ò¦(â E¨ ‘OÂQUts/žà.©n™ŽúÝž¡5ëJ”Ö:Énh뚆ENr”ÝŸg?€qzBôC×%3DY·ç¸J+Ð#‘}™ ¹ÙEy×iäEh–3IH$ Bhød»vÇ´øLôÓ¥½£Ú*¸y›£îwL3§] mèhÖ@N€Ê®íi"JíBD+ã4ž³\è;'ˆ0êŽ5›~œ\í³Å]¢ÕcΣ¢¸Ç)Ò­¦@ošÀíèñnm a¼‹BH Ç´k¿v)¶„UT„•Te}”'9ÏhQdѼJèôóGøÓ,„ÅRii2"q“$ÏvI£¼{LÅ¿¡TŽÓèáÓ÷ñÀàTnß*8îÈ~ÀwJõ%ü('\"2ô, ¢ãQ©À:ù-Z­SŠÃÝË)”Û÷<Èi:3t•9页.th|M:öÑ@öо -Â-CŒe ß%> mƒ´ômàPÓ§—›”¶VquK—…qó%Eœ7Q–üŽ¡ÙzFâëq b8‡uÀB°zҵβ¤JtvÝÀ_Ê9òC‡âA[¢S/4†ÎN>…6`­"žˆº–ö+ÚÖ® ñT4‰hÈòOJHJósÒsÚ]À”fµ4tÛ h¡#©f„•§ ¦”_öÅRÏ·²™ãHp£Qo “¨ÐSc‚¹Ã*+°Øs›RÖ›²¢M&DnÀ1ÉL056á[zü©3Œ"`×´®% ýa²!nõMO÷è{Y Ó”§¡$úë _v%!õEs\}Ù¬iwž¯´-Î1ÎO‚C‘Næç]}î6Ênâ’9 ºST—“bi©‘Hí5„"æQÿqÑ+tŠ)be¢Á|ASÛw„r4zØçð¦¸yWþú;Ÿ¹\WIž1Ñ«"É*–÷}¬³ÎßÇY´bü)Ç1Îg‘‘á:«êù‡$¾£ý ºgñ‰f°ÉÃ^ƒõÚ?´Ìô.Ƈ’ø -Ÿ,æPGÂ_¼xI“ÑÐÛûj(Œßrײˆã!ó¨ò*J‡øµ¶¥k=u9ŽÌ™Ð¶Ù–Šß%¡Y 7Îù„ô=œ#é‡Þù=Å1µ8šÃ2I9þ@{ Å P´ó[H—¦ôZ°¬OÅb½` xÞ9¦³’¸Œß |H W–;m‰`(|šFóy\–ÈU“88nþ -‹9øJøšÕ‘„öðÕÅèÝ9 Ø_â3_Ò¸Rˆ e3Jg¨„ÑûÛ¬dŸíY³.Æìàôö1'`#œÚŒÀÉuãä´9]œ3õ-FutÚÞ@xµJÂ*¹Ÿ‘÷ˆ‘j3ºzÛ0zcnÂ7žÛæô~ÜVI¡šŽ÷]r^Ëí“Ñìä[¾ðÕ(8-‡ê@_øû8M?BÄl£ÓHDÐ𠇘þá´ 4™ÌÚò4PØ&wr:º¾˜Ñ(Žÿï‹ñ(ФÝ6ÑÙôÜ¿bè#é /°T“Ö¤d&)ÚzíðšìÕk‡—ðœÃxµ/üd:¾|wzözËõ¢ÑÉ8övˆ¹òqÚö›žOg£ÆW53µÏÛqfåw Øë½ä¤(Û·~rYÊ\ž7-ní¯w˜jn[µV­TÖæ¤¾„òÓñáé2Ý ›:Ýá*}Ò…²f„¥:å,x¼%ͪÕéPc³ð`ÇS[”êŠÿTö(õ/×ø@ ‡ Á˜æ¾ò?ðúB¨ºü×…mª-œÃ‹»i5E[š'[IÑÚt¯ -j,aLª5l,{Ö¹ƒgdÝoÂÓ3J®ðY¨°XæiJ§J.l ¼à -“ˆkœÏ¦ƒ¨ zrÔµ.n7eN¥K=¬‡Ihª•L $TQrC&+®{US¾L¶Ä-HÍ¡dßo[à¡û¶7¿¯üºóÌÖhjS›É¦ Ö­Q …>¼ä©ëE35Jie|’±»è”kS %Hc:²ÕÚc’ɲ¦‘ñB÷8<ýÓEo :6GÓÝêNÔÖ`^°OI[Ú›HÀDÍ*ë‘}à.†;ž-Ð9žk}Àû°äR6YÞÓ%ÃQ7L[›%º9аŒÆ´t¨5 «¦+êÕåF”/Mðpœ™~§Zo7i•ôêKMAÏuðyj+øˆ;5LŠÍZ?¶Èñ·¿Ì¡)\‹º÷ëÂ!Ê4A{jäæÑ¤Ð<ÏtȮ̅#Ú$°_`^:+¤œÀ:íBªÑ]@àúü˜û“9×qç“Dæf ݽ+SÇœz`B5C°ð¤HLÓÁ¯ªûÔ{,`\Š”æFÝFàKNUëÎí˰6mZüñêì -{}ø8ÞsŸ«ºaß$ H¼;Üœºo¢¶Z_ÿCB’R¯†ô5B™è›…«ÿ¿¹Cm7HömÂ} ûß+7Ø9q2{ö_Ô©7³ -endstream -endobj -1371 0 obj << -/Type /Page -/Contents 1372 0 R -/Resources 1370 0 R -/MediaBox [0 0 612 792] -/Parent 1353 0 R ->> endobj -1373 0 obj << -/D [1371 0 R /XYZ 72 720 null] ->> endobj -354 0 obj << -/D [1371 0 R /XYZ 72 658.294 null] ->> endobj -358 0 obj << -/D [1371 0 R /XYZ 72 250.822 null] ->> endobj -362 0 obj << -/D [1371 0 R /XYZ 72 224.469 null] ->> endobj -1370 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1376 0 obj << -/Length 2775 -/Filter /FlateDecode ->> -stream -xÚµkoÛÈñ»…’-uˆ6\¾  -8‰}h›4©­àZ\î-®d"©#©ø|ùó×R¤Ä$v‘~‘–»³³óžÙYw¶™¹³ŸÎ\ù±<{~™ÌR•F^4[®g±7‹µ«\?ž-óÙ/NÖÍ^â;Ý­áÁ®©·»NÍ;ç-O¶·Ån‡CÇäÏà?õWsø:Ÿ'³¼þùââÞeÉ£ªÌ«z‡ ÷üU¬ñßs>¸:(Mkwu·Gd´ÙVFU?º»-VˆJ`ïplYÜÖð;y˜MΓ–»º™ÿºü;Hd¡µJÃPx_w¦Á]®œ 97ÖNWle.kd°®÷UÎúmÔNnÚ®¨²®°+yS|" -I–¾óŸ9²çÅUf¡Š6»)í‘·E+'™¬Û÷Ç‚JŽÈüà†î[øÑ;<°åí[Sáû)^QÄœéûUT„)^B¼ÿ¬;ƒ_‡”-¤m¿×6β¶2+Iiºå¹›Œ´õ‘a÷;´¡þí1síðIžS´ Pf͵#té¡öþÁsÙdM&ÔN±[¯ -MÆ€ÌM€V@“dš8(:^à3} qÑÕ‹<ëŒBÙ"âç—ÞÐ}ð˜D¥^ÊÇ ¸^!(laè!°«(ô`Á~3@3ph¥Óò\†V…s`só…vL êHBß¹§[ë{†ø ýàeÖaž‚#†n@3ç«ÂÎ ŸöMMr@ð”#öýòV¨ÖzHv*/‰-Ý?ž2«8Híú5ÙÏ9ªúåÅ:¤Y连bÓž‚Xc>’ÏÜ3­â·‹ÀOUëc“.óØè.¢È5Ù -œºå¹}kx@~CPûl K;ä,Ï£9ÂÍ—0¤Ÿæa¶½ÇÝIJê&Õ¼÷€Às¶{ô(™!S÷ÄMÖ9Ñ Yæ¤Þh’‰ÀqÖ45î¾ãÏ;tÚ¬eBØ,ê‚É(ªl¯G¾‰œn z 8XÕÛ-~°ç¶ü±Á ;¦z†ß©ÓCu“¶¢ãPEQúP[yy5…#P¡—~Í@´ -üðÄ@*Ðp{Ì*hZn0Ƥâ˜ålJá‘be÷š†®HMþ³ÍŠŠE|ÀJ†é¹©òol˜ooÄOE½oK4d/”Èx`;N8&ÖÕ_ºþ”Ú|ä-˜)qöž€ˆ!^€”ñ‘—gÈ&ª¢+²²ø ®_¸BѦ˶;â—И eZl‰“…2e.EÌÐ-/f*ä>yòdù·7Vƒ\Áa•-]@=,¤^ l“µS15U!XÏ!¦ú®E@Fžîöuæ\ìçíÇ–AXÁ.–#Â4[IÕ¸©_lA:å/ÔUiÝÛwSÇ£Ž¶1¿)u(õÁaž³EÝ¡êÊ®XôŽ.C~ìÈó¾êsÙB˜+{HM=ñ’¿ZÉ_ƒŒµoV‹Ô:W@Yч<És'2€9ˆŒá0HbDà`³ÿAâÉ$ :W¢fi¨×K$¬Ì6j ”†Ýµú §Jd]×7ûŽõ¦Î>¡•adÕ ŒKÓuF–kùç -‰ôrC£iP§+Ž þoOßA6aÂç±´´Ë ßʾµEm2[âÈ&Ì0hø©È6±'Š’™å‘’cÑÛÏ WŽÛ,gÀ%Ê£j¬Ÿî™èï–bâ p²<·9-+™ƒ%ZÂI°,‹ß·‡“ŠÏ.–g¿¡û¹3w‰ÐUijÕöì—_ÝYó”Ÿ&³;‚ÚμØW^À¸œ]Ÿýëh¿ç°ÿµýîL$ÄÛOo4±Jã0Eð/Ʀ™ôZ -¿× ÷Àó ¨½®3ÅgÙÚ"°„%ó0ýBj×Mƒ%¿- {qŠác´ÅêûD2~Ïgo,Ê|É÷Ž•ë,o,¼ºùQä¼{ÿ¢„ VïÙ¥ù -c¦lÄX¦*H¾‹Ú]_¹‘¨Ý3ö -ã«è«¬3µƒ&9ëâLŸ‡ÉêËœ?žô1çI ÕNü8R­´•ÒñMç -ŒÕs]ÈYþ¶²®ýMMã˜E¨ Cøÿ,Ʃҡ(÷Cè:×÷h·ääѤŒ9‰|é(Vž+Ê:ÇâêÏó†Fa««±ôhšNX -tò˜€=ÕC -‚Dù>³Ó76(¡dROde[³1ö™¤5Ìh“•SyM êje$ ^ο·eó;øhiž‘hÜ£>×óKß×^ ¼@LçêÕõ/¯&nGpÛŒ/RVe#@@Ù3ÛN¨ƒ BM2a‰.OCØŒWs6䧖ײ—„È0èëúX•p´˜¹cÆ•ÙÄ•;•¯£ÿï­l„bªÄ¢òÿ´|ƒu`=÷=¸WÀÏt™¤ãz‹¶‚´³¡ÀýÏ6uN ;kd¡ë.|-Wp´°õP±í$íBÀ éWˆÆPOò„èÐS‰›~›è¡A!¦ÖÖ|ÒÐ8.ô¾2žo'•<ÿ»Û,„ƒ±ó@ÆT÷{÷E’¶!ÑXJñó.ÛlLþ|ÏU;}Œ4 PµõKygªV.(A¯5µü÷ò÷÷ÔÊDmµp73Lè+J Žî’i伯¾åo&/É*å1°Ìžèpï€ñáuÂcŠk§‘ ¸sÔã£5þÃj³ ]sÌ¡_ºÍt›^F·‰¾}N³¶V"X³ìçßô¸ï)WÀä Uƒ±,çÈÇf#­©ÄyÉ'¼³¸.÷¯ÏQ9›¬¨&:>i Ò`¨™ ËïèBD»6>Îo)Œ.Û0[‹„’]ÛRôœCc£‘ƒTWÝAntXèþÉöƒAÂLÛHÒÅn|A#ÆABÑ›æý`ïæ¾¦ö+-ŽÏ´à<ºCåã žVRÈ%]fßSh+ÿïJ¸’òPŒ´(Ÿ88O!!¯)oxÍÀ.\S„+ÍŠn–®îGxg[7Cb':Bˆm]—¥´1ûÄ .ÓÇÌK¸hѺƒÂ¢&ÇPýŸ?§ö¨Ç$чØ&HçíOÞZqâÊ [ -¯€Ÿä›`¢&ˆŠ &Ø–Ýöùc±ßÖÛKlt‰<ŽÀ‚ô•å´Œ[¶šOuv±øÀÖË’^)¦:/ZEáqÒZbÌÊ6ƒÞÏ8kõ–< -#Á”ÿa¾ùßò-“qB7†q]a•ÐMQxP^Ç#ê]áÔÉ`ú]ûâtÈ;î˜~}èc¡uQõËB“k-PS3íÊv‰\rŠx„›ó•;ö%DÜ ¶j@Dï…ˆž3\Opeî, ™ö†&«,Ái,ö%¿)Ú•)ˬ2õ9ÒñT4þ‰(ᄱŒ=ÐIt¨&?cu9ïöeI}•„ð›5­›ã·5ªy®î@â5ÊeÇÈýûÜ ¡º¹çù»¢Ê9’ØÞ»Ð5Š9‡l«S‡Þjz÷ö\›uaé(ëzöüàŒ#RˆÇ -ÑéÁ<·ïÊÓ¿Íôù–wû²7¨œÈ«‡çtèÃcxñ1«±s‡‘ÃÃHÄ¡b¸}½§òÊsÇæ‹…f¶µ­[~áí»èÚC‚oZé­Ùä|iJÓÏV‹3ÏK•«±>LU’$Œ)LG@piý/ Õ é -endstream -endobj -1375 0 obj << -/Type /Page -/Contents 1376 0 R -/Resources 1374 0 R -/MediaBox [0 0 612 792] -/Parent 1353 0 R ->> endobj -1377 0 obj << -/D [1375 0 R /XYZ 72 720 null] ->> endobj -366 0 obj << -/D [1375 0 R /XYZ 72 267.513 null] ->> endobj -370 0 obj << -/D [1375 0 R /XYZ 72 142.237 null] ->> endobj -1374 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F11 833 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1381 0 obj << -/Length 2720 -/Filter /FlateDecode ->> -stream -xÚ­ZmÛ¸þ¾¿Âè—Ó1Wõ.Ù$¸6í¦±‹Ü!¹Z‹k‘%Ÿ$Çqúç;ÃêÅö&kœ¿¬ù®yf‡Ãu'ˉ;ysåòï‹ùÕÍk?™¤"üh2˜Äþ$ö\áÊx2Ï'Onèþþx÷×Òwö­j®ŸÿýæõpN‰4`A3ã×S?œÙªºög‡µÐi6ÙBQG­Ö™.u¹¤žª¤æf¿‰£ú“ë*§Ö¼Ö_p%®§:ó¯¢Ë‡ª^g­¶ó³ /Õ ­¬¹§µsrÝ|fqZ˜Ù´zÑPÏN—9‰+ÞH'S8õ‘ú)Áüïûë©Lb£ Úi몘¾Geë(ŽEâ&I;ïU£Z*fŵçTî@7ˆ: »²ØcWä” -°xNƒ¹`šw+UÒÜN\eåÒ(جfPã(ÒXCÍ(·KþB^mïQ³è”†·l`©BM«Ü‚›LÐÔóD†K?à éìQˆj[c-p^ür7£vб1QSþÔRK³e³U5·<^µF D[cAC¡d£ãÒô+ Æi£ -µhP€DÑ õÙß²jiRFõM]ÝjM•nWÔû+Š{ŠîØþ¨¿·¨ŽjylméŠ4Y;Dkgh®01ÌÄ–\× qUï© -Щ¿T;; ù €B/¶€ÆR-TÓdvÛ¦Ø>2‰FÐh݃&»ŒéÜNÛãBÆÚ hdmÔ£&4†B…Ö÷÷oa¾uµ¦b†jK”¨¨v¯—´Fkˆ0TYTëM”(xnË £À²Q)ü®•!J…”Ù_'Ò1|ðŒ¹îÀÔ;Ýðr[*¦o†¦4êå"q;eM¸Ç:@nƒI‹¹­˜Æ–­ÆaÃb[× mX”)™£¸hª<Ùc tà¼,È›ÖMn³¥ñ Ð?§ƒÑ¦©x¶¶ómµäÏVëuVæv[w¨† ®v"  =„Áè°–Î-{‚ØÙßtž–7ôPÍ¨ãŸøÌ©è ¤ˆWó«?®[ä1b [=¼ˆYOÄÁ‘YÕ×E±ÍÙÍöMKmŒ=ŽìlÑÆÈüÈœc@æ§"N’ï"ÃÚ^†ž‚íláÆØ¼@øÁE¬æÁmIÊïb{÷Ÿ…^<ÙÙ¢‘¹}À‘{dn(’øÈj[ªZeE¬¬êçkmÉ÷àÖ÷8Þ³á•)Œ•ÑðÊTÂP>Šw]ÝäÙ;>Žœw”ä™XWb_ÛûôiÔç‹=F'B&—°2¬MGVÆÛ;ì¬ô’£Î{Í05¯_4]$]ã+¼çª'ÆðN+e“Öxe~\=gã«'Šxˆ?£ÏME‚~bW¸‡—0¬ê|Öf›·êk;SŠÇ4+ðöÒ$G°¦×k•ë̤/9ÉâbZwÁpÒœ§¢5¥[ÜAÃ/ÂÜg§R‘ö½¿O™ÄúX.ˆ‡éø  m¨a§‰¡Dá :Õ`¥Vm¦K“[‚¥Õ°€Ž°…‹"U!BHqêüfο-6¤mì_wªÁ_¸ :*ûDè)á4O'W æê!Ûí) |¹#¸ànUÓE_]²ÊÆg¯ƒld“4ÃTÙKôöwPÀSÏy …_ÞôçA£ì] ì‹))ÜDèz9¡Âû7W“fÄê"%Ã( å=ñÁäìjML'^Àm|œ®zWsz¯±ç æ Ÿ1Xög}*ѪŠ{FÁÊøt¾íHçílþœ¾ú¢êäóËwëÂ2ÙXÀµ;•‡‹EäÞ#ç-?ðKFרl·X° °ÌžáŒ¸2F<u­”­0—ŠUÌáo¿Q¡BÙKa#@E¿°m¶uIRÚ6~ŠÄ»ªàbïrM^˜0¯#NºÞ úôìÏö²)ÙÇ’œ•åZV+û ÃiËè"»/B–å8égC‚¼KÐÅ}޽yÅ’áWC†S쿟Èv“<ÌpxÛ”\äi"ÒRGD¤±£´4©àVø£Ÿ<œX/„#ÕëÆœ|öàƒ#ƒÄ/Á¿œ˜;ÆêmÕÜÒÃ4¸[r½ƒsØg—3')5iž†ða‚<Ê4ð<ØýÕzÓ64»',Û'°ÛU57fb¶3[³`hUlɆ¢%‡|õàäŽßK|UviÑ H»/ˆ1yƒM…yǘڡýªÄð8•Î/Ãe PðÛÎïž6© _yGcÿ9›Þâ»ó‰±æ¸~L>ž1ypÎ,l8¨íA2 èkõœ@­}‹9V›9ÀÇûåxÐàé:èp¯ÔÝ;KÞ¿KŒ¹èdÐ|vð~ÝOýáÿMPƒù· ø%F@aÈE°J¡í]¨åx¥>9‡µ$j`‹•ž37Aõ _SÌ—+úR'Á&ëŸKDZ.1—Æ|¦ÿ8a5Ž ’“ʆf"¾ããvâ/(iê:·[¶-ôçcy­Ô$Ó©¡Û¥8¬V˜Qý9 w¸1„gP„¾óMÕÕ´PåÒ<àÁüO0ñ®{›@ûá!N{Pw/tv'²ô;a| ûý†ãHö÷Ysœy•cãB1r|?®—NÀ% WòÍ*rGƒà6ñZòä -endstream -endobj -1380 0 obj << -/Type /Page -/Contents 1381 0 R -/Resources 1379 0 R -/MediaBox [0 0 612 792] -/Parent 1353 0 R -/Annots [ 1378 0 R ] ->> endobj -1378 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [327.916 263.966 350.387 275.921] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.2.5) >> ->> endobj -1382 0 obj << -/D [1380 0 R /XYZ 72 720 null] ->> endobj -1379 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1385 0 obj << -/Length 1967 -/Filter /FlateDecode ->> -stream -xÚµY[sÛ¶~÷¯Ðœ'jZÁÞÒ43¾ÈŽ;Ž“ÚrÒNÛéÀ$ñ„"U’²“sòã»à.hQ7¦ª —½|»XìBngÒq;—G.µ§ƒ£ã ub"è ÆPtBî2× ;ƒQç7G2Á<&»=Î}×ù˜è§$›t{…ÍE’êŽ/–épá3Á%p©É\eÝž}GFI—;U’Ó@•c;Ë»"rkâ"”ŽÊF81JÊyªÌäWšôß].S]~_Qàœ›É“nä9ƒ»Oýþ"¦@2tžJüþjVå‹6×GЧ+ý¥2ZtzVrИžòGÖíI)ÁTƒîžt†ùlVKêyž3Î ìŒrÄTÓ¤ÄÁ¤|…(µàvMÄb[6¾ûþq#צ^È€[HÿOÌžñA– -Çk…êÊŽ“IF³¨G˜)0ì¨6ÂC ˆ]KÀOSm(„ÕÁ’A<€ˆ'TÖ¦þe…{«i¡ið™kiIùn’ Óň¨û$,Ì ÑãNf6YzÉLÔjó2¬¯ò9.0DÉVfÝ*ëZ_·mñ -5ˆÊiãH-èˆ`‰ð5Ö_öä¥õÒIU1YAÝÞ ‹9µ,¡CÃƵ’|èAÒAúæŸ&–ŠœmÅäµÃ5gݶÇžÛö@pxésTûÏCÿmÂö[·çƒU68ÓÞ}ÀöÇ7Ø~‡Mšd€šà®ë¼io8»ðÀ²«;æjbw€©yÁ’o;ä0n„ÏŒ{kŒ_·NNÛ¢öÖÛØ<è )Ûok;Lçº5œêq…½ÛÖx‘L¦U[“€4éæËW\B».3(!HÚ0„ƒ=;ºŠ/÷C@ÿü¾÷1 -Øùû3€Ç•€õ6{àúg^X¿¿@‘4ÖùŠ€~RàlZ$e¥³ÒœzŸBF¡“RÓ -îóè8ò0€pî g³-@æ@à]g.:•",¯tIþ@üosâv‘?¥ºø?®ŠGì¼ÍÇcSÖS~Òãq¡iÿMž}6‡Þvߢ}7ü@‡¢¾êLïQeb5ËÇØžßckAôœ«*y07“ù~Jª)™âÃñ;‚œIR_°/+8xk#£ÜÀ+C±Í[~hì@ÇIÿµH -â¯ÒJªjäÛÃþ¨Š$_ÔSp˜'e÷ ólœL¸Í$u4º"òj„aÁÝ-޹‰zR•:%¼Ô¢Êg@x‰ YÛd-¾½‘Qè!±Ë³]´A/a6/J±*Ôð³ùØ€QÐj”õVâ\&ÿÓDDWCPTÄñ˜ÿu—3QÝÜëW7çý_LÄõÅCD‡Æ÷\:ÇW7wƒ“ëë“ÁÕû›W›ãQÐÞ+š½÷w}³Åîö+ˆ¶pÚröþÝ»“›ó;ÂûôWŠ÷7gFP=;(QDíäúÃÛ“ÓþàêŒR§÷>n5Ñ,Øê¦Î¾­çµ+)È}©›Ì©¤Ü 9ÏFªøºšµ.'a^}BlRŽD)’ÍÒË:{¬óÒ¡Y4Å,©?8úëÈäÖn‡›"Ès]æA4œýö‡ÛÁ8@ü8ê<Õ«fAq è§»£ŸÛûE1“;öÃJÄ·×µX« YFsÈÃ)ÿ¦bS"çË%W äcëã¯×q†|^6ómAÅtb :ëo æ €l´ú͆ -/f¡Ûx.Ÿ ­úB58sJzë$ -sRs¡RÄÅ -¥˜%p;–¶þ€ `ÍžÔ ïgÛ!á?1d&LF>ŠYõa­v CQµ\L:#ꊔ|Ö¨æê!I!‹7µZEl×voqÛÚà™áAœ/YäG¨,D¤0t¡8QC£Ãçíß®ØÞ’µóóøÞfl9¶ÕÌ÷YìzÛÝ.€ 9-›„ÙçðÒƒje É|ï8ežW_//œ²ºðØúÞ¨µA—°6à]‚:2Ú -ØÁAÔAîtá²(–;!óãæµe“ÏK„ß{ þ½ñkÃ/ KqƒCfVÅäòP †píKÃ$É2ód±]‹½ÅhkÁƒú†?€ˆ܈¹ P-úu]¶N9,ò4¥ÛÂþÛõØ[–<Ì—‡0ƽßG‚œ¤šÄ -tÌ*ÅãaÞ+ð™n«Nû ÕÖ)r™Â6²9’m.A'P²ÎY.ÍUÛÌréÅW6éfš×‡h¨ì­¯ìã$˜¹Õöp>-T¹#^ì¯Ó$Þîí«™ë:&@nêPRpYV=hFA«¢†S]â^K!fÕ£f ; -›ß¹'‘Êh°]̱@F°Eò -êUHKû´ëÇÎÕØR_d#ónçÅö5jr­ˆjÊvrYƒ„äž-=¥ŽI6?ÛcN°ã•×àåçsÈÑ¡`ëF’l.ýEÍæ)ÔÐû¿È^¾Ï†Tï/æyöúìöÍ‹%Ôª‰–ž§Ÿ‘²0£Æ"懒ÌþÔa.ÐÜ–N–jC³¨‰²?0Œ­æÏüÔÌöL ¨Œ¯4” ÀCÅÆ§}]´ß¯!ðÇÌå1h - xD@À[‹à@ý K¾oè -endstream -endobj -1384 0 obj << -/Type /Page -/Contents 1385 0 R -/Resources 1383 0 R -/MediaBox [0 0 612 792] -/Parent 1387 0 R ->> endobj -1386 0 obj << -/D [1384 0 R /XYZ 72 720 null] ->> endobj -374 0 obj << -/D [1384 0 R /XYZ 72 720 null] ->> endobj -1383 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1390 0 obj << -/Length 2317 -/Filter /FlateDecode ->> -stream -xÚµYmsܶþ®_qãñŒ©™E A¦i;¶,¥é¨ql]’N“tD‘Љcy&y~é¯Ï.vÁ—;J‘ìô˹û†}vAo±^x‹o¼;þ_¬ŽNÎo‘¸IäG‹ÕÍBù %<× Ôb•/~q~õBï[øuWsúæoÇ¿­þyrVx‹¥º¡ŠhÁêV/ƒ pš]©[|”ÎMÝ-¥¿¶kŠjMc›´ËŽýعåþ÷èE<9÷ƒÑnBº‰”°¥t}[…Ú[3Ÿ ›¹5nötCdiË"“,ʹ%ÁGÝ­fÙK»R9–dÕÚm·ÇËžcÀ…ãÞ§É’äZŠØ “äñšü8»©Q÷¶fµª 2âÄÿ«d¿Š@þýÉñRJyhÒ´B±>±éˆi“fnŒLƳ‰§¦þùVWì‘ -¹ÁìâX86†Â*pºš†Z6ãø‚PüŠF>!µÞYÏ©zê3þ1§Gˆ1×Ä¡òÍáñR®’‰yv1ÃÂ÷ÜH(;gæˆ -ázý8팾ë{ò¡b¼¸œg&â¡RÀŸyÑÝŒ‹/ Ç•q-G?íúß×3 -±+#õ6ˆíøé›9H7ô“ÇÚ ¨²r—kˇlCéªäÁÞyˆd3]½¹XžÒ¶ÖÜYZeºdkW9£•îvM5Îó~KguùóÙÙÏ8…åE£³®n8‰•ú½“r&qšxU¡<‘çt·”¡Â„vÒ5¦$@?¬o¾†ü™(§¸¡YC¶‚—´ëôfÛMù¼/€ Ó@UWËNìˆæ“¥ÆÜEN[oX ðEZ­ùe’Ž[âò¡(ˉ DÞî˜o]YÍLvÃr CҼͭ+÷xzÉà0´|á©7=<jÂ‹Ñ þ_"ü°ˆzm$¥StDÀ® ²àZ·ô­k"¤¼ímQjZGU νå9Y½½t3ÝÞx¦nÞÒ[ † †u3*¯Óæ:]søLJb@8 :Ÿh^´Û’ •vé ù{EW)Û¦C57pCÀ}zÎO &ÌBá9—ï°ÀÓ§õÿp§Pç¼ÀÚìðü*ézðèJ9q,Â"ЄRÀRsv¤Hßu5à|‘¥eù‰ÆwUûn‡¶ôþš –,u•Õ&rÆ»ëĈ®°ÚO8 áßO|r’ZÕ¸?Kݧ!½¾¡žè3£nŠ8£`æX­¼~âÒìï*»ÜSY…cu…Ú! "‡k¾ÜÔ]Q³t$TÚð46RÏQÍEÌõ›v­Î]´Z8ÔÒV[S‡CêjBÈNðì]cªkmÊ-޵ö–jX.ËûuuS¬‹*-é­J7wmл•Ù“qÝ^§ØM|És ]s„rF«à­÷m bæm¨C§A”A˜7r´R97M½±<0¼y^—6M0âÃ?or ïõ²Ù°(]½½ƒC™¶ÌÃf Ç|9q(cÕ(@žp¥KºÇFàXã•–KQH’uYö-›[Bެrî:leÙN -ß!$Òn4œ -ëÊR›„BHÕû¿à':ua‚¥³•s÷—=L­×GžšËù£:œÓ¼A}rÌ8žØ©ª¯ÎÉÃV(˜ÚìÚÐLƒu~¯½ÎÙliÂ]9FMÁ–þ¦7¼A§%XÉéõ´Kˆð 2=Ô¯¶˜Ú»äª*žu[ä&/F -šäª儳¦wVT#^\Vø -Ô›B pž–mMë;Ä<ò0Ô,“Ã,…Dc'$ I¨C1$땉 œ‰“Ÿz̹ õœßgpzâÓÿœý›ó -·¬—?¾ø×w«‡šßì€Kô¢ïè¬À”%áñt@ØCP“±ë}aû֪С´¸ÁøàxjhÀ„†‚‰B7AÊAu³oG§Šf17Ó¯Âkšç&íÁ\ª7ThÏnfüƒÕ‘ò¬d×PÜ02²è+CìdM±%Ô³NÇ®=Úk#žÌP×Ôïž­ŽÞaçæ-^ùQäŠ@-²ÍÑ/¿y‹èàk7€îàƒ™µYpã[’rqyôzo}¸IÜ·Þ[°J´ÜÜCMå&*NÊ ¹†~J -`òÉ![¦¶™(Öæ"<º,Yói8£ˆÄD‘‰¨ÑS{qJ¡(ç×KI/06x¼ºSkIÊŸøÏ°– ÝHH6×Ä^»ë’³dŽ)sÎ|€gÐôØŸÚûŠ˜zˆs-ý1Ó[¶c¥3ݶXøÜm¥G«9µRàAçüE1%bx"`¸QÈ™åC³„uifW{­´»Þ]pôîÑòÑbNµ„ -JõgÄ‚/\åq,\ ¡f_¡mÝŒ2Tž±³Ö€P×ßÚÙÖ¹i -îm¤mÜî6Æ£µ™Ã4ùŸ·<†¼ 0Œ¼7è|8»IŸÇÌ 7Œ¤a„W,tÁ2˜sWå€Y_ƒœ¦\aœò¡ò´çl SkÂz(ý '¾Ûˆ_b4bh.F‘Ë &h |„Š`  Ç>Ãñ«Ëâ1È@8úý1‚s9ƒÄÀY¢&í%"ÞÕÓgø §Í2c%Uö¡´®äÁ­ŒÅT“Ó_ª¿]ÉÐkË";W[D.©D’ù%#0‹> endobj -1391 0 obj << -/D [1389 0 R /XYZ 72 720 null] ->> endobj -378 0 obj << -/D [1389 0 R /XYZ 72 473.857 null] ->> endobj -382 0 obj << -/D [1389 0 R /XYZ 72 374.808 null] ->> endobj -386 0 obj << -/D [1389 0 R /XYZ 72 307.128 null] ->> endobj -390 0 obj << -/D [1389 0 R /XYZ 72 192.394 null] ->> endobj -1388 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F23 825 0 R /F11 833 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1394 0 obj << -/Length 2429 -/Filter /FlateDecode ->> -stream -xÚ­XmÛ¸þ¾¿Â9… ÄZ½ZÒ¡-lvi/›ôì ×æ]®Ìµ…•D‡’n³¸?ßy£,ïºíжÈápÈ!gž™a0Û΂Ùwg|߬Ïί¢|VøÅ2ZÎÖw³,šeaàq6[ofŸ½ÄüÄç‹0LoõéÍûwëù"N3ÏXü.½^þÈ„Ui«}ßÍ^ÿåüj*3Ì -?.BX‘D®w&„Wš¦Qí†;·óE”{º6sø<0­êøÛ»j¤¥ž™Ö°$’óË<Ê<¡ë¯¥Þ÷n–’VÕKÁ¾g ·WÐ×/Ò”w{ Öfû2Ъg«³¿ÈkÂ$öáG¢²@ó—Ø[¶•-vÏÝ0Mýp™¹ A8dÌÅA‹ÿ=Sè,ƒ¥Çyj·šûÈ”‘Ÿ@Lj,¾h0Ä‹-CÿÎbŒ–Êrs£ïÔP]nM ĘEl†¿ñ~SïŠÂ›•-ýøIŽSµ]¯ÚR£Ø(ö*Ü]LÄC§5¶pyäbHvÀ pÛf”Š´zȸÎu⠃͆ªdõÛ¡—ˆ àÏÜ£sÅï`EN%|æÇ2ùp9ÀÐíÌPo˜ioÁC7ú¼Èñ.¶,Ѭã‚˜á ŸÃèò{"׈ìÇ¡ëÃõ¿.þc4ȧ4¨úA.«ãoïèlJDU ÓIÅcçZæÀYÊt:Dnª¡7 Ü`É]wÉ¡gÁôžÜo2Þk<½WY|ÙÜ3Orð¯8ÉÀóÿæá‘_äű‡OO(ÉS?ëDIQKÌ;ÁÔ”2ËÞà1>¢KþVœ\ -N~_Aæ¦ÜíJŒän¡wíª*ýžò/$`t™Úç“|8òÃ,;[úyÈK‡þÿìó" ‚C¦'"B–é¹[ñ‰ik‡=‚Sß"ñ8¦$#$R„%RïÁwpMÅŽgˆeËd²˜*—L*”IXìä ÊU}z™C²À})³îŒeŒ€Éâ'(ÙsÅ%…Õ\éÊÊ|‚ïЩÚý tAòCY–{÷äQ’u(‹ùJ’`ä¢7÷Ü··ƒ”rúPzañwÇã'2CÜJw/eæq'cIj=Ùç«S)‡ö·´«„×#>ÈBÛÄð é‹-bö±W¥v ‰Kmªî^ tçjÈ#¡ÊŠ¿Ü*ª™ïÇgØ?±Æ…»ŸÂÏÅߣ“»ªZÜN’‡“b :h»h¸Øº#vîÁt[ƒwùÀµÓ -+ÈQG$õU#2A+Í1á&:Ù¶$eDLÃì€(ÎUš¸ lÂÔ¦*{uë¶C$­¹{n˜Àð½`E¸ÂãÊ–“Ç•,õ~eÚᤡӸ"4s.ᔙЫí–>[º”9õ¬q4Qõè9+G$ Kjˆ"é½…cD¶”t³Å}å=ÅïN—‡'L< '/ЩÍVJÃN/9¶âÏ[¨W=äû|’t&w÷”ß’zU3ŠÐñHNÎóLŲe%·ÆXQ¼xñbýîýåüɆ{­5Õ$Æ•N/N)úeмBMÁáÕXœƒ$’âõøÆ§¡Æm´ó'Ð˃®Þ? -cý茓ZåÐù×Á(\ ÷*~-¢„Òõ§QÌåúï0Õ„rAŒö&ñŠB. -ÞV¹pE¹OêÇËd"ÉOÉzþÆ~^ñPµmªVÕ>奇±zT#æË±$`Ã~Ç߆ÓüGîQqƒó¹N~‘Škc»c {+6¤-%»Àº_s÷V„­ª—9œ^¶’»‹JÇai£ÁУ""xÂïOaœ`B¿Ðò “Jñ LgˆÐi´·ñ -»¢b4ö®ÂC%Àaº#l4\$dw´À`;cQ+ݲÖÊ>ç@®u+<£È®uÌ'|ÂB© ƒO_¡ME'<©{Ø6Ap‘œx¥ŠD’³ºøp}õî;ô$¦H­Ë æl=·Y?lƒg vl¬ÆAz[½­ŒEß(*ü ,À}1BKˆ^ÆGLP üš=| -endstream -endobj -1393 0 obj << -/Type /Page -/Contents 1394 0 R -/Resources 1392 0 R -/MediaBox [0 0 612 792] -/Parent 1387 0 R ->> endobj -1395 0 obj << -/D [1393 0 R /XYZ 72 720 null] ->> endobj -394 0 obj << -/D [1393 0 R /XYZ 72 720 null] ->> endobj -398 0 obj << -/D [1393 0 R /XYZ 72 642.596 null] ->> endobj -402 0 obj << -/D [1393 0 R /XYZ 72 445.7 null] ->> endobj -406 0 obj << -/D [1393 0 R /XYZ 72 319.425 null] ->> endobj -1396 0 obj << -/D [1393 0 R /XYZ 72 289.604 null] ->> endobj -1397 0 obj << -/D [1393 0 R /XYZ 72 245.813 null] ->> endobj -410 0 obj << -/D [1393 0 R /XYZ 72 179.555 null] ->> endobj -414 0 obj << -/D [1393 0 R /XYZ 72 154.745 null] ->> endobj -1392 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1400 0 obj << -/Length 1371 -/Filter /FlateDecode ->> -stream -xÚ½WmsÚFþî_Á§FÌ€¬WžÄ°Çi»F™N“¦™æj½é0áßw÷öN ªIãv¦Ÿt···/Ï>»Nç¡ãt®Ný}Ÿœ^F‘=xƒN¼ì ½ÎÐulÇvâ¤óÉ’¼ÌDÎÒU·ï4|Ñ+žý:Þ‘æcŽéãÑV«ç…\‰üA[¤Š¤ýÇ™²LwãñÅÝÌ®#Šì‘7¢ˆfÓ8žÞßÀ]Ï³Š¹d'm„4‹ÂÎtâ(PYxžoef"B±XSÑPbŠª,Ë"ÓXC ²•0Éæ¬Òg¿;nòlˆ|s1›Ú,(ã[±Ýï Å ¬T<"R<Ý!Œhg4°v]P‰!ECKT¤ËÒ’³dG•#R”ÊÙBL¡£2) ¶ [ɵ5¬¸:’+&_Tµ•’Ã=èÀ…ë%É«B‡ôçÆD\ñ”/¤¹Æ´ô#Ø©6Ø(×sCÛXž$74«Ë¬Ä}¡¯ç‡MÉ¿G<†ÄKh=™oß_^_µr)ÆlAoàYŒ¾i(°Pw*#¨<¡µÈéK Wö±‚4㪩7FA%fNøRäÚ&Ó~ù¶é£G[¾‘¦úÁ—ãûsh%×q¬W¯ÎIöåËß9Þ̚襬"ªD¶æôW¸þÔÒNCÏîÿÛ‘8 -ÿS°ÔŒÿ&ލ¥†±ý#,è»äE Xîù“05(4â<ò»P…ô†Á=öÓî4WÝñ¼2¼>}¯éíxàqHð¬:£Õ§fì9ËøgZм&®y©þ×|~{~>3ýVQȹjèN8´C?hNÎ Òéëf0Ô?£¦aZ’™M&½É½CzæÙуÿánüîg“çñ›5‚6¥ICÉ8iÓ75umššŽu˜mš· ÍŸˆ 5 Ý/ µ¯à·ú…20 +)¯ŸYôÉ¿ ñÒÌ¿¯*˜ãzî-V,0”Õ£®áœ/ÕK×%‡wü®µ>Ú¯¸lÂßÞèŽP¿pÊp)ž´±×gÏÌ5Á—‘xRÿ~$m7´í¡EÛ†ñæ†Ãк}<úýX'ê}v܃jÃ]3dÏõmßÃÉ6²#˜pÊÏ hܘÆ'nå5 -endstream -endobj -1399 0 obj << -/Type /Page -/Contents 1400 0 R -/Resources 1398 0 R -/MediaBox [0 0 612 792] -/Parent 1387 0 R ->> endobj -1401 0 obj << -/D [1399 0 R /XYZ 72 720 null] ->> endobj -1398 0 obj << -/Font << /F8 826 0 R /F11 833 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1404 0 obj << -/Length 1875 -/Filter /FlateDecode ->> -stream -xÚ]oÛFì½¿ÂØKeÀVõm©Xd±[´[›6qQÛÎÖÙÖ"ë\INâ?òÈÓG¢b]ŸŽÇ#y<~KÎh;rFoŸ9¼þ¶|öâMMæ×—ß¼{;¹^,¿|ºøãw põ­_±f½ AFˆµš÷ˆÌ%C”}JÖbˆòKÿbVsˆò²G©êaà%Ÿ{dߎY­©¦ÆÌžow¼zõú û~7>óÝ~ñn·!e -¹–U%ÊÓ„öë(¶’à4«nÙ‹+¹Q%£KyÈOY±µ‡,òVÖ}Û—³)Õž—Ù ;{ù_›–c×ÊîÆÞÌ’?òðÆÈ‘¶mÁú³Ðº¼%=jÅÑ{H! ÛÐ=½(t|’²OuöÄ»ßOKm¨ØN¼„h¾î€jêÇžQƒ€kíau-Í{$Œ8Æ Ù’¢¬ˆÜðˆ«Þeeʸl/Á~Xk”²Sš[UòÏ_®à]ŸÁ”¿Ð±:Ô™*À2aâ@bçù8ö-N)R¨à«šüÑ;QÊ¡¸/ -¹7¶ð%è2¸=¸G@µ¯®óÒάµ«»ÁöXÊ”¸Ñ?xR BÜgõŽP'dUÇ’ e¹Ï -‘Ã3?±¾9ÄwC8ÂçwÈ ·©$FÁˆ¬ªÅ­Ž.4¥çð›õ•_IÚÄÖ–µZ‰5rÜe„¦õ}LöeMòćX‘›P­F7 8”俵LÁ#¦"9J«¶úȂգ 6*Ïɶtöí(+ôöO”Ž9§Š(¨àQþ°ÙŸdÎW3£.z$è¥åCVÛC™³H¡½˜wˆ‚ÖÅø±µÇ Àh„˜Xy“A±Xý ê†ìè]¥£…¡%÷:Gs¨‘­sH2­9l¦´¬Ž5‘ƒ˜Jí¹¬û„¡Ž¼æ*­0첂±;J„ólU -|‚oa4± i’³¸;цƒ%(Z%ØÎ00†"µUÀqIÇá(„¹°ŠkÁN>œ%,%ô¹Rî¹VŒ…àw­W–¯}‡©Ô! /YÈ{z‰í[ï˜ ÊË^‹ŠY[«Àæž4ÌÓ¡'‹¢ÒçºT»”êN~Güv®ä]¦X1-ÛÉ YÇ‚°ã÷d˜gg¨u¬Óß^g`E…OÓŠêVë‘ÒöŸcUóÁ¦6ʵςM®Ó€²\\}°i·Ü –b¨¨Ô“Zw‰¥6´Ò€æ'VdGØQ³Ñçºh!Ô R¬'yÞH(¢bfäeÕ!x剞‡qú\S€ã‡6­¸•i¸Ùf¦*’¹àâFaÅR•õ,M7‘FjÈáÔiÆÑµ·0,Slœ†×ÁqN¾O;_—Ü€6{†­ì*&~œ `„Àí¼iîñuh‚Àñ[à©ÐQÓ„ˆfØI*¿|_G”Ný®:YMÍÖ¶C¬N-Mfœú}ƒ•زÄ»®Èr=¦ßküvüÇ<…Z£Ë*à[Gk«wÒo&„çP6}MGC¯Jîy¢U¢ýp/Ån"°öºuÎyªÝéêR¸žõQ›€~7AL§›øÐM¦Ñ,ÑEî¶""eÝáÿVÅóšòì–ÕÃ*$Q¨ óíôÔ¦Q…A1"7`ùî“‘ÁZ+±Âƒ\;1XøäO#ìÅ%dÍ(îŒ_ÔQñ¨Æ¹0tÈŸ€¨úlƒÏ h—žK„®ú@r ×UDÝz6:ÑÜHªóQ¯ÂÀN6–¦CELÝ »_>’ðcáŒþó\ë=•Ü ­K¡©c€2©g×í~^D‘íÜ£åÿútܙٳ 1çWC2;ô’×OEÀ ¢00Tu¯Ä3ÝK“ñ„§ãÃIÛÀ°[gôÕê9ŽíÌâ¾]Í<‰Q½øCû;ô¬j§Û¯†¹OÔVuݶ¸¦Ìô÷5 󼊙U#„(T1­Ö¥4"AÄþPW¬Ã’:?éæ‘â—#O‰ÀM¬,›« @¦ tÑ'í ‹‹§ç8Ÿ“؇¬¤¾ ˜õ±¬†ª’¦0»W<£zºÕN$‡ú®)cÿJè ëøк¡Ãè&S9QT5&,UÞÀt+$F7æys5UM—~âhÑÃa)sy7#Ý%ñ.¨(>pƒJ{¡¿4§}Ãpg¼p3 ­\Ç UT²|Î\Ûc–2Z?n%mC?*&46ž¯ËÇ2\zµ2÷›&Ø•ýó-oà Ù7“ ·_ÈØñ*¦¢.c»¤ßïY.}¤4Ÿd#ÏKlÇMFPsmÓ¸¢°G³X>ûÖµ> endobj -1405 0 obj << -/D [1403 0 R /XYZ 72 720 null] ->> endobj -1402 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1408 0 obj << -/Length 2173 -/Filter /FlateDecode ->> -stream -xÚ­ksÛ6ò{~…¾™š±h|‰i¯3Žã¤í´qÆV§—¾nh²páC%HûÔÉ¿}”¨Ð©›‰>ˆX`±Ø7váÍîfÞìõ3Ï|_¬ž½ZÎR7E<[­g‰˜%¾çzA2[³_ïÖóE |g7‰Óôsß9i%N §n:^[g•*UÖ2ô º #t²­T•<Ÿ7õožÞõmÖ©¦>ÅÙÐy˜‹¥#C÷wwRw¼y‡ p Ù»Epgèn̆‹«7«k\¸úW²ºà•Ë›‹ó·—vó|8…ÔóßWßƒØ ßwÓ(b× ð-ÒÔˆRxÞ︶n›jÀJ ¡^ËöDó¸Êj\Ce%Jç%Ì.jiGÀ|eŽh,þÅÁÊžœÿåæåÕ  ¥ß»óEÎÏóeàÈ“²ÈÖ¼yÛwGMH}`šeä¨Q‘„X0(Õm VEãÃY(Rºt´Áê6YÇ£½¥Xà'4†@bÀ˜!× ÞC-[mà5uŸãÊÆÐ5œézè¦4¼Þ‚p y ÙmiF–ùŨÆ,ÌÉA-TÇLäÆN¿åì‘u†™Q -I*R¨rmع–m_$ŽYbÃç);†–%ø {Œq¥À!Ùú -ÿ ÿ­qÁõÈé‚ÃèȦf S²0'q €/@peÎE½Ò±2—Zg-ù¤rªì(5ô`°î»žn‚س -§1#jž51‹›¶ÛVæŠTˆ0±jÍð>ƒà6Jse=!Σ|£gµ½`ò@1°42У'µï§<ÂM†{éAWä`ÆhµÍyÙr°PÅG‰"@Ên3mÒ'Nj„q ^šŒpöJÞËÀ^ ÜelLºÂ\šñ#Ϲ8ŠÚ~¸ÛÂMDTh÷ -™ -CÏyyWè«ï^3Ôwpw6ÀdBÎ3šá}²ùúÂoŽ›9™—µ¡]ÈuÖ—˜Bˆ6ÙaÞ0t85! ËH³e#¡%–ÛQ™ûÆ—&}Á@oÌ•ÂàÛÄó×еAÌ!.›¿y‘wþÖ¤m˜Ë›ªb?'ªŠî ¤ÌúTÞseeé‚Ãk“­xbPqnÕ1áy Þsœj4û={xcKw™ -ÞöŸ/ø›bëÃÞW"A÷2~î]þ†è‹8 Óâà×Õ‹ÖY%wMC>L@“A*\‘ÄÖSyrag6,ü(‰œËÂþ9`Jç÷/þì¤>5 oF o;_×£…û¬ìå)lV¢¯/®¿áÖ óMVßÙM\ŒpþìU÷¥Ä}ê1ÞЇšpaÌõòÜx, f|žì "Äd2Íí;£®…ùbÝ´¸—­Zï˜G©£Ùî¨Fž=MïÍ1½ò!ÛiK ^«¶b@¶™† ‰E@?ê;ÇätÓv¼ÿÖð·†0^t»-^Þq’<•üŸIïHãf§;Yíé!S‘x²Œ#Z×2+®êr7¦6aø)ÔÞþô¢Äö39뵡ÓJ°˜7íóJarä©NU¨½0~T{ï£[5gEv¶k÷´©{D Èܪqw-Ÿ#üH<•ºî±®ÐÆk6Ê\ÂÊøã½’ÿÌ{r¸‡ «:o¥ul+òßT%~B¿ÞrÈ’D°ÃN€È©¿è‚ˆ¼ÇÌì{ã­›¦U¹3MYR Ô£LDcJ­Ý'=_îbùðqirt­ð2m¸êµ)ŒìÕsÊÅÓ{î¶îv[[íâòI¾X-× S›;¿þ˜™ÄMöë×S4B7Ê7¥–ïzñ€0”ßë†j)ìoÆUS/¬áüûm|lð-Œ:*~¹*_á¹A5ØòÄP'ãg‰µI‚µIhkZÄê’ÂÖöÎ>TE„¾˜ÑOÝ0xª–ŠVqk;AIøn쇃²&Hù‘¦C]ŠÍÃCp`~Bç#†žO1â&ñòo$ÖYYX°LP -"7M’¿áe å~&/ƒ0cŸPMêziô)wô\¨¸,‚Ý[X0Þ”ñîa°ï¡•Û2Ë©M¦%î F4jy7tˡ닣 Âï;Y›åö´¡¹{€ïp‹…"°nÊ+UÖñ>~o&fp`9‡t–ø±sn¶è 1ꢷ‹0¶o°>Á‡Ò#Ú½ -åÔq–ÜÓøÐ˜cÒIß6Ã…ägšv8eò‘ißÅá^Uq‡t1h¾qlC×%î̃ 0Oó %α$¸Ë¶1¸ŽoX<­jþf¼ð"#>Þ¿n›¾.,#Jñ·™|=üåâíu`^2¨$:?)(“ž•æyf“vcŸÉ¶ xgr ½y€–Ô¶´6ðŽªÏP÷…!Ó÷Ô”1N B'ß/~â7‰ÐK^¸ØZcжu:‘î œÌÉ…<ãö¡·%tßQ€Ln -(%7¹55îjxÝhDŽ?TW~ Û¡SÄÉ/-‡^‚'µìŒqâ›6~$È„±ŽØÙÛåà±ÈšïsOÈ?çßrMã·ø²…ÄÉW'0K}µÇôJÆáOç,! «ùél{®€\BÇÄñhÇåêÙÿ‚ž^O -endstream -endobj -1407 0 obj << -/Type /Page -/Contents 1408 0 R -/Resources 1406 0 R -/MediaBox [0 0 612 792] -/Parent 1387 0 R ->> endobj -1409 0 obj << -/D [1407 0 R /XYZ 72 720 null] ->> endobj -418 0 obj << -/D [1407 0 R /XYZ 72 586.508 null] ->> endobj -1406 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1414 0 obj << -/Length 2886 -/Filter /FlateDecode ->> -stream -xÚuÙ’Û¸ñÝ_¡Ê‹©­‘Ìûp*ã{ãÌfãڙʦ²Î†„$Ä<ôxòõé )3/к¾»éoŽóÓ+_þß=¾zó!Ì7žHÃtóxØdá& ü½e›Çjó»ïÃ}ºÝAâ{Û"õt¹BïÔšRÕÛ]”ÇÞÇöÐÙF ¦k·ÿzü Þ…É>J£†} 8>˜Z÷濺ßîâÔ÷T[ñàÎô_pxgUjDôæÃübA–ïã"ì„õŸw{€>à¨ën» s¯TáXÅè`Ô:š–ÿÇÖ ý Œƒ ÎÔµ®þDx¶…Ÿ/¼#õº¯÷ü?t2Oïé¹;w3xà¾H¾ßÓ.ô÷A,~áUúL¸u[™öŒ+bøÿ‘7œ41 B¢‹%~‚ˆe*‘Ä©3%>WUÉn¦~ý¥tÃÀ³íŽV5¶¼ä…<Ù.»æ<Úî`çO|<áÞ‰G±§ð/ò>ûA\kÓ#àÿßc?,6õÀ·é ™ ŒâYÃ(e»ˆ£Ï´‰·¨ÿk­Ü¾àþB±•= ¯•= -bá_„üpJÐIxk½ ¼Š<‘É‘ø^Z^Ô_ñrZH€ø/\É÷EX0W>â:¨ ³4¬2V—Cg_þlÚªÃç<ß  ðîpr»Cz|øíýûO|ª?uHí¹ç©âÃÌÝ×u¸i¢jzót’=b„mn1•Ü·ã53Èùöê|ݺڭiV^“÷Û]€›Æûë—myðÒ$TnúüF?˜²ç¹pÎsKfiÙ1!9X-#gâ0ìZ· …çùŒ–»¥0‰¶ø_!ɯÛ$ñÜú©Ö‹W¦üÊÏ~âí’w DQ}éWuã·iO83ãIÙ½Âl8™žG“-!´ãÕvÀËQj=›á$ÜœŽ´‚Èy.ÃD‰ˆ\âëýqÞà`»ÆmAsÝõ¦"e™Ý¦êƧieE1àIwæ× « -gE2©$À¬þφRñ{FØ ¦y’•=i9ÌÐ&çSq®h›U¿D`4¦5ì\^ùŽxàèoàÜ„l¯¹í$€–ª]{¯¼¢©a‘ -dªŸzMgÝÝ -®B<ìù€°‡x\…×êgˆÅ r¼É´ý—KK3I›È^СàôDþ,›Â-ßçEÈ'@x⿦iî‘-º¨Ö - Ü]#x¹çP^ÅÚ(Üçó®Ì>”žÊ{kÑqÇAâ}²(ÏÐ+u5Z&vÕF‰ƒ}’®²ò4ìÊp^GGÌ ƒUg†(ŽD>0(“ƒØÏ–*·¯†KÊŒ‡MPÊÚ!ÆµŠœßÆõí-ðvÒM‘ .½2¤{7¨º1Ûp˜…œË>£LÖ¬º4/pÖêo—èâ„°ó+XàT—JÞõ¤38êÕIÙ -dÍÔ(¿`£êÃØ–ÚˆŒšä^p(}*ÿ[i!WÖ’jÔ„ÌŒ¢ÜÉ¡Üàȼ¼å¥wœ;gÞ9[âU­™ü8¬Nó.N2ª*•&œp”ȧI¦Q1«S#êIŒuÅ'ô7jtÍ:2qµ°ÑjùÚSŸ/Ý™Xš-‘·¨¦%ŒŽÒîyrCOî/Ñzì§"áÃÇ_îÞÝÞÍ[8‘÷îŽ#ÔJþþqŒ©¹ tM1õã„`݆:‡ñ¥4D¸ë½!ÜBmC7ÂdŸ”«9qFíD‡5¹ö‚²xxD ØÖè†:J£ Ü 6ÝËêè!HâGߛ뾆HÁá -‹˜BoXHÍ¥¹üsPlBn)–xyÜÆö<¥B2”†¡‹t–ÿÊ—²6%Ÿ‚2l+Õ–B”°fY "ÕrW.”.¤BoF3¸ˆÇååfi­s{4oÁ,¿\íæ\ˆfNÁ¦À²ª ŸÆ'zAì‡yÓ“[ =¦¤^ÝÊ -…ÎX¸Rë½Ï´‘Ó/õroJŽ[bSó^ñ*8ìÐìëÕš¡6á´Õ‡œÊvVgœ×ú€ÁÁDíð+OOi€ÎÑè{ù.)Ý|W¥úELçr’ÔYÉÙý@J$üD4} ðƒ™ Òäcƒ, ˆlÐ5ë\‘Jt©f€Q©èJšg+¡“ò­e -äŸa7å?9% 7ì÷8KÊ©ÿÖò¢+–{^PüwÉÅ; t–/Àêàê²O׎WL×µð¬t óp¢ye­é[MÈ-2:¨xåÔ¤<„‚ -ÿ•·Š’Eé -BzqòµûlÒ•¤ìÒiâ)ÉÜzªãÚYÊðKÇc1grü)J ì§%¥ˆ8òÉg¼Ò5âéóãû™Ú&G×Þ\~÷B—¢­K^ÜW®ÃÂî—Î4 ‹½›]–îÓ"g>¤ÙbÓûÇWÿ DÉY -endstream -endobj -1413 0 obj << -/Type /Page -/Contents 1414 0 R -/Resources 1412 0 R -/MediaBox [0 0 612 792] -/Parent 1416 0 R -/Annots [ 1410 0 R ] ->> endobj -1410 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [103.659 225.902 112.432 237.857] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1415 0 obj << -/D [1413 0 R /XYZ 72 720 null] ->> endobj -422 0 obj << -/D [1413 0 R /XYZ 72 720 null] ->> endobj -426 0 obj << -/D [1413 0 R /XYZ 72 703.603 null] ->> endobj -430 0 obj << -/D [1413 0 R /XYZ 72 357.907 null] ->> endobj -434 0 obj << -/D [1413 0 R /XYZ 72 212.957 null] ->> endobj -1412 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1421 0 obj << -/Length 2180 -/Filter /FlateDecode ->> -stream -xÚ½ÙnÜ8òÝ_Ño£lYu´ò–õÆ™YìL‚¤ ŒÇ´Äî&¢£¡#±w~~ë¢ZÝV€`ݱX,«Šu‘Áj¿ -Vï¯ÿ¶½º½ÓUúy’D«ín•E«, ü@e«m¹zðb_­oÂ0J¼û_þùîí:½íöÓúFe‰÷ŸÍÀ@ÛñøwÛ+½V¡÷ˆ·CgŸÆÁôëÇí?nï7«ÜÏÓ(ÅMƒÕM”ø*U¼'ï´Q¸“÷á×õM¤Ïö£xW!¬ºýŠOï¯VDúŽ–]†ä´«–íÚúX™A¸ÃzÏGðÚJ7z°mÃxr/ЋÝëÌ*)[å?þ´¼ñó(çål…{$±×´<Ú¦ °Ý.ˆé…¦ïQy\ƒ'çxU D²Ùéåxþu¤'F#³ÉçAŒ‹tGF`æ_8g~š“ÛÀÿpƒáRl <\ÃË7.¡Râw’œyËI dg¹$È.N²?H4°Ç_sª1Ï…9bu -RØOŽšÇÊè^À¶1L5i"ø£¸)ÀT.F÷Ç©á‡É~<µ2ê²´îÿ”'ìRÖsÅ1B+/F -®ÐÓŒ yI]i†¤6Û&¬Qî}hèIM}XäH§FÜw> endobj -1411 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [381.733 645.875 390.505 656.723] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1417 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [383.278 591.081 398 601.929] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8) >> ->> endobj -1418 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [258.883 508.937 273.605 519.786] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1422 0 obj << -/D [1420 0 R /XYZ 72 720 null] ->> endobj -438 0 obj << -/D [1420 0 R /XYZ 72 720 null] ->> endobj -442 0 obj << -/D [1420 0 R /XYZ 72 578.136 null] ->> endobj -446 0 obj << -/D [1420 0 R /XYZ 72 495.993 null] ->> endobj -450 0 obj << -/D [1420 0 R /XYZ 72 356.634 null] ->> endobj -454 0 obj << -/D [1420 0 R /XYZ 72 198.124 null] ->> endobj -1419 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1425 0 obj << -/Length 2668 -/Filter /FlateDecode ->> -stream -xÚ­XYsãÈ ~÷¯På%TʦÙ¯yH•|%»5>FÖ–³×%R#¦(RKRã8¿>@M‘²¼ŽvýBö>p}Ú}y£œxüÿíDÀ߉Q(G¡ˆÝÈ£Åúäç_½Q -ãßß°£/:ä¦F?‚Oá»"f½NP¯`™“z1ÜZ4Ãô§½´;A킳߂Å’ÁTšƒWë,ETYÃïáØÑWpîDZ ùœ{ -2Öð„np×/Û<ûŒäøÓ_]^ûò˜Œäõía›H»*`¾A/«jð1ªú•";…žN¾¤Ñv•QcJ¿jÃé´IÑI,ÚŒ7Éúo›,å’¢ 1Tw‘1A^.ŠmŠÚ§ÞÞiÍÆØH¶0F²Hv‡&µ%aÓ¢Šo˜!Š&¼å} –†è¢ S˜ãM_P7 œ3²ìÒæåWBÙyÞ.7YoÉñgIÆØ6£nkvå›å¾H€Š²‚¹`ñàú³Õn§Eµ^'ejŒÇÛËâÏo”×Ó!Ü_B††¬Âï>_Of3ÐŽ0yñéoîåý-u¦¸ÝÐöƒ¸ëlY¡D%¸ È¢ÁV@:“Æ+YgØÉÊÔˆ -Û¨1C ”Æ#ÿbé}Ï2cv PF7qoCXñú´î€»ôC•âjŒg&HDÚq xbMÆÀW23á½æø£)î;ÏË,=¤øœu ‹m=TušÕF?õ#ÑOÿ´VntgÿšQûîátrúô¶f‚Î,ÑQ´Ç.¡«‚íŽØ6Œô ۺΠW-ͤ» c+¢{Àä£Ë Ñ[µÜ‡o5êĵ˜’ È ê>PR‚ |gRðp…†Eͤmë|¾…œu f“œYb~“`ŽÇ‰cXdEÓ¤Þñ cÏcPvÒP'¡_Â9ÃÖ=4LŠ‹;â†-ÕÙ:ÉËÆ®î¬Mk!=Pñšf“,ÈŒ©o€þhi0º¶w™ tx6Rm°Àʲ1Ú¡ ¬Z©³ß¶ 8# -è’z‘’ö¯pçoc2x=Öí°³Npæ…am€PU™fe“1a[}:ƾƒ÷í{òô.î|‡êôÄÊ«^ȬÂüúu1Ò‹E½Å¼ySgé™ShpÛEèÆµÛv³m¹Íf Ív•0AV×®aÃäkÖ êA4³•‰fž ai“µµ Š ÅˆÁìYÖ2ñX'-k ­“lÉúhÁس¬15ZSç9oW¡Š5/ê`  ֮€24ÆJv¦1Ù'ÛZ³] u¬Øžxt¾-Ь¥C5ci•Ô)ˆÃèSî)TI×·•œ«\ábÕ&|+™8 ÉhÌ=)á•Y_º$0m3#‹,“¤DèwJÄ6ÚŽŽ­ü§‘Øè@sþ³%±ª«1`¿Ðhž²ÌóERðÁNÕ®¨Ë`s–#žA¹|é¥y³)I´·(Y; ¤©µ nNJ†(g¾-›ªnÉ3c§ÈÆoJ?bpê–ÁÙ$,Ý) Mç1škyJ8¿¬:óE´àíç½Ë&4ÔlÁÐl”( pòý®:öy#ÙðvÉXÓØ I8+6Á.Ò3 AŠÈ¸Bƒe²¶ólòz/žáLOžÆÜM -gai!³‰ÊèÓˆâž÷éj2{¼œ -åþyƒ‚üÆYŠj¹äö¸j¹ÍÏ2D£w4eõ¼*¸]Ÿ?s ¢2·ÖÕÁ Ÿ^>Ì®gS÷î~vèø‡.>_þÉã'ÓË·Ž‡ÄîöúNzîíäÒ#Îîïwÿ8{°4zGóôÏëëÏÜžžßsëñÇǽã#å‘?¼ƒ¢ ²Ì‘c}`e"ö<úõ’ ê}g©ûqÎì)ƒp„þظ .…¨³oÙ€!ݼBw"êL„–¬ ¦âZ’ a¬þykgzW6goëÒ¸&Ós61Ÿžw‹Œº¢ÿ³ºâ’Â7%EÖØ[×ÙŽ©ÚM³e²-p;àAÐ[šx2{¦à žâi§g(ŽK¢!ž}Í<û\5ùŠyöÕgèw<û»|Õg˜.Ƥm^uÀŽl£"|ÀµØÇ!&§æ~;B½Yí„‘=èï*[f†¬0 ±º€!$œcš?(¨9ör$)(M5`ÛИÅg{ ³ °Å‚ Co#.iÖóY8UKÊ lÞDÅþQ˜eUž±²©ú2K[ÊF<*äð¿ÝØD…ú‹¤1ø¯|çÈyô§Ë‡é)ÆÜ1_ïò¢W·ò{·bQzôhZM.¡Ñ¿^пr{ pèb¾M•j®Ûë†Á¿â“ækø9@Å&ç²>!×ö§¼HæEævGFn,ã^ÎËÊýkƒ’éELM“XÂÎWv u۪ŌC›lŽÙº é`“æ s…’v,æG…ò«]õï-¦8µNRÔRQú&ßÕÙýÍ#ÞKEžxLŒÝ’3ìlArL•ª—nH=Hy6¥á.¯€ö~ŽæÒ66úX µ…lêä\I‘éÀÀÿy3Þj°µbiáÌNÃËE_Ûèž­4 `ZuYN˜’ ÇËl%DcNPÂ%zÌ‹!:Ä N /HiyÁ±>/8·_1šÿà .àâT÷ö™ï›»G?|ò@‡ÐR"0â¯+<°ƒîŒã߆qÞ̬j|Àfµ´C<ð:xÒøÎ z[¿~:†Á¼±*ý,j |œÒKZeJ|³ç›æèš> endobj -1426 0 obj << -/D [1424 0 R /XYZ 72 720 null] ->> endobj -458 0 obj << -/D [1424 0 R /XYZ 72 347.18 null] ->> endobj -1423 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1429 0 obj << -/Length 1388 -/Filter /FlateDecode ->> -stream -xÚ¥WKsã6 ¾çW¨§Ê3±¬‡ñÞ²ytÒéÖ™Ä3¦íA–h›‰ô’RvÝ__€9q'Mz±@$|x96Aütó÷óòdtžóh>M§ÁrÌÒ`–ÄQœÍ‚eüŽ£,JÃ$™ÄáõÍ/Wçƒù4\.ïÃìl^£ ’YøEX›o„üµüytÝ¿2†é$ʦݸ(ŠÜJ­òªÚàà)œŸùËáNº|š…u>HÏÂ=-„*t«ÑC¬B«R6r„ZYb}ÛÊe¶´Üñ„KA‰)ù»6x²fÉÁåÌZ›Zª 2Säkp󊵪h@ý EÛ’$šO&dÛ¡, ›­°ÉqÆ -{Jl¶1c3§¡eí,Ék%hK¯»»hg­«J£è7Òöûvköÿ'Ô«ØG×Yü’³èlž’Ú¿jðÉ$€ÿ„¨Ž#ˆâ ‰¿6£ÈÙp…7¡:+pè,d͵woÞˆ’[U:|¸¸½óÌ -¬ 3lvþæträjwîÞ–EX¼Óæ ­Ö•(Ñ—h»PÙE`×ì+˜¸mWpŽè¼iŒ\µøá߯ï-·Â âqæQbc*кÐ;),ÑþØÃÄŸq2†ˆ­x¹G_èÖß;¼VP| ­éë”ï3¼î0ïåÞÖ‹Öz -´ÍY%u R‚ªI˜×üp :ù„z‰£Ùñ;ÆŒSP«1’[ËábDíB›Ò•q5~Oч‰ÕóGZ .Î ‹…Ï/íX…%x%úPrÖkY!6H¢#ð[Jûøf¶X{Å:”0Ô5ñàº]Õ½ž¾Œb âºØë -óù+ê]ÓÝ5vº~ÄüÏ7‹{.Fbê¹\¡ºƒ¤¹ñÞ0¢h´O"ë]BEo:ê….ÃÏd“¤+oÀe‹ÖWB€å⤼i‚ -P`Ièà—Ø,Œ V…HQÈø1¶6Ôå¶ÆhæZÆ—o¤ï)ô„}ñ¦2B Ø’ÅJQHì!ý´˜’Ýô>GðÚ¸–Ô/€Ô©TWø_5‡žó)¼r×í»0g$.nG_¸'a°WÓ"bކu+7®` mÄ×V"6o—Ý#öGŽß¸ß4ØlHó½mDMt¿×gŒ° ]ïàÄŠÒÄdÃdò@¶ `â?ÎzBi”žõpw¹¸?=VÑîÝç·¶‡ËKLDf†µ­\îV6ÉYË…; ¿¶@j\ðHÀ7C’ᕇI4æšA‰!l×?”äyÉÈî°}¢ÅèûûŠ›ðó5y0Ÿ§]×w*©º©€‡7ZàylVzmªï…Þ(ù·øˆå—б¸¨Ýÿ¥‹ã˜Pé'ÊÈ®kÁÒîüä±(¹I¹:`SEÁ=Ò­¡Õ³`±Í-œú®ÖÀQ×o]e…ë s'r>¶PÕÞŸó“³/L@hÖ¬K¨©O(7íÌ Ãt Dj,GBF"ö|W™hÁMê¹ÁÜP5é„ðùÙÀþ¿6Ô bXã¹õˆªŸà Òçúœ‡´•6Îâwε0Òñ¸÷€‰ˆ¹â»1ðפ$ÞÎý«Ø˜Üå1&p<mÛE6ˆäöà[xÖìvÝàs Þç“ø 5à„ô4 6y>äæˆc€¹“¹ÚNé<¥x@¢@ ±ê@KUzâ“«¨ï"´Ï7nˆŽ¡*.ý=/Ý€<ÖŸ®‰âC.~ù•îB:Ï^Œå³D7Ì!£µÎT$ :ÒSýH•Wôw‘çÅ׳Óa,i:âd §Óh–r\Ìâ¡«åÉ?åžîƒ -endstream -endobj -1428 0 obj << -/Type /Page -/Contents 1429 0 R -/Resources 1427 0 R -/MediaBox [0 0 612 792] -/Parent 1416 0 R ->> endobj -1430 0 obj << -/D [1428 0 R /XYZ 72 720 null] ->> endobj -462 0 obj << -/D [1428 0 R /XYZ 72 720 null] ->> endobj -1427 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1435 0 obj << -/Length 2604 -/Filter /FlateDecode ->> -stream -xÚ•É’Ûºñî¯P| õÊ¢¹/©ÊÁÛ¸œz~veÆ•Ô<瀡 j¸( é±’ŸOo (™ã$'6ºîz¬îWÁêý³@¾¯ož½¼ -³UúešF«›Ý*VyøAœ¯n¶«ß½ÄOÖ›0ŒRïêïïÞ®ãÐ{µ.ïæÝzç©÷oþ¼5ý¡VH=2âÊÔZHjÐýú7yyU¬J¿Ì¢ «M”úq³æÀ½ˆ™{z¦ç¯âÏÖ¬CP¡÷€ˆVWCgŽNZAlwoUÃ]g¨ºæ0Ú -óG3ìBU¯ÕÖà¡-k¯2¿Ì㵎ÓÂòlûœi~óñÇÍ…±ÃynfÓœpýÏÑ|[§™§jÝ®£Üx+_ƒ0¡#ƒ9ƒi42yègQ±Ú°‰˜•j·²}З¡µ6í½lPÔ•©Í`tï¯7i‘yW€ù€‡÷ë;€Þ¢l8l1%&Ÿ^î{Æ {}$¸I8*)'Ⱥ˄Ç5¬¬P y`³}„2ôjÕbܪÒ}Ür°°×(‹e>BMGæÙ«·°»$ -½/=m?Ê"XÃõ÷A·[- Àê͉›i5Cý±E…õ‹òÜyâìphµcÚë\Žá‰]ßYA™¡gàÌq7ƒÅØ û%ÓoâÔtR:+§be¡öL|DMu]óˆ°@u²ž è­j4ž0îN=°Ï Ã-{%û¤º—ÝŽÉÃÞˆDµÝ‚Wu­ª™bZ¬F! -M›Æ?žà|Ÿ.v`˜Ãá™æP³1QDœˆßiPýC¤j4~æXs@‰÷ù“˜Â/£òÉ´æž[”^×2æÖÔÝ=£n‹`ƒ$Üѹnž1`ö^e™òæóËŒŒüHxZFH¤§éE:à;—^Ü`MìÝ{JH ¾qãŽå‡ü]HêóNe pTÆHOjÕ¥Ežk£jÊçs–ƒõ¹´ËöÔgô‡VxH»èMOY(^W©¹d/Ù°¢^¶RÎQ`Ú`•kšéü3¬4Rz*#ž˜MWQX!}ežÝq³©,b@ÆY±Ôàâ ®Tœ¬6÷{®Ý 9rÊñ t¡ÒOaKnÎ0»š8'%‚{r¦óý!¬ü´yWä§é""Æè,çK'øDÜÄQåØV|Då&GÝdeὦâ¤Ì,7_Ry2Q‡sfM ,ZSæIQ̦«YvB¹ ÜÏ9,˜ µ‰1ß2%î,´ ZÕÒ½,ÍÑ™Ÿn/û)ö9ôù‚gf·Wÿ£•œÞ?q—úÛžRssZt]à!½<Ûƒ(‰8Cc_¬¬KûQâúL¼ºë¢²…<äŠ4jYIaå?Ñ…~j¡©­ñ¹„ ÇAdåç©Õôòú¥“#©œ/“I-Óùu¾ç™Ít¹ò›š)ÜaoÊDÓ2^ñçÑl5æ™X9MèEžc°xÇ!ÞÙÁ`BxÕåi½pJ>¬b@ÇåšÏ‡G§‡\²ôß|úˆlA‘Rè›+œøãQ¦°%€Íí›ß˜ˆëEuƒÕýt7&Š[¥¿ëjô N/)8Ï]Ú0¤¶ÆMqN/ íº©ËÅì²eìT þÆÉåæŸûLûÈmDžÏß=á¾ÒÜç¢vŽjãÐYl¶d~Me¦¢®kS•Tr’·”¿¯uåŠÕ³ˆÁÊÞ¯øëûg«ß)¶¿  îÝÖùüh]<ÉÆ‘_dåôôë‡øø›îñ7ÂÇßL^ ïº#ÀAwôôûn2»(bNàÓÅ¢pOqš-Sj*Þ“H8_¿ -×Ûæ›±Ã(ýq‘LË÷Ê…SøqdŠ$¼“3ØÝX‹š§LZЭ¡2½¦§ËìÉ÷™éÙjk•\£Bßa%¡‡ó„;©ÏoZ@—&%±oëý¸WÃBÛ6%ø;®”p£‚f›²E’z¯¤ (iõw/mbþÆædÏÄ}_^ÅÁ…M ¿(ÃÙ[Í+´G¥Þë?ýâß6¯¾üyÙ'p}$± ÕÃŽÕ z.ÔĘ®šÿ‡f™GY…¯£ì å61ÏhüðB(«•›µã/^8´ì’?ܨ!Dçè¸ êxè9žÈó§ZxáðHå$Z^Â…M·UÇ Ñ·³[§'¿©ÀÏA˨ۡ>.ñ%EŸhnÏØÁEòçüüÿjbôÁ$H ½a 8Hù-±p%yÁÏ0$Q­Fºãã †~g¤§hZ6µª¿&â—::÷ÀA˜ -ï¿Ú -ã;j ƒD®4º(ÁVÝá~HN}•e)`Wy ¸ªn–Îê²1™ÒÎSm•~–«MÙPVçáÙœw7Ïþ=|Y« -endstream -endobj -1434 0 obj << -/Type /Page -/Contents 1435 0 R -/Resources 1433 0 R -/MediaBox [0 0 612 792] -/Parent 1416 0 R -/Annots [ 1431 0 R ] ->> endobj -1431 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.873 337.974 120.596 346.775] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8) >> ->> endobj -1436 0 obj << -/D [1434 0 R /XYZ 72 720 null] ->> endobj -466 0 obj << -/D [1434 0 R /XYZ 72 720 null] ->> endobj -470 0 obj << -/D [1434 0 R /XYZ 72 325.03 null] ->> endobj -1433 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F7 1089 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1439 0 obj << -/Length 1706 -/Filter /FlateDecode ->> -stream -xÚ­XKsÛ6¾ûWpr)Õ±h|{’̸±I'¯ÆjUt`IHâ”UŠ£ß],@‘’œÔ©/±X,öùíÂÌY8Ìy}ÆÌï/“³‹[‘8©—F"r&s'NÌ™ÇüØ™ÎÔ ¼Àã9™{ûæíÍõÈîÕ(ÜÉÍhˆÈ½Û­‘Öf_Íz»Zej7šM~½¸í Lx1ãpµ–ý{S®£±3·]Jüà®ÚV²!Ú¢ü2‰+×´S®‰|'ó¶¬×(ý E1G-úøôúÌ™j&îEšÁ -·Ãñ„¹Iiv+þ×h ëªÌ T[ÝL¸»£‹ë9ŠrÆV{p…—†!Ù@W£Äü„Êû¾›×àƒu‹À­@wîJZ4à-à×ÞBÎl³ÑJÈL™³Yƒ*\ °¿·>ëy”Z‰—¤¼§ÍÆ%¡;-Ju9›fóõÌ.fÓzƒÞkfÓçç/ÎkE/§Eá­VÞnGë¶\ÉÙì8€ö:A×M–%¨*Ào*ƒ‚0¥n‘mÁ„`t‘"¿n”lŒšæ^eè-(Òî4­T²°[}6H™ýMBP¶ô»Ý˜5¹µ¶» Ýý™ñà ª#i !×kI'Ó6p¯ªŠXLLcŒi€YŽágøwñ 8ÃøbÒâgŽ¡ÿ–MKÈý«3?3†¨U/T¶¢Å:[ifîÎkP -¢6÷ºÌ•Ö5ÈÔ.¥—þ£/ÕAÎ*Z¡ dU ;­;ˆû”•M¹X—ú¸:§ÜÔUYÜ.÷JÖ¨Ï=Õ3°ÕªŠ2øfrö)TŽð±È‰pòÕÙtÆœèp¯ç§‰s¯¹VŽ}/ŒcNåÜý6<¦€H€Yß8œd×(7¹ØKã$Å^Ì2uP,œ±ˆ»·e%ɜƔh®‘gÚ_zÇøÖ;6Õ¡6âñúÍM„Çcñæ&¡‡©1÷ÍiÂÝ¥µ(èÇü[V=Z­¡U1óŸÂªr…Ù ZtÃú,ÛªGk54*L<=I¨"î% á0çýNêÅQlûèóc †Ä†ãfß”î‹s -0€þ±@Â)º/%ÂPòÈ2ôúŠ6ýŠ1÷:km«ÓÐ eƒÐ¤s -2M/ ‚ÖLÊý‡È<ÚµG‘a‘ÿÌ9 ˆ „n›Ÿ†ÏÈÂ'|‡ýâ¡ÍF*šbü®vÄŠ -)¦o©ZCL±ÍXÏaO~„à}Q+¢ÚÏú’“ð„<}èÜû¥4rÖõ~¿²ºeJžlé²ÀvdÿðßЌִv•ÙÞ!³Ù—¦UÌmG1` íLÊAÉ9¥)äB¶YYy”£â`>DN¢´?¼ -3¼’Âa‡ë@ºÓ`r=ÄuÍ÷ž¨‚ä¥Ý{ÜË}†N Ùgî·×Ï€R´Ó,kÕÂ6§e–çrƒƒŠÞk!¸™*hõêãÅ;:L!2<](Æ4“Z}(`iµ·EóÄÕ×óØFÛ -iNÖyµ-(xÃX9)gr=–zΰrs˜ÏÚ¢ùNeá«Pfh'º8qÿ|õñ“a(äF­v´ì¢=Ì}3'!«'²’l¡IÉg±‹xÒÐg÷p@û¸p3ì|í³¹0Û5u•µd¤,ìml•súÅrÁ3}ó€LaFá©C=ˆL ô|«”™=»óv€;!&kàU" ½0±E³k©p࣊T«~qù>S:pwÕºÖšG½?Äé÷Ç%}ØgFoÄzðiaÐõæk¶Ú€f?¤Å5]÷þÃ7o½Ÿ¿ûŒy§ÀR`Ò¥ï\˜gÊ¢\¯;˜»/Û¥Å,†&!ñ4 Àû(´xfD·vÿ €cŸJðôð~ä hŒ.ŸÆn;=u¨ìŠ¢gã¶Áˆ_íò!C @üûxþñà÷±;¬è  ?ˆÑ÷b¿U¨D¢ÐÕY.óZwÔõFZèB‰"ýïX=õæþQ,º<#[ÖѾO#±›hÆaÀÝWæA¶QoPÇø‚$ì1,.`*—:&@>Ñi€Š3ò5²‚¬ÑèÓôóiZ@Z5›Ê¾º‘°1,tc1_F!4%UÖ[sÿ=º€ŽiTöcãN8´GXÌqšÓ ƒ&ÌvËMߟ-ú+pïÿÆŸÞ¿;¾ 80)S”ûè¡£(A¯}9X&Eû«º;6?¨”SïâÞ{ÄvÖL·Ô!Ð9B¤ã)x‹ÁS€'¤d,\0*ÿ g¸éŒ -endstream -endobj -1438 0 obj << -/Type /Page -/Contents 1439 0 R -/Resources 1437 0 R -/MediaBox [0 0 612 792] -/Parent 1416 0 R -/Annots [ 1432 0 R ] ->> endobj -1432 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [417.47 707.104 432.192 717.952] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1440 0 obj << -/D [1438 0 R /XYZ 72 720 null] ->> endobj -474 0 obj << -/D [1438 0 R /XYZ 72 720 null] ->> endobj -478 0 obj << -/D [1438 0 R /XYZ 72 514.588 null] ->> endobj -482 0 obj << -/D [1438 0 R /XYZ 72 271.95 null] ->> endobj -1437 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1443 0 obj << -/Length 1963 -/Filter /FlateDecode ->> -stream -xÚ­XÛrÛF}×W ö%P$Ž0\ý&[ònR±][Vž²® - IÔâÂÅ%Š+µÿ¾ÝÓ= @RβÂr0˜KŸ3}9ÏÙ8žó÷+ÿÿs%áßs¤ûN,S‘xÒÉë«_¾xNý?:žPi⼘Qµã'‰ðhVÎç«L÷bÑ·¦ÃH)Ò0äéoŸ®îÞÃr©H#?ržÖN‹4NÀ)|¥œ§ÂùÅý´ʶ¹^IßóÜ:kÊfsýåéǫǧ™*òвóX`ˆÒPD©<à Qš -þ „»ëU å>”ý®Ê®ýÄýz½R*pŸÇ²VeƒOÊÝêj÷*²óM["K”ˆUt dI,”χs–§^è~n» [MhÚqصŸg˜‹làwÖçÐ#ÝæZºž®×v…î^§ãl,ì‹È]wm½ðæÀ…óçd˜A(ó¸–ŠàÜ/l²Ô6Óuåo¸Í7Âû\  šB-IxŽ<æ VIG,îÌqkp[°Å¢Á®ìÿ7ü¬[èHáEɽ¢A9²ÒÖµÉnØQ•ð²ÑôÐuh·°™píØåaPXáaèZÓYŒ¹5A—ÀtGíu[UÆ–ÜÒì²aCéN•ÚýÎØ®ó{óŒDª1‰—{¥ñ˜€ª3n¡£õ¶Ú}¹iÌJÆ/<ô Ð»ƒ)PSîkêÏìk2ÅÌ=i -¾)ѳ<ånÐk€ŒæŸÓ=k8¨ÆW£©¶0”Iˆ‘| ¤«ç›NÛËB÷ÃX å®Z€²KsLÌYàС£g'ß°W7\ÈlMlŽjœ!u!ú÷\[&Qe¬©û ¦o©ù²-s\K#jl`SWg†ôxò;ò¢ÓF^V5bB’ˆÔO ÉãïY ðû7&&½ƒ+ÖÝ{åÍ¢æú‘Qkfî{(|¡ºww8yHv¨-‘G—”“ûûC@÷£Á”mÈÜÿ×"ÿÀ¢ç[„|aàZ=‡‡Õ޳¢‚Vü–nîþëV¥cåšr,ÝyJf×éA Y˜ßWŽÄù‘FËf²Å‹ ËýÓ•*ˆc"B ÆH¾FÐ6¡„µ•oÖ†,ð–DÈÀAŒÙœäGÛÕ€ðë5Ü<ôfe îlsÅPP÷$Â!~ßÿðÓã>ßã"O4øáÄcÉÁÎj·å|®‡27›AûõB·ÉjŽ¡•5v‘ž0¦ƒ •*¸ùµMâTj:WÜ9¥|(›~èFTÍø47:pŸð`i¡¥½QÝØ²Æa›®af=Lýý`|"+à2] «rÔp¼ÿD+>ØM¦úcÖžs#×' -úWysÿ -”ü 0H%§?dÒ6tÖU¥Æl†ƒ÷¦DdW×vxÎÄ$Ì(ö’»§žié -5÷°_‹æ]`a %ñâmÉý%o ԬNJÚes -k¡ÝÕe3EÑAŽ^¨ÖÞ$•ÿ=E*¨ -Ý\3ýbüí<‘¶íÕ+šEm4ÝÅcªÐ“Ñ#¨Ž‡Y€øf w±±Ó·ô”ñ´r çNÓ̬ê©/P°S¢Òáa•©Ûý¶ÜõÖ, -&R$è5T#KÖß‚c“@GP M1bcŒv‚PÔ]R‰ «J£) Ùk„‘ƒñBiëb›u êY¬ã»> endobj -1444 0 obj << -/D [1442 0 R /XYZ 72 720 null] ->> endobj -486 0 obj << -/D [1442 0 R /XYZ 72 365.718 null] ->> endobj -1441 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1448 0 obj << -/Length 2586 -/Filter /FlateDecode ->> -stream -xÚY[oë6~?¿Âè“ŒÆ -%Q·EOl.‹.ÚƒƒÆÁMó XrLY -$¹©±~çF]lå´gŸD‡äpføÍ ¥/ µø×%ß®?\ÞùÉ"uÓÈëí"ö±§\Ä‹u¾xt´«]Ï \¹ò¼P9­©^–« Ž«Í¦h[ngUÎë¦Èº‚Û÷]¶m—Oë_Þ÷ðýÄõ•Ðëòû‰sÅ^ˇµ¸_¿v¦®Zl„¹®Ê#·Šß•›Îü±ÄßvEÅ­M½Gú³©ŠeY¬ìþp"7 C–âÍt»åJ‡žSw»¢Á¦²[»ËUœFÎhMdië¦#= l¯Ë¢å‘gÜëÈí4Ñ¢¸{XzN•óÒžÓᩱñ»èï¿“ýš¶ún"ƒÈ& mQ≿&UMÏØ‚$¨¢Á ª9‰YLl&°N¨Ú¢`ú33—5®÷CÞl <çî§Ÿoo–d°$pÖ·Ì^ÕÍ>+É(°Ò¡å5c>(6~΀çÞ/5-Ÿ“(› ÏȤ1Ðx¤bç§íÉW¼:ª»×üaÍØ :r^Ð9b§¨.°ŸÎ¸Dh‚± -nƒÜ÷Th½ÃC»e‡§qTeSÆc\Ész-¨Lžbª¶+²œ;õÖî. [Ï©kÎÂìnA8]_M¾Ê¸X—$6´÷Y·Aì¸+äök&nê§¼æíŸ°& þ{è°ßË»@î6Ìõc×÷>în–«ÐËï¯Îqà„÷Æ´¯e&÷%G¡À 䨨Ïä¬ l Œ7¤Ý -' -Cn¸us䮩˜]æ`;º†ÃXxaÆúV™üF~ÓÈÌ’ ‚Ê_7ÉÝoÑLt¢™ëß®™¬D½ Z³*jŠwu£å܉=÷9hc'“oçƒ?¡Špm\Ü?‘<ðÝ0ñ¦á#ð!' |çÈq$J«²äÆ{ñ‹µ¦Ÿ,Ѐxý`rµ³F«à•ö·WEOô%£|u…ÊW Ø-Ücý@—¯t•¨è æ+,_K1ö`?L :ðkÁa€c¤²LØB¼Ä/Í= –ü0!I‹2—1„Œ®ëb¼™l¢µì‘¶ÐÈe÷ß–º/ÕòÅfÞs¸wyÁõδÂo€Ÿ…•I¤jdí9Ý–™M.‡6[²õ Zõ¦ÐÞ;ÕDézªtèfÌôÒÇ{¼üDù&á¼ïìk–aGý@P[NÍ`#€ï³Mœi§jSrBCêñ<6µ:»$LèÔR_ŽÊÃBœcp'F¬ÆBÕ:UEÇqö}?ó§~Íú–&g"(ÐéÐ:t® {›s·Äs“èÝl -ª®wSŠîéÇL ® YJr 1ĉIP¸gL£Uq‡ ¸®xˆ6Ñ4£ Tyø| -I›¬b¢$/L…Ms&sÎO¯ú — #)è!éÀ™}ýŒ4IµlØY©& 6qȤób›$i$m!ìL©Â¥-Ær‰0†ÞKÖœK8¥€üeºW_MÃù|m¶DpZ[E#U`ç"£Q%%' +oCO‚ ÀÎï3(x(F( !x#ƒß ”¦t©EŒ†;ŠûÛäB3§G£\Xé2FÞh¢}©²}Ác‡ª´é0ñ‘Íß‘WarD¡­,­ƒŠ”•ŸR@\ Í„§„Ph1áëÏ0ö+¶.Nv|/Ì$#ë#üÄ#ø!"ÎŒúô¯‡=Ÿ!®üüm¬±C:ˆrÃÞ­{Œ¼þ™·ÁÈÄvrÒÈÒé{Ÿ‡º0 Az*o~Šc$”Ì ™2pz¦6Ò¹ü7õ~߯ÅI Õ¹’ÒŠ‘†%úÊëØp‰|+Ú8ðœ_jvSÌRúç[R÷kS¿4Ù¾åÞ¸x‰ÆŒ ÞêÀ@TYä„ëè@䣉Dƒoû|9ô¡ˆW" ˆ :~ÆØèá`ƶPêð,~*5\:§d¤A~ƒñ Yn é?¨X,Üp¾Tb -AÒ€Äi:(DÙÚœ–£\—¡PÁ=À"E P©)·f :stŠ"A¤‡(‚1¹;<ÔA‡|¿d¢3è[EpRøNMë÷¦Õƒi}kZ}bZ={Š–ìló-२°@äPõí{9¿¢½@ÈŽ2ò²ak¡“×UŸÊü€èEWè=øàõxùôøÃ·?ÊõˆßóÜÝïÝã‘ûh˧§¿|[÷‰ ¸d˜(ûL¸b¾°@±EÏ+t§OóÎ>Y`I:ý[Q.iäöd† UŠžÅ·!g.ã;»LSÈ:Ûº”ŽÀ*’J\ö-å|u3ɰÿò±ðø@÷MËO? ‡Ä#}Çã(7$ ™<‰Ò<œaïª~DqDîõ@}ŸšÁ¢½pÄFX‘û¡*éч,pÌ”ãéQÔ†Îè!×ÃT¸zù‘;§©-[zöxXÛõžwûÈ¡¼1¨xZ* ¨Ìù-õ°!»{ÖòŠ1–^$4/ 'GôërT> endobj -1449 0 obj << -/D [1447 0 R /XYZ 72 720 null] ->> endobj -490 0 obj << -/D [1447 0 R /XYZ 72 720 null] ->> endobj -494 0 obj << -/D [1447 0 R /XYZ 72 518.831 null] ->> endobj -498 0 obj << -/D [1447 0 R /XYZ 72 450.385 null] ->> endobj -502 0 obj << -/D [1447 0 R /XYZ 72 393.893 null] ->> endobj -506 0 obj << -/D [1447 0 R /XYZ 72 336.848 null] ->> endobj -510 0 obj << -/D [1447 0 R /XYZ 72 256.999 null] ->> endobj -1446 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1452 0 obj << -/Length 1844 -/Filter /FlateDecode ->> -stream -xÚ­XYoÜF ~÷¯òRmãUf$­Ž - qÓ¢EÑx_ -'³Òجc£#΢¾äÒ®%¶“p4‡×9+¬KX¿ þ¾Üž=»p#+vâÀ ¬íµºV(…#¼ÐÚ¦Ö•í;¾#ñoµ–r#ì_U§Wk/ÞØ—ùM•¿Ò×M»z·ýãÙÅ)鎸 Ű¹øýÏW¿®ÜÈ~±Š<{û -Xøž½oêÕݶº¥µ”À¨Ý›M)‰êòºb¢¼¢o‰,ûdå†vF+]6œV%îHá>Ý-Ьõ 7XëÄ› iò ä&Üe­þc­?·Ï[ºÐIGc…вߵš—êkú’´ÖY­}Ï·_ר¹±$Hûƒ5çH‘#]šæ(‰f]Í_ã £v+içž:L‰NµbÑÆbêý¾WPyÕMorÒ©¢)ºâœn@×–ýÓŽ”£+Ex¤šÝÑ|PÐL®›º¤ó;ðyhëëºa†uò®;= igA[g´7rb7&{_êDõ­a-q£*Œt02a*åsðþ4<¾:ø‚†ã]ÖhA ×ÕoÆö]¦+Í×ODœÔ=MÃh¦šÅåÒ=<}wÃùÕv8óíN­êÜÏ8T Þ .ßàBÞAD‡2²·Yþ0Á¬™¦Êß÷<&ñ@{Ú¢_ 0Í1Ì1ÏäXṯ1{ç@­S:9fÖÔKn,Œý7uê);¾ôT´à(é:Á&"?ü aå -ñyÜey‚Ñ^©º±úÜçï^—<Ú¦‰K6qèH`ó=‚Gˆž_¾CðœàðúSˆÄƒ,<Ì]·wæ®À‰eø˜\ý4„€M$7 ÈÜaÌÐÄ?ÁRÜÏËR§9ÚÞ7:Ñé<µüö—ñ›]¾×K(*@Ô4×VXyª›ƒ‚N¨¥C7:iü =׉fmŸ{Òö-ty±t¼pŒƒs;uk@y^îCÊss±bÖ>»ðÄ ÿ5 Ë(vIÌUªWNYW]vå´j®Vë €~V÷ÍÕó2¯úN¿ÃŸê+˜“$NÐ%<@ ñ0ñO]À­|Ð4íòRY æeÝ j,ØA0È;]¶<¬è»k”òhÇ»j8Zï1 T½‚/ bUéŒeZw-o&u]O(*æÇöEÏ0çÂhóF3m~=Š:,ÖId×@ÕP#{¯±«Ï‚VnìÚàkÕ™™c€Q§ù6¯àÕ3±1ÁàåBÁèF\ÍqC9¢™Rç¤ޱÔã·FªðtÍûÝØ×´BF–HŒÝ±YÈoònà2ãz—i¢–K…DÁÅR##mgɯÁ8ìf¤À®NÚÜ=ùd¶m_¢81q¡¦ †nºþD‹ˆo¥ç—Øu«æðA™@ØBŸ„Áx ,{#˜"k =”öMFó8>ÑÍèCsyHôMÃ>§g¡Ýõ ßá‚ÑPg ™ƒ25teB hzÜpáõã¡S#&pS錺 ëa${6>±|x¦¬ø‚‘DTå¾Ðç_ žQúÇÏ…¼f]Bû2/ô®éá -Iê6Ë›ôœÆ2Ž"ªîD)3zñ×½¸„Ù3HGɇ–° 'w8ußѤєÂÄ’¢65ÞôH·|ʼp øàPö lìé± U°9Ç®¦o©š[d;\Î+PO¥4Á5~3J #²â½#:´‹I·5/Âsøâ‹ -âÄä»y ÃÚ‡Õ¼[àÛ÷¨9¤n¦#‡*it9ÀNJ‹Z}$ÌÈÀQ tÏy{K\Tb$ݶS®i]™wvÓÐ{ø: áZLÉðùŒ;ïa§çœËIuÈSOàVxÁæ×ˆ8FÞ>4ÄŒ¹?´4AŠª^Þåæ'‹À÷ì7T‡÷˜ ûk™ºáµ ãŸmߌñÈcØo'!€=}BKX¤hõøD;=º~ZZp-šŒ‡…_4 8Þ465Õ `l0†Ÿüo è±´\Ü?øÞ½9ù-€Á˜ówÒÕ;Ìf”y™aÊ*F8Œ7“–fk‚Ôè*Ä´Ý]ì±ì¡Ã&e[X¸ËŸpŸ¬N~kN8˜Åðó=¿ø5†íËÉQÈÍ`ÈMê9ù)r$‚$BÈéf?q2r‹òà"a¹.¼ßd 4|}~„› ¼dþíHg7 -endstream -endobj -1451 0 obj << -/Type /Page -/Contents 1452 0 R -/Resources 1450 0 R -/MediaBox [0 0 612 792] -/Parent 1445 0 R ->> endobj -1453 0 obj << -/D [1451 0 R /XYZ 72 720 null] ->> endobj -514 0 obj << -/D [1451 0 R /XYZ 72 720 null] ->> endobj -518 0 obj << -/D [1451 0 R /XYZ 72 564.844 null] ->> endobj -1450 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F11 833 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1456 0 obj << -/Length 2402 -/Filter /FlateDecode ->> -stream -xÚ­Z[wã¶~÷¯Ð[)gàJ{šžã½8mï¶µszÚ$´D­y*‰.IíFÿ> @ ºÐK‡>¦@œù0—o†¤“O:ùþ‚žùÿæþâÛA'†˜”§“ûÅDó‰f”P¡'÷óÉÏÉ%á$˦WЫļ¾œþzÿ÷oo²½trÅ3’†ó›§)üNŠYù e²hì‚£Ç<3lÁq‹ëÿÁçÍó­¿ØÔåú^ßõ&¯·¯ð'3Yæ/uµ -‚RŠWmF”Á«ëÛó:xnÊu¾\n§™H`k!iR­ ¸&©jü¿ªj?2Ï[U¶ÅªÁù«| - lqüñ¬Ê¶-æ~ßr£_Ë™]ñˆ?gÓ+–ä_ró·ß¿³w¯­D÷ïq´Ù<4mÙnÚ¢ÁöÑÏŸmêºXÛí¡ˆ ´· -3FŒR¨pû˜ÃTÉ¥ÓL¯4Ë’•Sx¤ŽÔJUNY²ØºÓ°÷r\Ö–«óÆ=ú‘&Ç{2)À$D1óÛ†‰;‹9¿¯LªÞ¸|} ØI©“Y¾iü|0Ò#é0’xú'´]åm¶6 µ½ÈÜÃP^e4¹nðæ—²}Ļį›c[àÝj½ÜâÝžòº-ó½ýp¸lpäSùÙ>¸Xû}Nœ,ÌŠOV( „3os'”\ ¥ŠdU6“ÒÚ±ÕPJ™üµ@ –I^Ùúë¦r;úŦ†#¬q¸ø-_=-‹æµsç÷÷ÿ¿`ðD:a6`(­‰0“Ùêâç_édà Œd“/nÒjÂ3MŒ4p½œÜ]üó`yªißz˜‰ºár¶ø¾ƒFg°¸1Á;göÜ(–ÜùÚ‚p$½PÆ 6\†#lÈ|1ÊFY>‚S¨”ÈÔ ¿PE–ùúpÁ -¦yò6Ž2™ÃéçÖu¶Öu^áàªÂ)¯Ðòõ/¶vf‘×Ýxè„7K–œ+ã$)1\“”D1‰8qNÈ¥Q× §4yWÌŠ•U÷ãŸ÷νîz´¿ ªT„¢†ÁzÄ0@¶2zsœ(ea`cAÿ,$°ý÷Ì@>«û`ácÝ™&”bœ’”ú`4çVó>qúbÞÇ&âÝç¥Ð Ö-††BJG1 š‘TfšKï€Ìõ¾6ó|Ïù$êò88ô©>XöHuia4AuiR’š`’¥Ê̾ÞÂé}d -·y½£pÈWœÚE":›Ú:*p*’>k'õÁÊaŠV&‰ÞN ÃÈ,Õ@Ÿë¦Ý!u`!²’.ë L:}P Ö5†*5„™QìJs¢³`Wž„1 %Õ·vo)`å"m„š¾­ú2ÅBèš·:î*,îJ ç?n{p¬Ø.ÄÍ Âs‚´Á>ÂÉóÜ;Šb¨M!H]‚Ô€ýˆP×S“b¿æÜm×v¬Í;ŸsEDªü×3߉s”¦ÚàGÛgŸÝ±ØÜˆ}híÁð¬Z­|¢7I³ÅŠž‹­ÅÅ®_èsMx|”kö;N¶—&2ä¢Viû‡êÜè¬ËŸÞAëÀ›q£×'>»] -ä÷i÷K!3±K0kÚÎdM{ËZ’ ®ºÂ+Ç6êV•%–vl³^–«Òç‰Þ×ç©J!-––4u<=ò¦pD]'ždzHOµÅ|6 yõ¹6˜€†õ‡n2"9œ°kà Ä oʬŠº@o?ÞÞ^xwÂ5uÒ p,7Pl:JS†C9‘2ï‘7ïþ[üø¯^_’ÿfâê;Ï~,C©m\¸ØÍŠÒAÞvÛi·þ\æaƒ•aøâbÞ×`}c¸€yÓ?Ö¼a¶¨aÂ'©ò¡ÿ0ãË §XP±.fQ—Êj -µéÑu°°ºf@køË]B¥D³l—HaU]e€T³Z¼›“.Í%Ô·©ô%ä<é=òФ!º)ûÖi[ðA:ÜÕÏÝ6ží•p¾mUŸM¿áL+c"8Éh6&"…e¾{M)3Ö¥m9Ö~ñvÞý–iŠxV9¯Ë޾ƒªo<»ˆÞëKß¿ ¼2*PÃ'öÆS]|.«MÓ5?]Ÿ¸!=à ÕîÊÙ‹]’¥‚dé(/pYª‰ 5ÙWeé‚ÁBÄ:(¸ÅÆhå0¥ˆ4ž”YCHmS< -ð=NÒùÓ‘A×|°è±æP5F‹›A}¯¤MßL¯4…̶‹#™yØkq÷•>«,y¬8Ï0Ž1Œ¨Ìg’Ÿìç3TœV<Ô!2Š‚Q<ó=èK*ìªÂ}Ô7 'Dî+-(ÌP®jo,:¾ -éLy4µ -endstream -endobj -1455 0 obj << -/Type /Page -/Contents 1456 0 R -/Resources 1454 0 R -/MediaBox [0 0 612 792] -/Parent 1445 0 R ->> endobj -1457 0 obj << -/D [1455 0 R /XYZ 72 720 null] ->> endobj -522 0 obj << -/D [1455 0 R /XYZ 72 454.857 null] ->> endobj -526 0 obj << -/D [1455 0 R /XYZ 72 354.042 null] ->> endobj -1454 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1460 0 obj << -/Length 2254 -/Filter /FlateDecode ->> -stream -xÚ­ÙrÛFò]_ÁòX! §ªöAÖ±±7²½¦RN9ÉD M”A€Á!E[þøík@‚²Þ­Å fº{úš¾oöeæÍþ~âÉûõÝÉÙŸÌR7ühv·žÅþ,Vžëéxv—Ï~u7pýùB©ÐsnÞüt}5×¾s1O#çîz¾ÐIà¼ï»]ßÍ¿{{v3æäÍ~èêH3£7©“›uÖ—o¶õ|á'ãío^èU5¯ë]WÔU˛֔fÕ™Ô)€B-ÊÀá‹y¢Yä^´»2Cð“í6Â|Õ7©%Âó¬TVåB\lA™è•»MvOêš®ø—ÉÑb4R)7 C6²,Ú®¨¾Ì¯0D9k^ge‰ LTA9WŽAd+ÈŽq¤*TELÞ¸5¼%å°oM# Ædà™ Ð «f|ç±è6L)¼}²ºµl@‘\dƒå~Ü€ìÃC¤µuç~ì˜ÆL9`jÀ=áQ™µèk?p²ÕÊ´-Ú,ÈH<ì‡#ª-`HÄp‘(sàTTyñPä oŸ•|l8ßÕ…±žÌ¬…K"'ËkwÙÊð²1Û¬¨èÆðH] ÇàmÜM™:܉;_„J97…Ü«AX×5Å}O®Öaˆ×à òÁfŽf‚YC ygegšŠã¸°ÅF¼‚˜!ÅZˆQúÃWE™Ý—³ƒQ}•c`àòóå‡ZT|3œfâ­Aaô¯¾†˜ík«Þ"öƒ¸ÓX»ß”p8¯XD¬PÕMÖdàÌæ/XéVè t âÑÖuGLÑòñvS#ôn³–Ñ™ìÉÚ²¨„ß ({r}wòlj½™šéÀ‡Ê6‹tìz¡ž­¶'¿þîÍrÀU®N“Ù#Qng¾›&)¬ÊÙòäŸ\&ǵM¡ë©8EnJ…{É^•(½¿bÛš1ri•KCoƒ¯4ÉZ¨ÄMý”e½«›-ÜÏÖ>ôg¢& -¢A­€VÉQiD\.Z¤ ÜbÅebŒ1BtBŠé¨MÓ2zÝÔ[FÈ-•W¤áÈ,{Ó’‚ûrƒÔ”Üe.Š€döfâDªqRÑQa›€+Ê0‰±óDé™ ¾å7F†ëº¯ %¢ÚÈZXÝ0Îü™mw¥Á:ªã½Tæ“ _XlÁY>’ñ¶^ ^äHr‘Ú\ÇÜZˆ‚œoÁP - -h¶W5š -î“ÞƒÅÁõ·ò}UR‰EÚNúê `…Å‘Y õ¦î¤}¢öX².aëßðÛúc\˜¤žs·±¬ûjUö]Gar -ËØèZHûã¢,9½Û)ûÍŸ;6¼)Lµ"'>5¾–—hk(ç¾ JòËðãrîÇ}Ñn`8É#S¨×Ç.;Û5桨{‘!PŒä€‚¾ÄॣÜAk'#9i­Ñ±1:ölê7TóÐkÄRë`ð¼Ðã•sŸÜÃxf’5òãÕ4PdäØ^àb²o _$MoþÑø¦}7öÒÑè*™¯ì‡óÀ߬Æàx6*`ªØ› 5Â(¢pÔ÷¢(W'`@â›&'…û„°•ÛF¸}}Ê´<!Dñë‹©LÃ9ˆx{ü]Í=9lÑa÷4|÷&U~·9åJlm9¸A•& ;Ç8¼Œô<ôrqëòâÎ^ÔªÞny(h)+©2¹˜¶€"D®ætû>»ÑÞшƒ*2«S¸ÀÊÂìòZ“Ú¡ëk Ónª˜ì’ŠhÇT\@C;Oႆà‰Fÿm*€•ᆱÜ$q]±;ŠCç’ -TXíyÎ…Ì~´¹­óbÙéÃf‰#¹–•3þÛÑWçÅáó?B§,yí©óÅÇë‹+¡so±…*PÓÕîûUç⟇‘àýÄB•w®,ô6Æþ. ¾¾$ñòÇëË|Z²çÝÏ׿X>‘kŸð´¸0Níói£„ÌU8¹§^J$ÅàÖ~›d$N[s‚è~˜ÿÓÑ÷˜QºÞ «ÇÉÙuCcDJ‰Ç­÷#œFÈ}T£™ŠªXú[™{¡+¿BhÂ?#´ýs‹Éøw¬yz„ ÉvE—•ô#Œ©k!¨òbÅ0`7Š ÜR Ìo°±“Pz |"h†ÂÅñÁ†hò©‹þ -ì„ HþçB3¯,Úl+8Ž^ž£íX‰ô«¥™ã?\Êxfï‰BU¹à=‰ØïðþS-.ÿ±€!ÿ½8Μ'iS8|Ú#ÁìäX4ŠqódÛ7V|CPÚfÇ Bûc Ûº6À†Ñr²ý±¯M¾×AØÔGìJ“=ãÇÊ -ײÍÁß3º^^^/—5ºŽ¼zP4ü”ÚÀ;IÇ'®ïNþ ÷1ó­ -endstream -endobj -1459 0 obj << -/Type /Page -/Contents 1460 0 R -/Resources 1458 0 R -/MediaBox [0 0 612 792] -/Parent 1445 0 R ->> endobj -1461 0 obj << -/D [1459 0 R /XYZ 72 720 null] ->> endobj -530 0 obj << -/D [1459 0 R /XYZ 72 720 null] ->> endobj -534 0 obj << -/D [1459 0 R /XYZ 72 553.833 null] ->> endobj -538 0 obj << -/D [1459 0 R /XYZ 72 262.526 null] ->> endobj -1458 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1464 0 obj << -/Length 2161 -/Filter /FlateDecode ->> -stream -xÚÅXÝoÛF ï_aìIncUwúÐiâ¬íšv¨ tëºÅ’c¡²dHrƒtýãǯ“%G6 èòÝñx$Gò~´3¹™8“Ÿ9ò}±|ôôÒu&±:˜,דPOBåØŽN–éäkvô7)?ô­ïCþ¹| vÌ”²cßg…/uzþr~þˇÅtækß²?Γ=v`›?ÿÔv@v|Dzñ©ç?Ȭ•ãXÞ燴~\\¼;_™çï?ˆ íÙ¯÷ -O=e´êÈ~·j‘ªÔ©?ÈLZ£µÎÞÏÏ.ŒÉWsá·]#Äø~Péœ*Cò† !·=|ÎÅÙÕ¯oææœpf#'¶_'¥…äF-TØm¨pÌМþ>¹ïÝ8¶Ý0Õ«ÖÎg¾Ð¼4Ì<_çEÖ˜ÆZ¸Öu–¡¬§—Q/ø_‡{©+*Þ)Oö% -d@¬º`jUó»Ò*/4ÁÊ£\8äu|a;îã&WyGœb¯b´ì¦Œ1æ¹õö@^®â«V•ê¯YÍ" ±Ú·R¤a+y ˆ+Ÿm©9›Œ~…UªqEÚ0Om¹|ÂÊu‘”Ÿ™¼çÐÉ žÊ/¼¹¦7TuHÆ$’Ê춸ô¾­cÛQ1`ç°³üVF¦ùòÑßvíQ» -endstream -endobj -1463 0 obj << -/Type /Page -/Contents 1464 0 R -/Resources 1462 0 R -/MediaBox [0 0 612 792] -/Parent 1445 0 R ->> endobj -1465 0 obj << -/D [1463 0 R /XYZ 72 720 null] ->> endobj -542 0 obj << -/D [1463 0 R /XYZ 72 582.756 null] ->> endobj -546 0 obj << -/D [1463 0 R /XYZ 72 199.398 null] ->> endobj -550 0 obj << -/D [1463 0 R /XYZ 72 130.835 null] ->> endobj -1462 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1468 0 obj << -/Length 1974 -/Filter /FlateDecode ->> -stream -xÚXK“Û¸¾ûWÈ9$T•ÅáS÷&ïŒSNyÊ®ŒrÙÝ0$4B™$‚òìüûô $¥h²[s@£Ñøú E‹§E´øû»H¾wïn>meX®“õb·_É¢ˆ£0J‹Å®^üT½Vƒ®—«d¿Eq¶ŒƒFóÐ8üFÁoqšÙ#Òîtý^}6Ã×?Þ~}`jêªÁØŽ9â\öGy´­*íÏ»AµG˜Œ?À¸ŒÛOçTuÿ爎 ÏNYO§Ü[Ò²6û—å¿wÿVq–yΗÇÕMX&%¯~úüåîv Û·ËMìîPTÔZ5¤w:ª“§®ÖVºXqP3ótËTn•_”xu®M ÝÔ²áÏ~aº¼qdº'ž0ÝÞö­ò×NÓÆ›oM;´=Ê¿‚…Ý/WišÀDÔàÏ?ÀÖ?P.JCô€"°Î™ÇFö(ÇÌ{Û4yŸÝOxØè‹8 ã¢X€:a”ÉÑ ÿÄóë*¢à3*G‚OT’ît Lè :Ë‹_p"áŠl½®l_ÀA˜A6¦Õ¼ÁÊQ­EÓÈÝá¿""QJ`Ç­F„ðãÀÃO§Ô0¿ÁßdÃÏhd À¤HÏ­Á_à²òŒe˜o$^“×±+K®œa4a—E‚]YŠ?"å½é²,^ d0+ñ:T2V³½l)èà×£ƒè +£Sž¡s¦Ôe¿ -{žçd•aBp&zòäè¼Ã“ -´·ÖýŸÀ<}ó¤HsüxÌ‘&Ì‘@Ìñë•BzT*ÙˆÚI‘JfÆ©Ju˜~¤ðÓÌ^ëA÷­é(Àâ¾·-SÚHümEEŠqš˜Ö -Wü±s½§ÆÕµ¸Ý6Í\.Biœ¿ñÑ7© CÈZr¶¤×ÓkÆéD8ÛNÀpºÑ•ŒrΟ°¯6îØ(Üø"¢g™ -‡³Ô([ÛD~>@eáyqükYÝ)Ï.R -LL©G -/•æy0è -!ònÚ{&ÍĘî©ì‹ñʶ²¯¹þt„Ú‰õ2)/[3ö­»-¼„<€ïÒÛÁ' Á /(Ò-(‘¢É¯ÜöÉøƒ¸¹ËFÊ[Ëõ-;{Ì“O¾ÓuúyšÕI„ wâþrSi > endobj -1469 0 obj << -/D [1467 0 R /XYZ 72 720 null] ->> endobj -1470 0 obj << -/D [1467 0 R /XYZ 72 652.987 null] ->> endobj -1471 0 obj << -/D [1467 0 R /XYZ 72 623.382 null] ->> endobj -1472 0 obj << -/D [1467 0 R /XYZ 72 589.903 null] ->> endobj -554 0 obj << -/D [1467 0 R /XYZ 72 496.426 null] ->> endobj -1466 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1478 0 obj << -/Length 2223 -/Filter /FlateDecode ->> -stream -xÚÉrãÆõ>_Á¹$PÕ¾8'E”Æ“e\#NR²C“h’(a¡»häü¼ßÖ ¨pâŠ/D÷Ûú-ý–f°Ø-‚Åû7|ÿºzsuW,J¿Ì¢l±Ú.òh‘‡ÄùbU-~òÞ¾}»úpû'yÞõE{«‹Ë¤(½ ö>¹÷dÇ–¡Ú˜ÞXX—g÷ýØT ïúýÅ%ðm6£aD5šºÛ1®ëM«†V Ö?>,?=¼c˜êDìNwÚ¨¦yaxÝUõF úâ_«¿}—aè—iÊ–( ÉcÏjS÷#j˜'Þ^™êíPF3º7Œ±ýv@Ä›xÓ¯/B¯mèµþÅe‘%ÞõvÐÂõs&€-È$€ {lûÑlD ™° ‰rÝ‚uiPz/xf?2ªU¸{aF£íÐ;U‘ûŒßˆXš’v¨:®·d(.F‚dÃN‡…®ÀµSÖ¿jÓ³m°éGŒiš‰QpD¬7ƒ®xoaÝ›Ÿƒ4°ð2ðd 9ªÚ>ÉùCÝÔŸzc´‹ÌëO9c³ÑuWµjê_I»8Ž î9á|<®~ø²Z>ø(ïê.Ì,0Â,ñqâçiÉâ?…€‡Qê}¾ýøé=pç©÷þ|ÖV¼\ò°zx±ƒnYò<»@n”úq³\‘e‘·á;¥ \‹ ¹¸À¸}E—"!‚à¦ßÕÿ¶’¯åà.gßs1É®jC|/&Oî Ñ—v£ºŽUˆ9ûN¤@öÄÉW÷ݹUóâ,D©ë±nÈ¢tæÙ ²X(¸`n#îfÅ+Å GBÀ]c×qÐa¯˜b­„ÔŠSçT¤‚Å—c`*H¿Q˜~q–{Ï{Ý1—8ÕíD~ð_9—±q­®j<r]§9˜×öÈÎv+Hïˉ*§ÂÃô•©™ÄÒñ\ᬄåhY`Td#ÂEoÆ {5gœÖAµœÃ—“ÐaÑ­kanÕá\øÈ¬8žIÅÅqJWb,ü2’ܹFE’Ò¥¬Ú£ ØqÊ×ZÈ蜤½k”D UßiôRO×Y,³l0šÞjº1(£¦$x­ñKùÀKºÄ¬XÓ8AvÔ̪:Q;µµµp¾n϶礲ÿ0°“H½ y¥yEÚÆŒBO¾‡ïØUráÊUT£ÉeBÖ(|Ðø†©ÚY®8à³Q˜²+–ì¢á®gOéÀé…Âô-¯øòÀbÓ·-; ëNÝQréÃÛ+‘ÚõüUf7¶¢µÅ¯ÉÑó‚S²OÖ1ÉyFŠ*U"¹+¤S~Þ(Îbªu3W S(~gû×é¯â[¸=P2 -@ç$I&ÇÍ©;Å7k¼›/Aæjh¾Cµ¦1Ë}¯îâàU;(ü¨ŒæA:Û4fT·_õf”Ä%œ #ªl•\ÂVÎ~;6ƒØP¿öÀ¶Çª€Ïä7Ì¡Q³twGÎ;+ÞÎöþãSùÿGèÉ(óChÂ'á¼i´â)I¿§Ú‰+n¸¸úȽ$qÉ?ÓÕ/ìÓÞžIo_-_5vj"°bb[wþ+hŒ ~ž~·Ï£äŠl¿TÝYÞpóL‹)u¸ª[B- ½Š×Ki ÏUWJPXÏpwQ$P@6|3UBIí³€Z&a¡'ÖÝû­ãÏ=÷=†É$Üþ¹´{Ä.À”ÐG'»²Â»ñ>âj¯Ž]‘!ªã/xf€ÞÄStÚ¯IäÔ,±ÐÉ1<²<»â‚«À:)h8³:н[GªYÈÆµD”þÄÈé0Ã{;¸ðöf°Ì¦£Å¸­àÝ9ïÐ-È2h»8ˆÙ²£hÉŒ5݈lšˆŽ¢°WQTY’‘÷OcÎ&V9+{e2‰E0éøŒ®ñ©Óˆ¥®<ðvz¢ú=©/åÔ—ôÿš!ÜãkŠk™\í„Ú:Å˜ŠŽ”™›©Áæ#´ i.H"§e£*}¶ RЧ‡ÓœKоÃδ Uw€P§Nq@„†4µà4º‰“…Aµˆœ¬›“}y`§¯ñˆß¶gÉ{mÀ$5á°ó‚÷J L.ö;|PŽ,!,„0,‹B¤p |=¨²ByîÝâàlÜ$AîÈsWé` -ĬQÔMl¹Ó6š‘¤@ -•/,ÏŠÏÇfOÕ5ϵ¥i¡(Üá™'/¦|Ê‘»Ùèu¨ž»YôB åA‚‹[±-çRö%aè-—þý½ÿøè3ÕŠê¯I§•Þ*è˜ø[¡:F;%Ä«¥óéþÝqs‡F¿ç=ÿK‹oþÎp$œùÆŸTñm\7øh˜OŒ³v͵õÝ•ÛoôÖ%–cyàq†ºsÇ ³[ðâóû7‹Ÿˆ(ñ‹“ö šü%½v“d`¥¡{5v>B%Tb- ìW;íåÖ½êqäçY6õ_?Ä ÷ø‹¼sð/‹å·»j2KfÈÈM©Ë]eOçý)ÿ ³t¿¹`÷½nŽ÷—QÓ¨4ôÇ >€UÇW<(_8YÕW&ÝôÇ1+\\,›}g™¾Òvcj)3Õì¸n¾0FüN„€'„1åU„ζà8cø3ù4®ÛCÃ6 ^›$<Öp„O3! Ï)Œ+–Žfö *nVˆ’º\J³Bä–üÖòf’áF¾î†}¤E½E¡ùd}Îj9 ž½ˆqªW­€±býÿãé·î ’„òºå¶I·COzŽôÿ"ÂOFè¨nFìš‹/cÄçr#*¦xÞ×üÓÀS[2oF¾ô @¬OÄ[ Z‰œ‘ýW ëôGÜÓ4P  vÊkl{ô¯ 2­g> endobj -1474 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [269.869 265.87 284.592 276.718] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8) >> ->> endobj -1475 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [523.506 207.74 538.229 218.588] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1479 0 obj << -/D [1477 0 R /XYZ 72 720 null] ->> endobj -558 0 obj << -/D [1477 0 R /XYZ 72 658.397 null] ->> endobj -562 0 obj << -/D [1477 0 R /XYZ 72 403.534 null] ->> endobj -566 0 obj << -/D [1477 0 R /XYZ 72 253.029 null] ->> endobj -1476 0 obj << -/Font << /F8 826 0 R /F16 823 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1482 0 obj << -/Length 1926 -/Filter /FlateDecode ->> -stream -xÚµXK“Û6 ¾çWx{‰œÄŠž¶•['M;ݦ;Ó¦™j%z͉.Iw³ýõ’]eÒI§{X‘ € ðt4»E³¯Düýj÷àéËõ¬‹e²œíö³U2[ÅQ¥«Ù®žýìb¾È¢8Ð÷z¾ˆ#ZšWM?_$렚ÿ÷Dk‘£DÂ=n,‹“ ’@vD0$; ¾épª¬Œüs>l±QÏ*¨™÷f$^À¾î“ó8èn‰Á8‹ª¿UeKÔ®l™¼ï0„ܱ¢8¨µƒhoÛ¯qšm¿˜ÿ¶û¶ˆã°Èsrͱé´Ïiš¥~†\Þµîûôe B’u˜§)ûw3_äIlqïùU\p¾›¯Ó ?Uñ2¸“Mƒ£ íˆ68&¥~oWÓÔôôÎÓL>0{]ÎË"áø¯=šs}À)õ±ñw<–±ïU[2¿d›îÒÈaBߥdgÿ„«ËªGƒ‡AOÿåÑÛ-޳ gï¿8©þHÊbw)ôT«Ï¹ õÞ‘éëòþ¡¦ GhÎõõÓÍæé»w¨ù™%GÁ‚–ß~újáÿ—a›Mx}Nf]Þú¤y+1Í– 1ÎDS£S³••ßöQ‡'H+@;…Ä*R@[ÙÕ´ùÞd©øv€Òº8Bi76ÍM辈«ïX»½kX4>{{Z¨å­4lFÒDég½–Fözöêü9Ïó l$É ¢¤`yú4–ñ4Ï%‡gGQ&ÿ!ˆµ?$„ëÞū͙œ‘ˆC -`Ì®yçÒ”RÅTåI‹ A.]qÓip¢Äbœ¼#ðÃUoYIŸNÜ‘,ç{§¡?þ:,’‚Žÿ#APZà^üŒ<€SNv0³,r—m÷ÁÔÃ’¨!j²%‹E;ØÆ£ã`B'¬Å…È¥:)Å’‰`d‹(·Z¦Œr^È¥:œyŒjÁ@ÓÕ‹Nš.c$ààÀ…‰?r”Jõ¤yWf] KoDÙa'[æzÞPÙ«°Â½ÇT‚ŒíY0ݹÝÙ”¶bRâ¥êOÄ#¯>Ýh#Íɰ`ºç„îæçuS#‹­w&N~žxä<ÆX8áØ#—±~pöêÕ³ëëgÛ-cØ2<†‘ëp´ó[ÀuÕ{g~’†EüqEŠ8©öñOðÇ:Ó8éïyG¹ŸQ²/ˆ”š¾¥Ö§ÖF/LlΊ-gGß$£ï¡?)ùZ›á…@ttD,‰üƒ£AÿóËÎmdç—P0c3rµ&Gž­¨ú®æ ÂG»§ ²o¥TµÐ[0b¤ÙšCÊ…2áP.;L¤IM_¶+ÍÇ@ùýñC´È~Ò†êÑQ ,Z.´ù4azOßQ»‚Ó!3}8ç¶ íÇ1‘@χ촙–N¢=dGçXþ¸€?ŸiœäpåœûQpNÓ¤¦iŽàET®.ø‘4 ¾ÞI*@9•†%T¥dyËÜJ˜“êžLè°)ˆÌ†VGå(¡·5£§ïÑ×@­Yiçëç2 ¦–KÑ"ËãàKwö,6>Rª÷« §‚lžL‚™­y•‘“n'óJh-ÚqŽÐŸg˜ˆ9–ß’×õAîY¥ - *.àªo¨ëA"WØL/¢<lù¯£% ±MÏÜâ--‹ú¤ )ísfÜišßãÄVN4¯ÿH;}RP”›{Š'}ßÙ:sPküë¼½È|x¤>Rḭ̂ ß_4#íèÖ2¯™X¸ ð¬z2n‡çN´¡L´vïÈ•{£9¤pÅ’)‘p•ÙVkmKW“ïdÇ»‡gßÊA(¥(¡àXÑnxU®ý«rå^•+~U²’›‘ÙÞ n‡"‚Ô‰ë騥ºž€›–,ã§ÒHŽZÔIh³!Á`"»³n‚˾¦•Ï°Êø– ¥‘Y%ü²rϪJþeäýE3bƒ¡ö"³ævfó7{nxØ$¡”Û.';êÞÕ•!Œ‡ÁW² ˆ=hÁxi¸ñ‘'§~K@Ž–R§f>z–ø¾Y_ôçµWÏ8Ä­{UÖBWJ²Ó™«¤iO/×d‡Ô$ Bš„ëhMGÎÂe˜/vö¼ÿ/ØOë,¸,ÌÕÓF¦K×Oñž"ZR»ÏRè|Å’49— hÙÓ‘Ç«m¯E jÑìâ<$ºÒôî]mY¼´IËÚ«¦TÒ`|K†ÏÁ,†FÅýöñDþQ¼WxÏúI-ˆ°)Ålb2Y Ûág´Û×oÞ¼»¢îçíæõ–†=wˆ?oÛñb÷àocoj! -endstream -endobj -1481 0 obj << -/Type /Page -/Contents 1482 0 R -/Resources 1480 0 R -/MediaBox [0 0 612 792] -/Parent 1473 0 R ->> endobj -1483 0 obj << -/D [1481 0 R /XYZ 72 720 null] ->> endobj -570 0 obj << -/D [1481 0 R /XYZ 72 253.752 null] ->> endobj -1480 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1486 0 obj << -/Length 1807 -/Filter /FlateDecode ->> -stream -xÚ­WÝsÛ6 ï_áîer/V$ê{o]>ºôÖ6W»×[Ö=Ðc몌’šåúÏ @Gr•kï¶› H ~y‹ÝÂ[¼zæñøëæÙéeºÈÜ,ñbs»HÄ"ñ=× ’ŦXüéü±L§–« œ^—ª`²¥Q+ÉIC¾\ùN«"þ>ÿ~_Â4uö4-pGꨎ¦MÛ¡þ)»Þ]®¢ t®š®—U5:ùœè²g©ë‹Í‡ë›õ†4ÖXýÀœ,–¾Ù—¬\iÝêå_›×à’•ï»YÑååÖÙêw|k÷ -‰Ð9këšÔ÷ZÓ¥rÕu­vQâÁÑv<½ ¼‘»A¡HÝ4óIá‹/À89gU›&²hÑIH½}·!b=ÜÝQ<¹Ø<þ•M‘´¢‰Þ“SÁLƒÆgâºü‚S¥q€7Ä@f;h>ÙÖwC¯xv_h€"ð€¸#Lu]ö“ó41΃±S=iÔ|G1]ÖÊÊ5hµ9w™ ¨€"¨ 9g$Á™óÿ‚JŒ ò½Ès.È&C— ç²—„ÏUNû.°Ïâƒ*(>Ð|9t,ç l®Ì5À>¸!G"åWM0jš=3§— ¬‰@”]7° Iœ; 1Ü……PÂVÊê§•¼ÕZå=-ãÕOé²ÿ!¡ß çëVѨŠH´Gãw$rLÿç?4ž#û^ѵü Ox˜ÔÒ¸ö¶c KŒ­÷mA&a;ðÎd©Ñ”cÆØ=çCÇnÖgïÞ^^½bÁMxˆøã žJÝ¢æ‡^P¼Ìã¢ìä¶bÌKçäZ§˜¹ÌJSº`ºp8tSØá{#¦ApS –ùÚ|·pœ^úñ‚, RŠã€ìÝj‚¨Þœ½ü¤$‘ó•†ó²»«ä2ðb¼ëapúÈ ¬T’%‚ÌÁ;‰Ðx§]mžLä@°ï´¬‰¯Kˆ’†Ï4´ã&õˆ!»NQ©0 UÉf7ÈâãæùNðùÆ©­ô·­®;Áúñý/뻊j;jÙb ášÍlßÑKsg\…Úp;T´ávh „'sÐï%gn{Ký=” ‡ZêÖ --QË=µÇÌg¿˜ãZÕ-¥üž6å²RM!õÏ|—k¥F¡óTbÛp²*$\›—ÈÄÀàô3oƒ„‚§à—)#"v}ˆ¦i¶_¿¿̳ž?KÓ9­‡†ëMËÄfàzóË£áì".uÉ-„4qäzq2é^Ħ0[àuËÜ48ÚðžÇˆÇ˜Ç„Ç”ÇlÎvßã·Ó÷-!,X"´Dd‰x"+fY‰]N-‘1!¬aÕ«Fsv «SX"¶„U#¬aÕå°'1>ZˆìP \4ۤRܦ9O—p\á;­MIx®Ìc,L–ã’‚bNmp>ùA(Èš¾­1e_æ?±M#n‚‡Y5ÈŠÇ1L¿²†ž¦¹lˆÁ=Mr*œÔsLÍ 7Â?d+s÷,>à¦Cä(yîcJ’UEUÆäãQjʼnQü˜ÀöÖKs˜OzÛ^í kœ[š‘z-©“šúIÛJ¢ÛaÇ'ÎUŽÅ6µmŒ¦Ý"Ì2w&h< -—d-‡xaüÈᇚ¤c罂ʨU ¦àÕîÛ0ò³ØM½dÛþk%2^*¨lc…Žoü…+@.…ì1P†1‚7ÊpÁ3þ„¨Æ'Þ³v›Æe]ÏÕ…íšÀ}èöDãsQ 0Ahi"ÉX½YŸ¿[o”&§p¹c'á:}g %iñ¸Â%öCÅ -Jú&U>"v.8¨qMÒø$®Vô=ƒSèÛ jÆ5sŽÍ¸MEIy¡U%G}1,tímOñk›´ù¦“ÿÜhÃcß ô$7ðeäÉ“Ç<æíg™"ðHkóÛwήOß°@h¸Áxè+NèÀôF ìL¤s ¤ºJ-Ø2ôö©nèƒsôØul“¨œIÙiTRCÙØD¥GõtÔòÓR7\¯¯àicÛÎ…qlúäW^%í¾~B$u´q_îöüŒ±&Nq‡ìhµPŸ> endobj -1487 0 obj << -/D [1485 0 R /XYZ 72 720 null] ->> endobj -574 0 obj << -/D [1485 0 R /XYZ 72 472.435 null] ->> endobj -578 0 obj << -/D [1485 0 R /XYZ 72 302.123 null] ->> endobj -582 0 obj << -/D [1485 0 R /XYZ 72 229.997 null] ->> endobj -1484 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F16 823 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1491 0 obj << -/Length 2560 -/Filter /FlateDecode ->> -stream -xÚ­ÛnÛ8ö=_aìËÈ@¬’Ô}^iÒ[Ì´Ý&Åì´3Š%ÇÂÈ’«K[ï×ï¹I¢l§³ú`ˆ<$ÏçJ«ÅÃB-^](ù>¿»xöÒÄ‹ÄMB.î6‹È,"­\åE‹»lñÉñÝÈÕ®Y®´”óñúê—åÊ×ʹ=TKÏ8]úmùçÝëg/mÚx®g" @(î¶ùrå‘ÓÂÓšoê†ŒÖ B§hò7æÍA»}™»ËU ç_V5Ù§MºË; ¡f©Á6Bõ¡`dÕ%ÌCo$9Y“âÊ×EX¬¶AT7 f¾#æ=ÏY÷M“3ÿð]ͳ-¯ÃŒÀãvÝäL&Ûâa[ÂNÕÃÑÞäÌEÎA°oø+'N¨÷U–7<üxýî½K)%v“°(¨8Å€>‘¡›º,kRi+cè=N³sd+Ož‘šqÕV³‰Q3n!5G¨fš’x¢ÝãN'_(í3E‹-¸nß„l=¸ýˆß]j±vç˜a[èæPnFÅXw ‚yF;„¾ß!¯‚5jŒ³iêoÑüéj^ІçdÇðERï¶põó¥]Mö‹i¹ßâíÞ³ô]±føÉoÁ˜×]Þ´|ª¨øÛïEWÕ8öÉÒ™Ðz‹ï+çå2öF&òo):Ú¤ñ«}S”çô1ª mT-NèÊh„ÆkC«#Ñá+Z¦Ý¾?FïÞ‹=Ëâá¬µÞ ¾q éR:`ˆ7ñ -㈠-yB×ѵãô”!CN4*­¶¹×7u߬²â¡è|Æ0H»>Ç¢sét+X‘¤oóìræÇæØó!ȬoÄõ‹ö¬Í¶m¿Ë3â#À[öàÚ"ÎúYe5¢—Ù%§e+Œ[*e†%RÉrQeÅ:íd=­,ö=xÅ€Îøb Ž˜8m™¶Û¼åå?T  #ͰtØiE"ÝòwnŒÉÝö’á’a`”í¾dE Thoë¦ãá6/÷¼¶ËÛ6}ÈÝÙ}‡,öuÍ—XT’=0Ð#Ý«_~’¤‡þigXØÒôeN\ÙÉfŠô#*1Qˆ­u|ÈÆgÓ²KZ×»ÜXû32zñâîâó…~ÕBcùÄFÃx±Þ]|úS-2€ƒ4®—Ä‹¯´k·Ð¡q5ÌÕ¢\Ü^üûè|õ†ö¿wv²+ðñ3ULä&Q ¨|7õ·c+óƒØyŸ·}Ù²o<Ÿ{:'"¨ïÿ¾ -‚ØÃ§jàœ€Šï‹ ±Y‰ŠÇ¨ QgJ®ëä©LÍEòC7QÁ)P®Ÿh[&”àŸX*op'*À†’ä}\¶'s7Ð$?D6/v/<–íu_‰¨8ŒŽ $—è ‹öTÞæ’ã&‰ÿ#D3¡Ä'צY.% -S«¯×)fŸâͰ|äÄ=ËùdNç‚Â’ò’!¨ö]‚Ì}ùâ¹\¡2 ª6JqÚÎïÕ”v<.è“9=T¹ñ“BÓ© fá'†…|SA·M¥ðøºò}jE˜hlX -I1ÇMÀ¥]>ÔÃî£Ãc¹`×þTh5ùç¾h°:¢Þt– ¯zÆ­övÞÜzp/š†Ê¸_9'·§]. 2d:ïø¦wvãõ­]ÝÕƒ#×ç+G0¡ˆÚ´Pȉ¢³5èCë—Þ—äìJ-ÿ–¯ûN€û¦–ʽ)”¶$1Á¼¶Â"ÈŽŸØÀR9Äýñ™ï–T'QÞCõPp“=ØVpRI̺XÿLʶ0©SŒ К¹H;$¶`×nÈ\5+ÀÇb†WË¢’ò뜰oDµk`Í“:¶¿þ_Öû¸R¯°s •“v]¾Ûw8ÑŒ—zYXÙ¥YÎ#¼n\Nû®Þ¥ÐL¦eyà%«ø”½ÔJÃæYÓAø¬Þ¦_1_`Sݶî…þÇÛ›··¼ŒöIÛŠq]Ñë|(ç’~"ÔO„úa -¤² -ÒsíLQµp>º¬%„™Ág¡’ Íà´1º¬ ÀéÞ¼\zÚyŠgÅŸëºÂ`òÐ7©´üÐ%¸´\‡Ç}Ùg¿m‹Í#ÒNÅ #òØH‹åD£FpþõNÐò Ýhp:@N£Tòý»Ûß^¼x'­¬HÄâ‰(cd^ÝÔ¦¶@g†‘2V;ÓûÁ꜆Á? è”Ö->«’¿»±‡Ã™ˆä[$\X£8ûCܳî[°ºâ¿T_e +d#{zSÔ½ `&‡h¡í‹Tâ¼­Ö9/’×=O¶d´ÜÍ3R×"A"OìžÖ¾#ïŒ÷÷ðùŠ×Kê³ãÂÔ㮢ÝòˆBj4¾ÐT¹À·y!˜³|“bGA“z7'Ä9¶À Í;|ùkç8ÁgÉM„”°#X«<Ï,4gÍ7ê@¨Sß Ù%É+PÅb*r>®n-Ÿúl¡˜FŠ4¦0 -l_ŠŒRNež¶cÝ¢1_ñsÃ*k¬ «°±MIp„¼Q°2‹ü 6¡çìu[ H¡V££Åñp±8¡N]¹×o7б‹×>w¯° ×ÌDx«€¯'ÑïÉÍã˜B¯Žú;:•®!SìÓª ØÇSlí§Ì´dYë㔇6Ï!«¾|k0héyGÕ8ºÇ˜‹ƒë`ÚÏØ s¾<>êà ±ôšeü‡Ë°Ûš¿ì)0°^ -“d¾>±š#’ˆàÌe^¿}÷;ÞÔ¼rA‰$Qòfê;U[˜ŒÀÕR¶}hù#ö$¸»¿‹ðÖ-ûÑüŸ ? -‡lÎÖàƒ;;ðĴɼæ¼9<<Òã>y>.¶=T DÇŒRdømNI’ˆU>çÍÂï_],>ÑF톴aø·ø¾Ä.W‚ -âlr1½ºÊVk^–CbùlJ`9¼H µ Œ8vñ¸…¤”Sˆ¦• §'½Z¶á;çoØø‡M ØÀ¢jÕãÙ.QLì‰UGTé_ ŒSD€a1 K•‚RDËP ¹ûà^ž“ûãnØMâq•çfˆ$— ·,§Óß 0> endobj -1488 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [400.974 156.725 415.697 167.573] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1492 0 obj << -/D [1490 0 R /XYZ 72 720 null] ->> endobj -586 0 obj << -/D [1490 0 R /XYZ 72 720 null] ->> endobj -590 0 obj << -/D [1490 0 R /XYZ 72 479.874 null] ->> endobj -594 0 obj << -/D [1490 0 R /XYZ 72 335.907 null] ->> endobj -598 0 obj << -/D [1490 0 R /XYZ 72 203.951 null] ->> endobj -1489 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1495 0 obj << -/Length 1733 -/Filter /FlateDecode ->> -stream -xÚWmsÚFþž_ÁäC+fŒ¬7@dÚflc·68…Äqœ¤s–¸‰¨t²ÍL|woOo 'á‹îövŸ}¹—}°:«ŽÕyóÂzæ{ºxq%YÊT=ÒLÜkH·ïûÆ KëÃØ8)úNd<‚ój–«3³ -¾4¬lè´åZ¯LtîÕŽÑÂ6åYìYGOI*K!ñY#d¤œI&s-´Œò ‡=Ì»Úp®Ò´Ü¡ƒG,êdµÜÚ9SÖëÂÄp\ª1|-ƒEwÌ$§é2D=Ò«±V¯ÝugAJÁ8ä[¨Ì`BáÁ ædˆq‚W*lšçyƤë{´Ç°ÎŸíoÿ%jÉMmœ[TÂõŒOÇ$ ^&鎦‘È$m(僑úº¡‚*½K[Š›?4$UÊ5Xö -}¼è{ϹmyæÀî=Á>ßgI¼գТ™>VêŠz¶é{.»æÈ¶Éøä³ÕÇÊ‚{O/ÐŽ,§IÜ›ßÎ%ßÐ[BÖVŸÓ:Bÿ*I?¬ƒýÐûÐ¥È4NG»º¡ -^‡Kˆã÷Þ±”³6o[Xx*EÀ¢Ê2þoÎ〷!NjˆÓ„ô'Iº™ð"*¦½ðX ð8á÷:±,"VÑhüúîÌkøó$ÕX÷º “2ÆiÙ©qâh±Ûò&ANk*Ò¾¹X¼¥Ñî¦.óußÍÅø\×%b«¶JÜü`ó^^²Bx•„b)xø²òw¼›öC±hÅE›¹„‹\X•B‰[¡ÆÏõZÆÅa8ÏÓdË™ž¡5›WWæí­iyôokè'Ñ#ÛiÄmUã[ÎÒâr¬ðqFg`Ú}§±E5’v1/N./O³©¾ä³éâïÙ%ÝhߣA3ÍG_ïHõw]ö k¬Y¼*RýEÌBѵaßøºÀDžiÛw¹ê&8Œ“ °Ã¶b½nqþõ.ª{Åã¼ù>•¸È”þÐuÔ¶Sþ$+Ã#½ø[Séš·Hr]TË9vó.Ý¥X)$"à¯YV¯4¬½¯gk–²î*R(ºé:Q}2¦)Þpüªþ€j¦‰”ɆŠO9N¥Q´3W„Ì)û0­ä>" -:Ñ@÷RÕPÙ%©Ö1ð²MÁú…éòýÈJÊÑÖæÊ€vDÍÒSŽç}R‡Fu¾ -B®ë&®’(ϸœ)Nð »b­‡êvíôJû%^£û»5¦bú?M¾ò læ’o圦?âÞpŒ¼AÁ½ªœ.wH'Åᨲⶴ}¸º¤ïÁŸ–'l‘  Ùµè|3Z{õ¯vë¨É6EÔxjŽ{uü‘ñÐíSžæŒ€Hå­ÆU–Ñ7LŃþ#€JŠ©Ôô÷ç™Î/¸¨tð€çŒc¹¥aűœ‘XTÁêà÷lv}K^Ù(“öÀÒ¬ˆð§xQÛµý§ù#G4iO«ífhŠ„¦'i°Åkz*d (Ó$jö÷¹þ H@ÑüÏ’íN?²ÓY›¯óÊ×ù´;E<¨ó²©.÷{^ÁöÆhQeôr{>ossQ¹¹ˆ³m褢X§|©^˜*ìþ7lûªÂ»Ê#)¶Edp±¾Õ1l×>Ì}Ð ;ªx»¬ä‹µ˜ÎŸ‚(ñU„;ýl0*àtb©»üɲ¤[‹z“æ™"+œ1_2È«¥ÊJׇÿ¸–eœZß!ÊT–òŸCEßloˆ¶'g½¿núækäXpÈG~Iç¶ï5,Î/þðvà -endstream -endobj -1494 0 obj << -/Type /Page -/Contents 1495 0 R -/Resources 1493 0 R -/MediaBox [0 0 612 792] -/Parent 1473 0 R ->> endobj -1496 0 obj << -/D [1494 0 R /XYZ 72 720 null] ->> endobj -602 0 obj << -/D [1494 0 R /XYZ 72 656.206 null] ->> endobj -606 0 obj << -/D [1494 0 R /XYZ 72 266.508 null] ->> endobj -1493 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1501 0 obj << -/Length 2366 -/Filter /FlateDecode ->> -stream -xÚ¥koÛFò»…Ò -°¾EwW8vìúÚŽ¥à'-°WÒ¢|¨\*¶ûñ)ÉfÐæâæììì¼v^+o´y£‹#O¾oæG¯ÏCo”¹Y$£ùr”nø£©ï¹^8ÍóÑ'ÇûìÅþx±óöqQlsóêÜÚºã‰OcçÕ«»¿ñ¯óÿ€È‰ï»Y3_Ç×ýË?aù‰Ùýú–Á7±`~/ƒèÿf0ƒø{5H¾—Áô›$S7ËâÑ$ÝÌg&w§WçÌäòj6?y÷îd~y}ŘÓë«ùíõ;:;IS8”ªðËñoŸ˜ô_ü™©/š¡ÅZU+myñþè_L;ž„ ÈÿÆ“ ÔûãßNåìû­i¬ê&xçCWñúøÇ%Þ>n -e*^ü¬«-C×›ÖÔ•Ý)ú±çü"Öƒ¯œ½Òíîà±lþóè¦Ñ_L½µ¤LàQ*î;õ¿k³XwÔf¡) ^Ÿ§{<éÏ¥nš|ð”޼Ôiׯ -4RçiÞJ¨©S/ykQWŸ=?Zm…†®Q8Ö”›B3ÅõÕëëósaT¯V…®ªŠe]5ŠxÀX0{OB…”?ßÎDzÈ«kþÚVµ[a[jkÕJ‹&ªÊ‡ÂÖêB/ZS­à2âVáš.Ša2ç‰aðú8˜:º±hZËRÎ6üEõð+*A]JÂ̹\2ö ¬·"‚m*” òêå3)5@;ŽöxÈBÌ)€yåyΦ©ËMkyÑKÆÅµE@å¹A~ªàµ©`«ì®5Ž|'7‚šî…\‡T \ö‚lä j> /Råè„,Š“Žú¢ -.-þB×/²ÐÞ³D\£-\œÍBGµü%!pO‘Z·m]"" 'PØE£uÅðJW¢WvÖºØ0„~Á¯~4-³ŸB:_qóÁ´k‘Ñì0õVT²ä­/ä­*ý ºÅ8´CÆJÆÁ%T ,€-Da:.gr°ŸÊp4 ÜTÚp䦮-–—«­ §àŒèéŠêÍÇ—åÀ}7˜FÀ‹˜Ì)äÊÿ)'g͈\/Õ¶hyùOI™cלÉÑà$ßÑ +¹ò̘K -ÒƶBÑj7BàŠF¦x€âF‘À; u[p¢O:#M½­rÝpÍ4ëO‚†ò] Òj(à9Ãê ÔP¶}‡ -jòÌF¤ìmÄÅ¢.˺*žxµµZØ`S1x¯ò^\[‹>Pò‘-ëÏ©å¨U«F•¿­Y ¾X›åÓP†˜Ä’ÞGÄ=Ô«ßbÁ<ÁUŸaG™DBõm夨P6†îË+ -B@`ßÇW¼âØ`ۚ´Ý=ƒˆ-¸}óa~6c¯qo.†®¯DK¶ˆaäpÔ¼`/‡aHÞÁïCcZÙäN¸gÁ¾Œ:Ʋ*á.švƒÛ»ˆîåEäZ)C0±ÚAW‡ ú$AWˆ2,B0„ÜÝŒ³È9CÍ›ÿ„U(v&ü™é–»ÙÙõŒÁ›q@a_¿,R ˆÝ0 ¥ÏÝ`E<C2[/rplÁ/X á3B®Ïë|ÀÝéÍmˆ`øìîÑq{ÎuƒQ½2Ð#i:¾ÅV‚‹nfAøÖt½J¤ŸÖU…Æ4b¡„®åŠR5¥% Å_Õ@+£@Œ‚ÍÎ(ÀͺdV @’ßDtƒ‡ÁÃǸŒÈÑžµ@ÚÙgœ­*5£j£îÑà3Î@Ò,J÷&Lw¥€»äú©š03Óª•ºS}aÙ2ƒÝE±«ÁåòÞpš`?·Œâd¤Ë1ÃWµäÕÝ+ˆ9´×T`¹V¡’u… êìÒ$ö¬–ìݾ ëëŽ|°Ï5«·G£OtÐw#"èÚ`:>ªvÏ-xóûdfª•n¹6Û†ó¹¶‚áá<|~§¸Å#} U5pò§J•fÁñŒgTÑrÇûd[]йJ3 Ö9…v·ªöŠ/2*kºŠ\–`(ˆ<åØyBüÀË J&'þž¼Ãc‘X.ˆ@DÉ”t! ˆå<`JN€ -PZîÃ!I~«T]\ÁÑݰ;šê± ò¼“gDžâÏlN.¿%Ÿ¸aUeIR†câÑÞü|9߯·gÆË\_&¼¶Ÿ °ÎÆXggþ­Õ3˜z{¯1ËžY°OÜÕ#¯z1gx‹a¢ØMó23Ñ“—7eìÃ$Eàô!nÎô_¤ ùnò,]DÑĈ$ŽÇ8† Õ²Õ•g„u·<›ãÁVNVXä.iàø»w*Àü £1)ØW(aSeðå‡ýû Ýã“JJÀ@<4¤A\ÍW‹”1w"ð.A±ò¶/ä÷` -Qm¯} Y -O+¯c?îÛ‰ŸHžø»V &(MVð¶=…a°§éŸÐD´—»ûŒ8O¸ßš¢¡ÿ‰žaDÙÁ³ <çm3üÊ“Fç*ç. ÙJ¬yòD?•¼iôBçlxH¯µ²o" Gê¾’ñªPVj?71y•þÍÌís6‘„ÅÎëûò+ç»×îË[:uS$¶·/bz×¢‚)T¼B—âC uS–`/dH!i¡–}y/3,óÀœG˜ê'îRPñËK´yöK Nõ~ÌH8E^F¡CýjÀ’wéÁ…7 œ iGɨ8>b¦¡LH×èV™JPì§¹ß-YÓkl;-|Ï9¬ˆ9˜0A¥/ÅÒ7øc‹ê -9>òüÙ(n¹Ô6øÜàŽëƒŠÜÕ¡QÊO -âÄ™† ·B"³üeïz{UZìai#Ñ3‰Y»ì$•öUšÅ†J_²Wú’®V%ô¤ìÆEŸö¼¤ù~–Ã<ÄÈ2¢ã²– EX-ƒÀ¹æº¾ÎÓòZWêž~l†ŠQŸý0z¿5ºýá°UAæz~É»‘—²mi|@ôv~ô'‹ôcˆ -endstream -endobj -1500 0 obj << -/Type /Page -/Contents 1501 0 R -/Resources 1499 0 R -/MediaBox [0 0 612 792] -/Parent 1503 0 R -/Annots [ 1497 0 R 1498 0 R ] ->> endobj -1497 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [503.134 309.595 517.857 321.55] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.4) >> ->> endobj -1498 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [365.617 209.076 380.34 219.924] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1502 0 obj << -/D [1500 0 R /XYZ 72 720 null] ->> endobj -610 0 obj << -/D [1500 0 R /XYZ 72 462.03 null] ->> endobj -614 0 obj << -/D [1500 0 R /XYZ 72 381.34 null] ->> endobj -618 0 obj << -/D [1500 0 R /XYZ 72 256.302 null] ->> endobj -622 0 obj << -/D [1500 0 R /XYZ 72 160.266 null] ->> endobj -1499 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1506 0 obj << -/Length 1538 -/Filter /FlateDecode ->> -stream -xÚ­XYoÛF~ׯ ?@ÄìÁÓ@ ÈGÚmlGÊKŽZZÙ(’%¥(ê¯ïÌÎ.MÊŠ%ygvg–óíœsîæü1bæy6½z8©ŸF"rfK'NÌ™ÏdìÌÎGwUyc‘¸ õÒKºY¹@‚»Ês÷«ÇݺÈçùºØá²p[µ¦ýõ½"âÃùõ;Id­ï}oÈØÙíyµª µV¤^Ày‹G›cªe'¶êÞ]gM¶¦%¾Qóê®ÌÿSfÿÖ±»3¯¿ö’Àx‰tgzŸgî1ç~†„0oOqyt9ý;â°ËŽ×%p+\:óÕèãgæ,`t}™&ÎVK­&¾€,œéèfO=Žý8LžRI²ƒÔµ/ÄÀ±ŸÆ XÂ}s¯=)\‹.J0æþ£²2/ïÃ’¡ÇÛ2„…~Âä±P!‰RP# çÞ8ŒÃØêˆ‘ÒDŒ ºˆµ©Êš¹xOü5zVGÑ7±mìk(ý$H~Ö0öi¼v`!} ØÀ‚•î‡éÅÕ”È7%"·–YARà'ÏÀ?Úþ!ü€ûIúK\„~_ß |ÆÝ«ZWÕdk?/ iFì'.ƒ›M®Ö/ˆïÊ– t/*Z/+4u“Ó­}ûFކ4¼ÐäO„ŠØ‰¤„g`ó˜\I0¾x!ÔÖb£Zâ³¥În¼¨¨kLn›#«'œ´­ Æžß_ñµˆ~ò}”"”®*ÔJ‘»ZZÉEÄB}b<(±‚‹ -œÝ§ÇE“A5#ü7\‰j #‰(µ"ï[¼0Ô}»Ya•¸.v;±[H•5åà‰æÝåbx¤¤#sFwdeH¨5Á=Ï!}û&¢» D†Ò='߆ÜÝÞç]z‡Ì]eÈìhÏØO̦ս dtÂÀ³.²¹ÙÔ=–TáÑMõ6(6p²MkE*óìnÆH´ù]‰mx¹£° ±™gëÁ¹ÌošÆø²Ø‹êîNO‹C-¶~èW2àn{_m -„ˆJ`%&z”˜ùÖjÊPëEm-+sàÚ -£Qž™M${—@b4HÜ^P[ k–>±Qp¾"Ö8ž˜FÕjÑ’ŠõAÀYûPÎNN^èŒÝëí !…ŸD¦~ês_€á.†–4‚¡~`h˘»—_3”Z:jX^Ÿ¥)œ¨Oš´ífEž‚ }»!FgÚ] ¢+º¨Š¸^^ {þ’ž” -Rp:ƒëz œ ím®$­‹®…Ù+tÀåÜ–1z!YѨlñŸf’B›Ͼi8Ò½¤§1 (Ö—·ó,œ?„jÿ¤˜rîø‘Æ…Þ‹{ë[bt”«lÃ6/¶/\VEQáÖ–üÐÑ¡ÊÅM7 -˜¨—FQ -²½ìÐà -M‹¨hgOáÌ(lta{_¯^K6 S‘@˜šzþáz‚ŠÐ}uñÛ߉ô–VSXMÁ'8ŒëS¶yQ)OT<+™°rk+!È-º‚¨"ÓÓ½wŸ±Ÿ‡~”òƒ 8ƒLûÂ}F>«‡1 ¸ R«,áKÀ(IÚ8’×8ù:Ç»×õ:Ý­n+øH"éSzL˜!Æã߉899=ïá¢ø ÅsqPñ-”\ld>ŒÊÙdz¹¯ý¶*AðôyÀ4§þ8`î¿úŒâïÖ<ùÝÕÕl_› < -Øñ VLØ^Úž -1©û¬žÝ©Ç ½Ÿê fÃr|®¿nóö~ð…£jEÖyUögaI³pðíYøô'÷æ¸Ì….û+ …±áG -†)1–‰––êÌy[4Bg Yì~ÜüçJÄ“fh?c&дì¶@Ÿ3@P¹ëU|`ôTӳ͔Ñ4„…œ¥0ŸÑî¦%°VPo'0ÅAäíh½ß§úŸwªsU¯s0C#šÔè‰ü+qK -‚ý„ëz¡Ú¼ÑÜyÝ}Ö˜¹@° T y㿬xÇð Â8ÌðL’„^“D!øôù[{Á -endstream -endobj -1505 0 obj << -/Type /Page -/Contents 1506 0 R -/Resources 1504 0 R -/MediaBox [0 0 612 792] -/Parent 1503 0 R ->> endobj -1507 0 obj << -/D [1505 0 R /XYZ 72 720 null] ->> endobj -626 0 obj << -/D [1505 0 R /XYZ 72 564.296 null] ->> endobj -1504 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1510 0 obj << -/Length 1038 -/Filter /FlateDecode ->> -stream -xÚ¥VYoã6~ϯÐÃ>H@ÅP§¥-àÛîMƒÆ‹ÒímÑ1Q®(¯íßåÈGv½é‹Dçžo†äγÃ_/ø+ÿëÉÅåûˆ;9ËÓ0u&sg:£€3œIáüå>=Œ'¿y~&îåíÏÞß“—ï³?wü0cašôì^¹c/‹]‹¢Øí²ÆUä¶R/=`w›ºÐDZ«nJ<;p«7“îyð„»_ÆÉÁ/°}z¼ýãj5bË’ò‰íéæáψ–¢[0Æ o°8ý `ybÃyÜVÓ¦T3⾢ߘۅïÿB‹wï®zsCéÛOd:ú†àM¸/hû•, Sç½ìõøñîPú¾©‘4ø½û'âÅ”Ç,‹£}­Ä½*­©ã‚û½Ü°æTέŽÜfEÑJZÜ7Àª®UýL¸°e0œuA‹™èXȪù‡HZèNt+M²Íüà°s±*;:5á"u áÒjŠŠ·t¬Uµ,·DhÂA'[tëp˜ qøjS¤¯6…m…Ñ®bÓ -Woöáü^8«¢”¥AxM-èpüž÷läýP§ÙWçuu ,ÜCuïS²Q’‚˜å,„ÌY¨ažB ácjµ¼kÛ¦Åe`X|öò€oQ„ߥÖâYêÓ IX”FdìS]H«m&ÛN¨š¬Ì!ªSM­˜G4ň¦Èz¹•À†ÙÒFi½’$+_<ìÿªž7m%P¡(‰«².2Èx?1=…ZÝõ>TUS[çÄJ[õÐ…'ªÓå!j†ô¹”CQæ £ý€ÙÌwM {[È™úƒx&vY๫W4+ˆS¨U¦­¿z £TKÙu&Åܦh†oUáwJÆZk ç T-;*(HvuNv;›'²pìAÆ)´ÀÅDg‰ûá°|W -Ú=ËZ¶¢4³ -¶zÑ`™×´£Ñ‡d˜‹viÆ"üÅ‹9šp˜.<· -¥Å´”Ö;‚wë¦öåFéÎGv*¾I?yKȬ¤!V*mg½ÒWo¸Ø¯EAz·YÂŒÔ -a‡{Ñѳùîdìù1pRÀ¢³Î5Ž3(Ú¿+YÏ$q`ºŽ8µeÅlàá `ß´7n+i„¤µ!iÚ †ño` e¹;ÁÀ²ËµÑÎŽimF4As¤á+|b¬õ-c^OeIyŸšËÄÁ%s×öÙ%ì³Ù°7\/§§þ7ï»ÉBÙçâÃLï{õíf¯o¥—¥ ;ã°Ïy¨„»Ñ´.½'‰8x@4í«7ÿz÷ü¬bz9ëÝ,$˜Zÿ#A·»^Ú%i `˜­0ÌrÐ’³,ËHK6Ú“¸›\üì¢è -endstream -endobj -1509 0 obj << -/Type /Page -/Contents 1510 0 R -/Resources 1508 0 R -/MediaBox [0 0 612 792] -/Parent 1503 0 R ->> endobj -1511 0 obj << -/D [1509 0 R /XYZ 72 720 null] ->> endobj -630 0 obj << -/D [1509 0 R /XYZ 72 335.329 null] ->> endobj -1508 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1517 0 obj << -/Length 1562 -/Filter /FlateDecode ->> -stream -xÚ½WKÛ6¾ï¯0z’X+‰’-å–Ç:MÑìk£A=p-Ú&"K†Dí®Ñ?ßÎP–7Û EO ‡Ãy~C£Í(½¹x}¹¼¸œ§£ÌϦÑt´\fÑh~ f£e>úì-·j<BxŸ¯oHÆÞÛr¥žQu) ÚÜK³%j+ºO¢™§àtè•´—ëFÞ*ÿ¹ü­³À­—sôìF“(õ§³˜Ì˜Œ'I”x׺ b‚:†–»ɉáζØÓ Û¡¾a\ªü}ßµæÄø²"†*ÔN‘·¼Ó%/A|R5‹ªÜ˜-ðBÿ'|¬hý°UªxÒÍÛHxÒµÛ£Qì= ÅÖØÙÉ\e*Ún”áC´p„€zÐf[µ¬åK(bkÄ/,Vë{]¨jüñ$ŽCëüB±ò…Z]•Öï¬ FõfDÄ훋Ñg+ù³A`,;öd™“’û=”Mê©2×ßWuõ­"á­«š®j…®0ô³„ÃUq)ªŽ˜£Le€Q;…ùûùô}zõþVùãû¯)ú‰ýDŠ.‘À6\o”Ⱦ;|ë°'¶ªä`ù¼¢0³æ²b¾zÔùj×BÅÿíº¨ï»>ÐÛG¤Ëy8Q­Dl¤ˆý4b#c? ËBLíâÕÍõüíÐ1K¼¿hyU•ˆ ›¶VĴܶe©Ë }8\ðö|l_L]{¼+'VÝ%ãгÐÚàG%ª½íBK»‚˜‹“Ì“y§jL:œS|ÒöJSçUÚ{Cl]:9÷ÝY`Ìì'{„÷n-uyÍÁÞžúçÚñ-$%žfý£Ö.`Ù{§ÀHR5ñ¬ ´G6JÀœû1ÎFDìƽ^Q#“þšöWÕn‡ö€¢ÐËi¯Ð¥" -O«GgŠ9ßQ»ä,·†Ã›´“z‡¶;¾õWÖÀû±…2­Ê•:ë~¯pú¨bOµJx¬*ÁIƧ¶‘®õuUjh] < -7ù'ë¼›ZͪÖwäëÖÜuO7…þôo½£G©ŸEÙ7…àGkªTà - -æ@,#uQamá‡6*ÖHópBë ¶z9Īִº6 -]¨BB>Òt¬9ú¶Ž‚DÛ(\"õÞ©cÉVì ‰9<Œ)>ýTMɱç~¡br¨CýÖ òÖHÓZfÂ3©P±×±^ëÙÉa½¦ÕZSµ, -¥»oªûO™Ä«[H´‡ÿÏh¯ËŹ9ÞÛã‚{O«r+¡Vóm\ ´wÙÐj¼”o¼×¹ª:ü†"k+M»Â¨2;Ì­ulÝpÉö5¸¬,ÂÙË(Vá °«W}BÍè6Eä§":¢µ"^'A¿(S¯WÁCX Åwöy„]þ(/Ç î‘‘µqOäc;Ç]u­éP B串 -ƒÁtfg~6z·/.A |'ª÷uµ©åޝr§\ÈŸÿÈ,?E¥œÛ<ô?Ú0´pWóZQ}!ù{U+;…3;À¬RsͯT*·5—u]Œ‡)ݶ–à±Ù6Ð{ØàHF[ù2Üjä][Èš>†¥œ1’d®3[p5ë<×/ðÜÀ¡†³)™Ùg²O@Óäâ›ñ<7lì¼JÃÄ›ÛÈÕ´£%dØNé4õÚ2Wõñ¢$ë0 É;¶XT/+´ý+ñ\ µ…:JŸµÞkQò ö¼­>MaŒÑGô½9Ô!´OxðJÖ?V}\T¾ïÃSj­ácuÚ·ô¢{PþÁA"ôá9Ïp—ŸÙWå½®«~Ø 1$¬!Ô÷œ¾çWAð«C˜ ?‰ÄÉ4¶µ×½Z-õ‚ªðDÏëyLz¢©&áP ÿQ àËv»3×£†9i˜DAæG¡&&t¹dN{W蟄?00'™Í:e¯çJ6:ÕqytëC­eW%¾€‡^ßœS( -o•Ì'7%"åee,ROŸ4,è™ËÆ8×ìÿƒn¾õ{5…Ap¢´WM}„Šà1’$)„5óÓ4¥ Ótpâjyñ7_.R -endstream -endobj -1516 0 obj << -/Type /Page -/Contents 1517 0 R -/Resources 1515 0 R -/MediaBox [0 0 612 792] -/Parent 1503 0 R -/Annots [ 1512 0 R 1513 0 R 1514 0 R ] ->> endobj -1512 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [411.458 591.852 426.18 603.808] -/Subtype /Link -/A << /S /GoTo /D (subsection.2.7) >> ->> endobj -1513 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [492.242 591.852 501.014 603.808] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1514 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [414.729 381.654 429.452 392.502] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1518 0 obj << -/D [1516 0 R /XYZ 72 720 null] ->> endobj -634 0 obj << -/D [1516 0 R /XYZ 72 452.846 null] ->> endobj -638 0 obj << -/D [1516 0 R /XYZ 72 325.908 null] ->> endobj -1515 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F16 823 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1522 0 obj << -/Length 1957 -/Filter /FlateDecode ->> -stream -xÚÅX_sã6ßOáé“<³VôßöÎÜCÖ±s¹én2±{i·½¹a$:æTs”´ûP¶¼JÛ›ÛiŸ  ð£ƒÑÓ(]¿ ø÷ýæÍÅ*FsžEÙh³Í"?ÉÂÑ4 ü žŽ6Åèg/OÒ(õ&ôs¥ê_‰ZìDõ$‰~¦RÕÓx…Aà½#æÇÛñ¿6ÿ€&aèÏÓ”Ìe=sw¢ÙõåB±>ÔÜ}Ù4f< ÓiêŒþ´\Yö¼]³-)L¾;Ý*‰Ž.+ñXÊ¢÷éMÕHS‰rh“YOóa'eIäûCø3º‘yÈ¢ô«} ¼Ë¢0Äÿý¬®V«¿í·éí·Q{Þä^·ªxñ Ø\”:ÿˆ°«U˜Íú†32|Ù3¼nÄþ™ÈïEÝpäó\ÖõùÎïº"  8½xÍöÂHáÂDã0=æbù> ‡×ì}Ð…Ú~ÃÞbÐÞuÏÞµäó^oǃò>§å¼\.çƒ×}ÿ‹«,BeØ‹7‰b†dwY5†Ï×è¯ï&þ»¿ë+,¼ÙP!œ¤ë߸ÇÅjvrÑáÑÌŸÍy«ÍŒFiâ5ãhêÐÏ©gY©§·$ºEîÌ“F4tÕz‡qH„½¶ÈUAÄg4'M­tEŒj &Ú=²iC»ÃÔ;:_*æ7ìØŽÝiô3qȯÔIàËÜHY½E³·Õe©q›/hM²?¸8°åª[$Þ§ÅÝ}<”Ü¥Õú¬Œ®öÒÒàP u¦ª-œ[›=žB‚‹ŠD•”…,|h6óÈ»7ãdîUš„¸q^7MEr«Ûªx‹tì úl÷R` \]ÙŽn]¨Ø.Æñ-‘¶ì^ª~.…-ab丅½3|‚F¿Ã½ºè~ÏæàÙõð}¡«­zj-}¼Tì’ÿ”ÜÐC?€¤OQ»ÖïòË]³aÇ€ëÑË  Îc?â~ùQµô'%Û›{v®V Ù‰2?LÃ~Jg•hz]â8†&Q0÷£ðÌ•°?¸ÛÇRåü%dGÅôwÇtôª£œ_4.ÿ–ˆ{æî¥(&·UypYÉ”ý®[IÏΪ‚+õâàÁ÷|¯ÏpÎ+F¿nÊþ?ðáfµï_Öu»wç¹ýøç ŽôÛ ¡¾!@8±øWßS˜Dµ²$‚V­\aÇÆ†-¬ 80Q¦aè­Æ3˜~†ôä œ·”Ð “$ñZê™héÓÚö§žQj‡Zå¼ÛV³²²£UTM¸›w¨Î¨9òÆ3hüÊyJñc—¨W$§ëÜSðBÕDÑnHõç)-øu­é°™öq¯šžªþ‘·xÕµ½p$5Òª_TQ4÷ƒpå’ù3ÎëlÞÓYnÞüÿ@÷ -endstream -endobj -1521 0 obj << -/Type /Page -/Contents 1522 0 R -/Resources 1520 0 R -/MediaBox [0 0 612 792] -/Parent 1503 0 R -/Annots [ 1519 0 R ] ->> endobj -1519 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.873 175.542 133.326 187.497] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.4.10.4) >> ->> endobj -1523 0 obj << -/D [1521 0 R /XYZ 72 720 null] ->> endobj -642 0 obj << -/D [1521 0 R /XYZ 72 162.597 null] ->> endobj -1520 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1526 0 obj << -/Length 1111 -/Filter /FlateDecode ->> -stream -xÚíUMoã6½çW¨=ÉÍJÑ÷Ç -d8›Û± Ýí–h‡XYREºÙüûÎp¨Ä’µMÑ( -ôbÒÃá›™7Ã'ÏÚZžuuâ™õÝêäl‘Y¹›'Ab­6VX©ï¹^˜Z«Òúh+&ª¦›9‘ïÙ?//n–¸õíMoÛKN–G¡È$Û™d6/Ä'Ï -:fm;óíJL‰¦–d\ÏÀï‰ö«*QoûHó›×W½›¤6‡˜&«KòcÅ;²©nlmÛ‡¡!g¿¬~€rßwó8¦Âº}í>Û37r²/¹R‡Ä"›aÈ ‹í–IÉK2ª†Ö—,у™+Û®Ù·fßlè¬ÀBXÇ -ÈלIÞ‚AhüÌ…¾Vs³éèp×tÆ¢ØZ¾m-+¸$rŒì¢Ùí˜t§ -¾d”’’S–¸Ít’¸Âqz˜$ÚÖÔÊ­¨¡osn32\—¼F\¥»MÝÈíÇñ-³…vJ{'ƒeZ–Ùðß·5ï0#[B@’2 £á±ÞòÒ9©çÙ×õ«`„6EVf¡-ßIÜFvÇ+êÚ1¦^ÅŽÓ±ž44•༇y‚…k'Ì凜]&'ÉÝóº0hB’MùvæÄQdŸ“å“F§ß’—ÛÚä9äÖÜÖ¥¢ã› NTŠ$„Q¨s{^é‘¥ ?ÓŽ ®+*vK`_±Ò‡ÕÁ™ƒ7 [(·%¡möuAÏK‡¨™ò˦© ²£4šÆÔ€Iñª’t“¦%ÅiÁ¿ºMQø(Å:Á³ã4žÚ£ŸPñ/S2ù³ÌT†¤iohOñÂȾ„’¿ëÙvV¡Ò¸ôÜë‹ã7 ÉÄã-&𬶖º~[ìf¹OéÜ]>:1Œõí~ "Fè Q™ Ø }K‰5Øà¢ºQœC© æaâþëØg·˜1Ã׌Aî‘”N(N/k¶®øðvàæ^bð͘ÝMáßqV:7uõDPømFOX×°—ðM©‡=7 ‡È‹)dÝ9&¿gáÿBÈÏ„~Ç«f;¼ºi8Jû›)ð$´çzvxÁFÖ8ÉCº7MÒ!ÝËIº<£~6{3SËŸ– Dtp®Hub½WCâϾð…†À ú~táð‹îC¢!ص£ù„cÀ%g]¯Ñ˜ÌsžÃ2hÔ›ï¦Ê¼à¼"äwOê½~ª D×(^¨#"ê™OE81u\ŠÚÀŸ—eÇ¥Ág®°ƒ>žOá/AûZÓŒ¢@ jô­Søž¤£ñ:¿?ï8ë9yÞ] Óþ‡Wð?Q¥Ø˜7Øù -G¾úcŠ®¦b\qu¤I¬MaCwÇoûtò,ÿ,¶å$nFEƒ)Q¿˜õI‘ÿM‘Ž_鿤ÍÉÿÚ|()É]´â¿%Z4-gÀàñÔ€¸$‰ÿωËÅ -‚ØÍS¨)ŒÝ Ï(Xî œ.W'¿H¢˜ -endstream -endobj -1525 0 obj << -/Type /Page -/Contents 1526 0 R -/Resources 1524 0 R -/MediaBox [0 0 612 792] -/Parent 1503 0 R ->> endobj -1527 0 obj << -/D [1525 0 R /XYZ 72 720 null] ->> endobj -1524 0 obj << -/Font << /F8 826 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1532 0 obj << -/Length 2202 -/Filter /FlateDecode ->> -stream -xÚ­XKsÜ6¾ûWÌæ²œ- Í÷9l•#Y¶¶R–Ê£”+Š÷ 13(ó18+;¿~ûŠ£0ÙöD »Ñht7¾n0ZìÑâÝ«H¾?Ü¿z}].ª°*’bq¿[¬“Å:ŽÂ(]/îëÅ/Áíq0}ç–«4_O³]&epÀi(«™îL{l¾ñø¶{}û9ŠSúý¾Ñ²|”×zltÍ"¨Q‘€mÖÁAYµ´•ÕMß Wuõ jãF•ë‰Ê2ØõMÓãüÉtûå¿ïÿç^ÅqXå9Ÿ÷LË€ö¼gŠk[S|àœ€špeJxdŒ­ý™ø¶çRE‰(‚D#J^‹Õ»FÄ"5»‘g¬(óM*4¹a³:Γ—Öu³…hr±ÓçDDŸL›}b¶Zž•‚E50øŸÐá³Ñ1Ž`±“‹‹Sn·@äáJ:¾¿Út¡ì{Óùðkîºîém‹!§¾gZÌŸ•¼ÜÄ6³mâ¦$ Çg›Ï<ú‘2G—þ!.Šïhéº 3pï™›ßÊ3¥Î„_„ãŠ_·"rEÊÅÊk$‹Ä¤+½S§f`Á a?Ö‘b=nðóÛ ÐÍò7Ã;õ÷°]@ÿY?½KyŠò6/é„M¸Å,Jÿ—„ª1þÁ7©c–¿18nÕ—¥¯d0ó¡(©Ü7ž¡¶ÐÄ:Ã|˜ïà±(œn|ÇbjÙî–‹d+©ò%^Î/~‹å¨™¹Üê"Õ¿ƒèQ†êi&Æ­·N¸ƒ¥:3[׬Þ+[7ü”Ê)À‰Ôm²§?Qhpô†Bƒ##K Õ¶‚ÅÔ„Éé†ÐfK]R|°h²‘÷‡A!ÀhT΃ƒe$™d´¥*'ð¿¿âup³ó† < úß·øåÇ:Îýß»Yç(r|šN²Z-~:¥ØLÞÈÄá—%”% ŸtÅÀ“7•oâN^”ZÜ鿬“c –?d|¨ÕÀ”·CÒ*å‚rÖJ²½µ “3@}·L~¿#lZV…ÿYä1Ï#=Úúø°¹ÂÑ-Žxà~ú¸ŽUIR…Q\-Vy–‘¼´«óoï_ýâ¸Ï¯ -endstream -endobj -1531 0 obj << -/Type /Page -/Contents 1532 0 R -/Resources 1530 0 R -/MediaBox [0 0 612 792] -/Parent 1534 0 R -/Annots [ 1528 0 R 1529 0 R ] ->> endobj -1528 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [117.238 176.095 126.01 188.05] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1529 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [340.706 164.14 363.178 176.095] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.2.8.3) >> ->> endobj -1533 0 obj << -/D [1531 0 R /XYZ 72 720 null] ->> endobj -646 0 obj << -/D [1531 0 R /XYZ 72 440.112 null] ->> endobj -650 0 obj << -/D [1531 0 R /XYZ 72 335.996 null] ->> endobj -654 0 obj << -/D [1531 0 R /XYZ 72 139.794 null] ->> endobj -1530 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1537 0 obj << -/Length 1310 -/Filter /FlateDecode ->> -stream -xÚ½WÝs›F÷_AÞÐL„}K-«M§©5’&šºé’NS@vÜ¿¾ûuy¥3yºÝ½e?ï~·¸ÖÎr­_®ÜWÖŸW×åZ‰“D~d-¶ÖÈ·Fžë¸jd-6Ö_öû¢ÑUºn²G=†~h/ÊÝ.Ú÷\×þ‰e>/C^¦ÇÕõ4möÌ-«¬‘Oo‹t• ýÉ Ýûùøn„7ø{ñ›åy¡ãF#kèyN†ìþ5y¶þºùq×üðdßWNâ±ù›òpH‹ ó{VÈ×7ûsÖ•¸_’…QìW/¾®Ïž²+zë³ÊC2;õ6=æ ëÍuÓdÅn0TÑèdÿ»6Å ›Ý˜,¯'q§—ƒ9q’°éå^зQb7û¬fª|h²R¤FVëFÔJ^ÿ¼‹vÅ«¦¬7oK\{Kl—Øpܤ®2I¥%Ùø${ÀÅÖÕ!C/±k?UÙÀ³±‰È•f?ÅÀê~ ¦ñHr½ ×õÛ^µ¥+äWE Ÿ3—æy9€PŸjæÁ³)oL>P(v™ÉKÊm6zÃji^òXEͲé"†ï@cBWêLïõÒ…ÀÏ–ƒXÙ|jQ'W¦•PT5Bs><4õ¹ô(T¥(~´¢‚“ˆc” -7±m$kã®MT*]өìàu¦ÓÍð®ÈŸYEWUYÕ3ÿÅ9S¾ bà‡rÔoœÛ³öÇAÙzÝPLPˆù±nRò+:Òð™}=#…§w¸£@ô.õxöÌ^\€oÂ2ÕƒšNôÈ~äÈ¥'tm/C’Ù%H2;×ü>’Ìþ’н6P"wú$QÊ$AÊ ‰R®md„$¤VòJI»âµE¶¦™(Êêæl¬{_`kZ• t™G<Ñæ4u®pã™i$$·Çb݆¹@`¹Ÿí§Œöýâi˜`¬Ó̬sV ÀQXS^žè®U‡îg¥¥(Ö¢™ÑêfzýAö -¸bø~á;L¿ßòÊyúrïaÅG¢¨xí¢‰IaAÞ-&°¦˜gÎY¿´)àB·ˆŠÓ8¡Æ) eî,’Á«À%=ä9&iÝ0pL²ÏZ0®À?,œé¼ÜµØa:ÝFð=€q \=¸˜P¸Dq¸Hr¸„ l;.‚ŽÉ%Ð1ù:tLÎAÇÂ?w‡œ†`NƒH‹l$ƒHÂo3 -xAíŠøpC>å¸÷Ú³Oo÷ÉðŠføî>°dk,¥Ìã£HCÙ¦Êñi×Ìb¦e!.²‚…O{xeÁÍÞä$ûËçùö;üüf|®«#øRÜŠSÆõ_]•TFàFrçPN„Ä €©ôêˆ5Ìe3Ý6Æ B– rÒœ v2B.OY´ŒÂØ^ìM < Ôæs^˜äÑ¤Š’-œuã­?µÉ~ûPvó®Ÿá³Fb°/pí_ÓjÃ2¼.²-’سw˜Øà&DDŠÁd“AÌh -ˆH+ĚجP<é¢Sy.yŸ†QŃ.*taX†Q ΰ3©Ò)£AM°“*?]«cf¦.šâÒ<—t;¦I6ŠÒg…M…çf -Ã[d ˜Zn·Zç€ãÆ„œ"ÙÛ§ -„ý§ê›Ç½P@»ÅfÀ¯b§—åUÁ0ò­ƒ8Þ…=¼n¡ÙDK¿géwCõ›/¡:zªßôRíc'TÔ £ -î9ж‘ø½/nWÿç&› -endstream -endobj -1536 0 obj << -/Type /Page -/Contents 1537 0 R -/Resources 1535 0 R -/MediaBox [0 0 612 792] -/Parent 1534 0 R ->> endobj -1538 0 obj << -/D [1536 0 R /XYZ 72 720 null] ->> endobj -658 0 obj << -/D [1536 0 R /XYZ 72 559.664 null] ->> endobj -662 0 obj << -/D [1536 0 R /XYZ 72 376.801 null] ->> endobj -666 0 obj << -/D [1536 0 R /XYZ 72 183.09 null] ->> endobj -1535 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1543 0 obj << -/Length 1715 -/Filter /FlateDecode ->> -stream -xÚÅXÝoÛ6Ï_á½É@­J¢dY}Ðæ£ËP4A XÚ>(m •EO¢“eýî‹’ì:hW Û“Èãñ¾x÷;RÁh5 -FoOù¾¹=yy©‚QægÓh:º]ŽÂ$ðã$¥aà*Ý£OÞyÙæ÷•~5ž$Qâý2¹ým4IgÄ9‰”Ÿ…¨—ù®²Ì7×Ö–õjÞTù0N¦š>Ù袔Ţ)Y9NgÖÚ4›¼ªž˜ás&f»E¡ÚýÍ-IXç-/ŠÛZŒY ã:¯WºðÇ“XeÞÕ’WžpÅìxû¶Ñ­ÈëÒ¯bdèÆ®)`0„ÀÔÇâpfH‚mL59ÃãRÓ.¸0ÌwÖlr[.ÄY Uf…ÊUÂ1 -háA­y ºàÁB•ôÙé=L"öÖÏ»-gVñqfœíêŠñ uØß8޼7¥u¹™÷<‰¼”ifÉSNC ´„c€¤Ï¥Á20/‚/.ÉžH"c©¯ -Xsç&îVkë¸]rÁdÎô|'Ç@çXt4DzazïeY‰I¯#±:H¶g[Eº×)Ré¼ÏuÞ,Æ*ôÖ<¶ƒ^ÿD/è`ë›npÓ˜ÍÖîwƒt¯ZP°q=hÏù5á`ûª‡Ös4—+áEO#U <çEÑ Ö®p ­óŠÅ©¤jÿšAqAƳ›ªß{×O‡¡‚½Qâ'p:?ѶNÿIÛ:8szõ­ù²óô®· åY¹äo³«ù‚„r©w䘴ý¶xúÿ´Å¹®éI^¦Ü{&Sý{ÆKÈ9]ñ]KR^óBWV<]ä»V‹¤»ùÙõûË«·¢Áðw+yŒãþ֎ʉтZ„!\±qÖ Ëp^€!%š(évPæl¾X€Q& -;Dt)ñÈPŽs¿;5èBÓ(ò®÷Mp`LVV•A³»ÍñÙÙ3ºo«œŸH-„¬4ëbh 9<åäQòòuÇœ½ Sy(So4Ÿßùš®è%$ ¯~„f$‘äŸC”þ¢ùé»(ñ 6 È|qÅxìòø/êêù¶*_^x2Q6¤1ΰâ—"ÊÒ–ʰ„£A]àÔÉÝ”øÇ}]î“4Ãß«Rî¡-°oD<`™sç|'ALB>®X·õHXÎ\g^EæªZiË”vËMùÿY:§4e<—=>K³À{o„¡(\5’€½„ÍÑÒè?v`®hç‚òywœ*@ÈœÉO“ìù:Ør†„oÖLfƉ¼ž‡Hƒ/G²‘È´òðì^ ˜<Ì线KQª<[Ȧb‡ht›Âù@—C5Åÿ[`þ«þ³,ô¢Üsø†Ô½iñš¿_¨£(Êü Ìàr¢| -zgjéâöäo,ÿ -endstream -endobj -1542 0 obj << -/Type /Page -/Contents 1543 0 R -/Resources 1541 0 R -/MediaBox [0 0 612 792] -/Parent 1534 0 R -/Annots [ 1539 0 R 1540 0 R ] ->> endobj -1539 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [253.347 449.521 283.567 461.476] -/Subtype /Link -/A << /S /GoTo /D (paragraph.2.8.2.1) >> ->> endobj -1540 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [428.566 425.611 458.787 437.566] -/Subtype /Link -/A << /S /GoTo /D (paragraph.2.8.2.2) >> ->> endobj -1544 0 obj << -/D [1542 0 R /XYZ 72 720 null] ->> endobj -670 0 obj << -/D [1542 0 R /XYZ 72 607.484 null] ->> endobj -674 0 obj << -/D [1542 0 R /XYZ 72 400.711 null] ->> endobj -1541 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1548 0 obj << -/Length 2638 -/Filter /FlateDecode ->> -stream -xÚ•ËrÛ8òž¯Ðm詈áS$sØ*Çžd2µI\±·Rãì`–¸K‘JÖ¿ý*Lf÷"6îF£_€¢Õn­Þ<‹¾ó}u÷ìÅë4ZUaµI6«»ÇU‘¬Š8 -£´XÝÕ«ÏÁ/ݨÍÅ:OòàæòîW†.ëÚèaàÁË‹?î~{ñºô˜D«uR†YQ1·ë,*‚§‹¤ ú®›A=´š㞀Mpýá–17H«Æ=úãØôÝs€Àû[Gõxê¶8scþuF†”`®n^¼c( –¢ºš1÷UÈðGýçI£¬zì ÿŒâ¬þ  -½âöâ8¬òœ·§¶[2FÇAßµOE¼%¶'ct‡Ûy.Ú~·Ó5O×Íðo†H+œ> Úfj^w4h¿2Àê0a;Ãl­FÅÐpQÄF3ÍAuj§Ú &ž†QešñŽR°‡¦í ´×žûº×F RÈvý|.)Å Ã`GχcZE'8„N—2¬ °ÓiŸšV’!ý##Ø9A¡ƒ˜dN†£¹A”6Ûþ@§à/k›C3* -5š  ÌÄ©ÕBàüh†æp_:=Ž,:Ùˆª‰¤¦BóhkØßGͤV‰·ÍT¬ƒ‚2Z1dOÒ—ft«¿\ä9¬´Øó­¼u_€Ý:€ÓÖYÃØ]cTf D¥^²€·Eð—:°r¦C·&§àX‹½ŽÏ=Íh™£¨==ìŽöŤ«$í2J@ÅŽ154»NÂnbðÊd8o e€3²~GÔyt ?±‘\ xòÑô‡}¼åSÐfÊk<ñN©–<Ñ_SÐî(ÔÕKßâIöNã´”ø-m˜”ÁU8ˆsÃ`¯P vðRÌ~Fó÷¦“¥ÎT5åá¼ ~ÇdÅ'¿6œWJ:RöVM9ëH¸¾*¨8Cå‹¥'#ñ‰Šª‘!v×Ű::‡Râ1vYêo?…lÜœóxœ'£4¸¿ºù˜¼HeV˜gAm‹zÀ]ƒ'û÷KÊ -œ„Ö Ï¼co‰Fp’Æ”˜ÂGè¬Ó²’“&"¨ÁøÉÎb”¬!ʧ†hçhjstŒœNe0Ð[½åL…¨Ñnû-:·Ïká@¬ÏgYJ^„ å玎¾£gELŽŽ àäH¤QÂì­ Áü£”S"æ~ ¦œ³Ò`rh_•«ž¥KÄ©‘Äwê¢HƒËÅnZ Ñ4§QרtœL'VÅ™©ã¥=mÑó©qK« W¼JZJäØÌÏ_F/I$½}ãzŒ -{,§$\ŽŽû •a2-ú£Ã÷\"'—ÀE‹ç‡‘ŸÇÁµ™R /CùÊ´jiãŒè+•i›bsIXHMçžCÁ…”w €5˜íØnù¬æÃˆ’5Šh,Æq¸¿¹(³àSÐݯáÕ‡wŒæÍS¦ÖÃNŽÃ½¶Ý’ n57ê0õ,†Éhev+>¾y¶úLÉ! +"°×XGõ/Ÿ+$©¨m©Aú*ÙÈÝ.¦N ’Œ¦EÊœ’Ê炇-˜y!å®) NÇyßæ*f6k^H³@EÖz “yycžÙR?±UÒR*ÁA{‰F Bøu8»UþpDÙ —Òeé©)Á^¥iùîE„ÂÛÙh̺\®¾Œy=½¨¦D¼z²ÊÚ´·àžJ‚÷˜™‘«ñ0-5 ÅŒ‡ïl’‘äA¥Ø`Vë­“p ¬6“`LmÔ0áí±æ%~ɉŒª æ÷ü¡RŽä’ög »—Ÿ;?-œŸJ£.ÆüIJ©×"¤9s—š»ªf\mɽ•>ÿûË¿SgÑm²Ì—‚#2”-,Œâ–c ->ÝŸÐÑ1h¡d1¶ÃN©"AsÕØ¯ÈT|ßÁœfÑ|À]¹Pˆ—½q®Óº]{# ¡mé,„»pL~|â1t¶øUü9’©ÖPH8h¨¶Í‘ ?ŽAÕ¬6s‚›#ÏPØÂW:[¥øo\ôˆ >X*52™q¯ˆçhðø`õû®ÂÁŽt#I(Ìt¸£t -%'âG›8öŸ~â0Š`B‹ÿöí³NYeç1d™õÁ•§$•Gž 0o·þ¨­â@&rniÛ®œ¶„©ÎŠ“7‘$ñnK"žzºbRH2{-L\äž±'`úÊÞÓ¹y¬ZzÛíÚ.d ǬÆÂ͆^„ -Û‰ó,xÏ`8$³Á·ëG^õØŸ:ìÞÒz=žLÇ·Ž¥˜,W¸–£à[aËx‰'ã´1½³Ëój·LTÐv;ÆÉY|·æÄ…»E ÌýùÂCÌ)KdO%.¬HœÝ)r±¸œNÁQìtB5×/>‡ØF=B|Yói'Ós¹µÚú®¼ÐÁ>šñ¤l[õMWÍu‡b $YNãÛ-Õ -L¯\a)¥{Úæâã±m¶öÅò´#Ü ¡m5ƒ¬4ö\2¿€Q)—ðßáÝ8Åø‹&Ó2ç•ø¥×ѶcL¹7lâSWrö$&aQI¡ËÂ8 -Ó°„3ó(ø´×OÚËWOÔOC·ùéJ½ix˜â#ÛÈAsÔµˆS”©8 -÷×€£Ôè÷±ö{öÖŽÏä›0ߨgòÎ67ZÜ%'q/WògÍÑAÖ[–6 e`¶™ù>P{5CÜÉ5jÌïñÏ'¬{wA^ü‰cV„Q‘Î9žõp–Áý4Ä.ÔšÖ&y˜Ãñ¬“4¬bæá\ɹ{BÈud¢îÏßnkcÿ©à–ÿ“`âjýó=QE?Öui¥üwa¥¬]é ¥¼M]ëGEåénÝså¦p*¾ÿ0Ù«f¶µþíŸ*ž·|¢„—U±÷·Jyï <æA2÷ŠØF–.>—á„ß´æi ðêÃû×oßðò#Ty’ãê-b]c‹Îð$·žX©I%\D÷Úžø4º-¿~p3„ÜÉ}¢¶¯ö[œù0ã±µv{Ò*÷}ô”€¶2:Ⱦ¾Ë—çyã®ì›¾9uRêl/WV~2d Î,y -V½ü_3ƒ÷šæŸÿ2^=Œ‹É?\X$›){°Ï/˜üÿ’7ñ.R&áý­<âíÕwë$©Â(®`ÃUX–%+Pe³¿Ü=û/ø€{ -endstream -endobj -1547 0 obj << -/Type /Page -/Contents 1548 0 R -/Resources 1546 0 R -/MediaBox [0 0 612 792] -/Parent 1534 0 R -/Annots [ 1545 0 R ] ->> endobj -1545 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.873 489.778 120.596 501.733] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.9) >> ->> endobj -1549 0 obj << -/D [1547 0 R /XYZ 72 720 null] ->> endobj -678 0 obj << -/D [1547 0 R /XYZ 72 332.003 null] ->> endobj -1546 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F11 833 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1553 0 obj << -/Length 2318 -/Filter /FlateDecode ->> -stream -xÚ¥Y[sÛ¶~÷¯ày*Õ‰¼÷-µ’wÒ8ÇöLgœæ&)›ŠT@2ŽÿýÙ/’·i_D`,À·v!׺·\ëí™+ß_oÎ^¾‰­ÄIBZ7[+ÒV¤\Çõ"ë&·>Ú×EUd]Y߯֞ÛÝÃJÙ—ÿtw?ªlÓ»J„;+›Ë‘}·Ò±ýÄò¢ÆJWQÙ)7l¸Ö®æ¤lìÔ=ˆÞ?Š¢bÙ¯OK°ç°ßÏkþ¶)ÁÔÁîRL:ov«µ²wi¯>Ýü{°VÊI‚€Wû®¬Q -í]³ZƒÁ¹T³´o‹–Ë·×›Ëk.v Ó¶íwÒµ{H»¡$¢Áx(òžtÒPŠÊ´zDyJ"»|ÿ‚ ÷åWÞê(zÀ#·ý ÜèZ÷ƒ¥´jøþé*haÁYÃçbÚ\ŸõUìÙ¦ìŠö ¯Š:Ý‘R/°qëHúÚ¤moŠ!à¬Ö¾¢ÅN…µ^c¿¢cÁ_ÎÆ·/À8I˜²M -š¾¢u¢d~$P…­h°õ±åúŽnz™¹áﻥųyahÿ·øVæEVîRÜ…°™ç°°–[›- ŸPUÓ–g2 aß³/:•2v>&²AçÖfÖmyWVe‡6?qW2¾E»ÊKa8ÙzGC:© óìMÓÁÎÓÆ-";ÅŽqb×E KÍW·‹c»¯KÙ+>8Ú hJ+ØÀ%°ÊP)8æNT¤Üi؈ƒbÛ¸sñb@î¸c^mE௰ßû~I n™ÆÌ"ÿ“t òP€¼J׃J |¥XãÈáØóÝhÎxÛÊTçß5éuÍ×ö;Î{ž ›;t^/Ø&ÆmŠmJ8ÃŽS´FãT¢+?¥˜T‡ŽŽ$º!"Ðñóby¼bn ,`\/¢†¿S{ØV‰—Ëxµi h¼¼¨?Ç‚²9`Ý ` 36™Û ×NÑvpj©É17Љ‰ÛÂVçSNˆ7ˆã߀OÆ@í„Ý@&ÆP´À æŒÜyì)qð¾g Þ”ÄM×´oo›á(ÆYöâKS"1 5S@æÒÝwä°Ç(ïÐßNýñã_:×§ó½«B¸½‘øXClͪưžþ4†¿‡! Jq1¹,‚ γ j|'ØÁèëK_Ô™ÔÀ»è+@h¹–Öò$@3p@å‡p {Â'ÏN´,@®0†ÖĶrȎ⯚¥æ$â¸Û¾ÎÄ%AœO¶ÜÆ•’0À(Ù• ‡ÌÞ”xš!튗|äØpÝ¥»=,”¥)G±ä†bò”Ê|tP )yä ײS‚H)'¾-g.W=÷¢·..{ 4ŒÑ:%Ñd*},é‘Jwì\ÙöàaXû  ØDO:Sr`N–N9™ög7T(ðÖüèîZ☑Épc“„¢Š@ÙçÇIJÍ]<-×rEÏnϤ€?즧t*”þ“ðäïìè+BþGKH‚Ö‚üÚæžE -endstream -endobj -1552 0 obj << -/Type /Page -/Contents 1553 0 R -/Resources 1551 0 R -/MediaBox [0 0 612 792] -/Parent 1534 0 R -/Annots [ 1550 0 R ] ->> endobj -1550 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [333.987 506.708 356.458 517.557] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.4.2) >> ->> endobj -1554 0 obj << -/D [1552 0 R /XYZ 72 720 null] ->> endobj -682 0 obj << -/D [1552 0 R /XYZ 72 591.995 null] ->> endobj -686 0 obj << -/D [1552 0 R /XYZ 72 232.405 null] ->> endobj -1551 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F15 1136 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1558 0 obj << -/Length 2080 -/Filter /FlateDecode ->> -stream -xÚµXKsÛF¾ëW`OkE`ðHN^Iv”ÊÊŽÉ­Tùq€€¡ˆ -Ð Eÿ~û5HQ»öVí…èééééééþº‡¾óàøÎÛ ÿ…ï?Ö¯Þ„¾“yYÄÎzã$“(ßóÃÄY—Î'÷¶éM—}õ§Y,u Ý÷]»Û÷‹e |ßý‘y¯ù³äϪÏw{&ͽˆ…9˜^W;³ø²þÅIR/ÒÚY*åeð¥ ßíûªm¢ù³¯ýkøQÕ!¿¯ÍåÄ]!׈ö¼,»Å2Œžû¸º~Gó´K”x~ïò²Þä6È\,£D˜¯ç -—*ОRg„^¦XãU»ÛåM)ç®q×Õ6G÷™Nô÷×ÏO³†ÙÅ&éÙù²ì›Ï‡ UÃ1ÿÜ‚kvĸï’E­³ƒ^›M>Ôâø•éûªyßËjÑU¢ŠWoÒYtù )õ´²ªõ¶‚Rí¶tëL¼¦~b*_©ûçBUÕì$d?Vý–©ë¼7v i:æö¸ìIx¢s3-xÅ$E#Q¤áàÁ½Ã‚7‹4t[Ñô>^ŠÖ­ˆo†¦xnuÓöä:ÿØ¿¥ù쫨§,Ã4s)RÀeø-­ÏhtO–3Mû…™ïþÚæåBáI”Ûñ܃i ;{»lhJ#3«›õ¿Þ\­=¾–mý$]5"jø`õ…»}§{p˜øðöÂùDB¡y‰X쉡©)±‘~B³ÛáÜù·r‡rY—JqLÕ »1hR}ËßκÏÑä SvmgжiºY\µE5aJ÷|ÃÀíÀ\1 ³–6™.8„Œy\ ©pÜrÛ4¥hÛæ=¯³ÇåsðZ#à^ÏxÁ†yet¼0Ja‹r( ó†¦1hKÞ=1£¼ÖmM^bp‚ k -N^¿25\ èÜŠ"^¤,ð"Í¡Ž‹Ø<°]Óà=…N„±)ßžeG¥·VŽê_å™CîÆkÚS­@›Cß&;°«ºfªÈ‡ƒxºm,±?ã5<’‹çÚDG/Ì{ø$6¤0=pªÎQ]ÝmAšƒ¦$ØâŬ­£v< ˆ•yËB=:°7åpºâ0çÇ£L±ß“RkÁ0`-ßV6‰úÐýXa>ý×ùÅÖ”ñXL1OÃøŽs„ÿ·sL5ù<ÊÑÍ¥^dÒÝl0²Õ”É88JÂü\˨ç/e8Q{ŠÀ¶âUÌ#h%)ÃÄiêPȆ‘ïî^HE)²­l<"Ê‘¦©êàˆK *æë`šBFXÉŸ™t&iÇöýÅíKFtëÎ% 4-Y,ÉIÌ{[pq0:“ªÈ‘¸t+U0õZp˜ùˆÕ¦–¯Š¦UÏ+¾]S參´?mp ¢äe@œãp!¾´Zü‹ÄýPÕý’ dÏt söÌh»‘'Ž%`prìu€ÞåRéIóØ© Efii p£{3¢ âöÑæ3ˆ$Á ÝþLu'–@Ð“Ì ±©ÇË—áð×.åà!ØŠ¶)¥\ièK©1ÝÉFlöÜßžª6¬Ùä™X•ðôãÉBª1ÚýÓf½.™Îùs¨vûZ~VaDý¶ ìŸ~‚ ¥ÝbÌ*òÛ9 õ,ªabà(%¥|?Ó èA¢dó(E`(ºb÷ØRˆê1 ôtgÓRÜ‘rÃjëwbAgŠù-¥ÐhXD 6 ó÷u^Ñ0U ogv-\ %ú/Mf¨ ³£ £d° ÃAÚªà³>!ÁG5Í:”JgŽ˜ãÕîÏæ¯ª4EµËkd„ôæ8Ë’(À %1Ú µÜ 0S£ÖW@ÚF±1Bà ‘N&<¢l§}DóŠ?Š‘E(dÍ‚‡{y£Ì,EpŠú™³ßÇÕÕ»»7·o±ãJ¹÷Ó™ ¹@©£Ó™‡¿¡;ÐÖ§ÀÙš¿òÑ=8#îáY왈Ézl96‚Àí¸ðzXM±33,rÈw²TpääR~œŠ_¶8¥>%-®ÉquÉ“’­@Íñ$US_ÿuÀ¾­£4™´©YMJÊZª8`ÃM[×Ô#sÓ^2×b%Ò9/øùÈÀ˜ÂKCà_·ç`ôîÝzªb‰´0š?ÞUŠ¿MëÁH'hQ*ž­ÙCù«Š^Ê9pakxC‹t‘‹öOQ Ý߸Á N:œ0ðRÛáDžò½ÐS -\¨ `ØKO#÷j/—¼7<ØHÃéÏžÀ¶ý[àY—w³¾ø*ïAå(­=è°@iO‡Sì.>}ñ&Ák^˜¥Î#‰îœÐW^¤b kguñÛ‰x½8*L¼4 ÿ“ßI/ŠEÅÙ¿­”vTâA:'ˆµ—jå¾ïéTZÑßʇ¶âÃÝíÝÛçãRù!­Ypç*•¿7Z~ÝX/i$"[õ€5–SNï_ Ÿ0J8‡Cî-(LÇ/Wðë‘Ø'ì°3æYEŸRqk“cdEÙÞ¾} S+l}lÊædžÂ‚‹‚„&Q$ÏRbü5‚“ˆ!¤–ãYɈÈÍ{«âd÷¢Zž³—º·ò\ªÝŸ„rÛêBãOOBè#ÐÀ>™´€_í.'`¤¦ÌiZ¿ïÚ‡.‡'}÷ƒdà?sJpÌUÂÈPûŸS<ýç„ìƒÙçøK e3r©Ó<ΔHÇð -ɾ?ÈŸ'ªˆ“è{’í›þàU -â> -¿ãÞ«—þམ™ÿ­;{'ÎÓ-2ÏW™³ŒÔ´{­OþÛ-Ϫ -endstream -endobj -1557 0 obj << -/Type /Page -/Contents 1558 0 R -/Resources 1556 0 R -/MediaBox [0 0 612 792] -/Parent 1534 0 R -/Annots [ 1555 0 R ] ->> endobj -1555 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [469.15 559.05 491.622 569.898] -/Subtype /Link -/A << /S /GoTo /D (subsubsection.3.4.4) >> ->> endobj -1559 0 obj << -/D [1557 0 R /XYZ 72 720 null] ->> endobj -690 0 obj << -/D [1557 0 R /XYZ 72 250.843 null] ->> endobj -1556 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R /F15 1136 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1562 0 obj << -/Length 1910 -/Filter /FlateDecode ->> -stream -xڵ˒›Fð¾_Ar ªX„A€oή›Ê®K©Tü8̢ъ2‚5 ¬÷ïÓ¯AHƉ]I.šžž¦{º§Ÿ -½[/ôžŸ…²þ¸:ûáYzy/¢…·Úxiä¥* Â8õVkïÞìv¦^ÏæI”ø?—µeè|kZSô¶}ÌûïÏgïV?yiè$ñæJ9¬Äáimn*ùì@M«Y¯[ú.<þä¢ìð›zNDsÇ=Šƒ\ ¥Ý˜}Õ3áÒö}YßÎæñ"d ¯5²øáY6R„Fi‡‘»ç,Ê|P‰Y$Ê7¼œó²i›CýÖ2°³ôÍžwe=¬Ì Tþ‰°#ofsØ­ekªªÁÓûŽ÷¸i„YßðZÌ¢ÔßšúÖ:Ù3åø-{³»“;¶Öô‚n›}OEBÀĶ åfÊÚ¹±öM+ün÷uÍÆˆcÿõòâå2`ø Ÿw¶hêµi{ºë6ww¤«5m÷….çÖ¿;y Q\MTCxUîzå”ÄÍ›·a^ÀâÇ~ÄhÄ.kûwÎÿ>ëâP«Yûhû<÷×Ì7ƒ…îé: ýï 6‰Z%>˜šõn0dô¾„#ÈðxÛ´¼Zç-|ìÞ—˜Û{["Àò3¼Ñl®|žˆàðDhð´`êÁÿ ñÁu¬*†àýn@ßÞÕ–]·2ܾ+cÈCaµm[”JÖ1Ü¿ìßÜõeS£¶Zû7{ùªìÇü„tg(&2ˆþs–@n(+1þHÖM+T€êºÞîXøZî\5â}mw¤ÿ‚õ¿ß"» å"ùoN4ÌDj†:v¥D|ä¡ÿ[]qpÕ!Œ`cZ+@=æ‘"|Ò5c‡ËüéåÉS4_LØíÛ[;!ÎÝ´²ÇöÁ#| 'àç‘h­šzä*YGùi8 ;¢]r—ÿsH.€m6‚äÅ%§|”œÍŒXIS9¡¦0H9 ˆIÍDKÞJîÍC'[%ÀÉgt“ˉDSà¿O^]_^?ÿ´ÏUÓ7ó^\IÿyA}Pì_7=˧+´«4€RÀ{—‘~@ÿä†*–Œ @aÛÞ”BÞoð¥`=D JØYKýäD z¼¡È€âÓI‚G>Eù6Tz¦˜«¡ëAÊbBÊZKj&TOq#yŸ1‰[v+M•¶ìzÆšÞ±8‘^”ó©ÀÁëpÑQ£L²ô$Y$xQþ:Ñ]»î„S+_@*&.`W'…,œ¹b»üÄÝ~i›ÛÖìv¶ýNòÊP5ØÏ°I–¾TƒÅ¨1 ô‘ÞBסD%ì8Rt²’0ÿz'ÿ4ØbY–|M°…_2oÅÄ‘3Æeíê•ô¶¿Ha‹t„2ÓÈø4—±çÐ+_5œp¤Wþt&÷}IÓ=>ôÉÛ=¦5ž­†æÒ•§Ó LãS§ûß§ˆ•¹P§‚<ÊÀ)J‚ðË/G¯¾j½+¨T}©†ø¥Šý'˜úàd²½ššlÿÃÑÖ 5ƒQ¾Á!L/¸VSJ”§à;œü(à ÎYG¤†éð¸.˜¿p=Œ$ʼnÛ5Ì|1Ôi âù99Æýøz±1±m1› úèø23êqÇ]ôä¨ó3Ê"ó»} d‹-^ºU†Eê&  M@°O@°Ý·Ö€1ŽŽrp¢öªÞ}%U -™Óhmv˜G-œcþÕ7t'ò¹±!þ"XN­>ò¦œ ¨iÄh:áÉb¢\¹9#JÒé9#J•\I6ЯïQN”Èòh4CMÀõ°—Uù0% ùÒV\8zÞóãp%m6%(dÈ £b”Ž@[3Í[ë«o6=Ÿ ¼/Ýôð¾a?R2.P+3 +hv„p° 6µ6¼öCßÛŒ¹ ^7®€ÚÁ h‡fÁ¦´2Èá;gTÿl°òõš%˵¶Tmy#­#;ÔÅgJk)UÌ×ù—Æœ˜ÿùϘgäWí訣Û{Q”¡Êá#¬Ì”§GDÐ üðYó -endstream -endobj -1561 0 obj << -/Type /Page -/Contents 1562 0 R -/Resources 1560 0 R -/MediaBox [0 0 612 792] -/Parent 1564 0 R ->> endobj -1563 0 obj << -/D [1561 0 R /XYZ 72 720 null] ->> endobj -694 0 obj << -/D [1561 0 R /XYZ 72 462.093 null] ->> endobj -1560 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R /F15 1136 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1567 0 obj << -/Length 2096 -/Filter /FlateDecode ->> -stream -xÚ]“Û6î}…®/'ObEõÙ·^¼Ùn'»éÕîÜ\Òºñ¿?€%ÚQ3í½ˆ‚ €€|ç“ã;w7þŸŒÿÚݼz#|'÷ò$LœÝÁIC' |Ï©³Û;Üí ëÓj‡±ûÐîËÙà]Y+‚~iÇ¡lùð›ûøe/Ÿ*õ’ÈH½EjƒÄDü~õq÷Ó«7™µ¹ï¬ÃÌËò€ö~³Ê„Ûv«µÂ}¿Ù¼Ûâä -2/sâº?¬Öa"Üó*LÝv$D5«0sÕ!¹’¨ÆB‡cÙNˆ‹Ëeð, zîÞˆ’ÅPþ°¢‰ºÕ«öŒ¶­ÛÓщ8QcË[–ù\G£söê󨚂Ù_<¬‰LZ÷u[ײÙO¼<ŽÉoµùÑFZ£ 4zIxÓâZÀmõDz.«Š 'Í«ˆ£ÚNíi·ÄQ«†“¿"zàÂ|ÇT?ˆV -ÜŠ—¶Þå(E¶êˆ›ýHk©†#+J„32âÍ!£ìø0c_6Ÿ<ûÆ…uá±?/CD/C ›åì4šÎ&ˆLÀÓXVÃZ[x7 2kÉz#O?žˆÐvÃK¼ŠÄ¸ L¶'¾R€k‰êœY²±­ÖH­•vü=mô„Nv&¸Gë©Jo€Î —K—&î-ñ´%’J='& ôе5I¡# ­WEÛìew&ô,'<¨ÀxèˆÈ:Ĭ­ñS¤¼x¸Ì -챚¯õ–Î÷ê‘ -¾„Hoe? ¹?…ê™Q_*¹A©/ëSÅ‹ÐWoµµ¿#¬*dӀ϶,÷Iû´"d„ :àþZ¥÷[íF´ÝVÔNLÖÑöd}¥%†`øÂèψ½`[rÈÄ•û}§ŠlíFv×X;è+J¼ˆ_ÑÔœ‰¼Õ: -rLœœ`R+ÿ’ÖX!»5"cÏZ=+1í·U<5™G1XáÐ?ª/å^e-1;9j&´«j*ÙÎÏ'ßEÃw` -Y d¹1ð\¤µ ÒÉ=E×qŽ’Ån eo´÷±ýèäç4UH}v}ûˆ¿ß¾~÷øæþn1[ -Ï£I}&ræ$Ó:’ð£ú"g«„ÖM_psì¤S¶ÐJ¼DèèÁEƒF¡»3áÖËšÏOÍœ$ÒYöÒK’Ø/I˜¦væ@´ƒ /;íÉ)‹Bàõä€X`˜p<´UÅîŽʼO&W,i¸pMŸޱi‰úønG€ýÂ:6&¬š¥{ûc…áUô FSã;Óœàé+‹^m$Á¾c50k!ù=$“ÅØýƒJ—ðªv¡—%\•DTQ øHÀæ¬ Vè; ÁŒ ¾·LL— L&é`(7ÕË'Üö«îvwóù&Ðw'ˆc/ÌC'Ê/ˆ§¨o>|ô=L‚M<‘gγf­á^$WÎöæßWB"(Â"xt£,û–ßISö!‹åe;Aê…A¡™Â$ö²dgä\dþgøåy¼¼ûº*\¾ÐkÖ!ÜhÑtˆ( ÜGL«lowÐã†y,›JÂS¬"¢+ -Õ ²lŒÉr‹94û`Ô’£õ\>%ÖGèï\àîˆÔJ êHB€/;ÊtùEÙí ží©>e¡…ÄSa`dy - t½˜¨¦õ"¿RŠ×Ó^€_£+¶T`­9µ=€4ù¤)€?wí§NÖµêþÙ/é𠵸QrÅ)ñ`‰e5G[¯N²ƒ·­:c½¯«„K§ŽâÄ‹ýüïûãB\€ˆðÛ"®ãâ/õL"^(Ø5ïS‹q[ô3¿6aàûÐ÷hÚ kÆ0= `=òˆRN`Û†Â3­Ñ”y‘éíÔ½>JÜXu¼É zÄR°\ÊE®§"É´b†[è­K÷¹¡Îfâ&Ç[é–zuAù jè¥NÒi¯ÇwskÈÓÞ¤¸å¦0$Ñ;Ýbµº×Q6Ÿá\º2'5“˜k&á¢ÏA'¢º^—õù\UмdI4PEq±G­sBË"²Ð#5ò-‹æR ߪ„áF™‹×Ø~`„^R¿~`‘jX„%-¸¬Abû¡¨Â® -©­é$_ZL Fzy@ ÖÈÅ‚,±8ÀfŒ½…²4H­láœSE†‰¢ÿ~ñ©»Š»+Ϙbè:|þÖŠ-RÕð—RÜšË'ke¾>- ع{žkÌÅO?Ì˦’Póí ÐÅ鼘Öu®3ì-‡±c2W½¸5>5s9”ÀñÂLÑ|Ývrv`Yö_€)å uáŸÿ<àªIÐ5œª²?šß -“KŠh.Þèôö6–—’Œ·ôÓçW~Í!ïZÞ—‡üû¨ÚX@P_ŒC—(vOÔþܪ&Î=ÿ©¨&×wˆüÔ ¯Ô±+^ÝXÿ6`ªQF¬nYW{¨NÃÚL— Dª÷sýŠšND¨XYl’´ŸiÞÕ‹•ìú,;DÎØ|âø 7@ÓS줉x9°«¢F:ªŽã––ëº'0%KÙΛøÕ"› ^±”@ˆ£¶:×$KÜÿêì>.Áü¹ò­¶Ùÿ>ÙEÿlÈÙ¾‚"†ËžæÛ€Ù‰›]ÐçË4xºÑºÞĵºA.Ë\ˆÚ ˆ&\¶þÜrøW-ÇÂY­D˜$rÉVºPûv’^ö ÷ Û¹ÑM¶yÿæã2%†aîùA›çžð9çÙÅ -¨èþg#Õª -endstream -endobj -1566 0 obj << -/Type /Page -/Contents 1567 0 R -/Resources 1565 0 R -/MediaBox [0 0 612 792] -/Parent 1564 0 R ->> endobj -1568 0 obj << -/D [1566 0 R /XYZ 72 720 null] ->> endobj -698 0 obj << -/D [1566 0 R /XYZ 72 531.768 null] ->> endobj -702 0 obj << -/D [1566 0 R /XYZ 72 130.231 null] ->> endobj -1565 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R /F15 1136 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1571 0 obj << -/Length 2010 -/Filter /FlateDecode ->> -stream -xÚÉvÛFò®¯@NÆÒˆÜ2–ì(/‘‘~“Øñš"ž±0X,ëïS[7AššÄsaWWWWU×úνã;¯/ü'Ö¿.X}'p‚8öÂ,tÒ óV~àÍÅ»÷¾SÂáOŽïEÙÊy ÒÆ‰üÀSApí¬/~;a¢²ÀITè*ü_L|'M=•‹S½þ³¹xñ*ˆ õ VÎfë„Iì­âÀI}Eë¦tÞ¹ÿ]¾r¸»¹¾y½x¿ùéÅ«•“yY&xeøÑ.ÃÀ˂߹ìKîM72°¾Ú00n?V]ËðÔÖzüã"\¹ÝÄ›¼× ºóª5Lrá[€ /…Ê ÇFUáËÔŠcVkص.ª?ý@éˆWÊÍ˲gé°i´D&¼]_Þ®Œ\Ð LÝQ÷Û¼Sbš¦Eޝ¼År•¥îu»<§Çá~”(%÷ùˆ_­Üb±ƒµh´ih²б¦Müµïîû¼itÿípN‡_rb7åõbE‘›ãÃ>-âÄÍ«:ÿPkFzŸ÷ù¨ëÇ<ßCNW›Y<ª8ñb?ûúxü2/ú©èkòâlPGþ,@Sà ¡¹Š$4¯[°~^ŒÕ'xaÆh¨fq¾ï~ϸ5/KÙé‘K0Ä‹MÕÈÍõ˜7{cÛ0‚ðg/»¦ÉÛ’‰~w1ôr—£`Ý‹ïÖt7]y -œr䜫–=€djZ1Zü™HÊUÞ±ÔxKÃ}¦Þ¥ÞæS=Ú·U{ÎNR+Kx•_¦»=çs[òpóPÕ5ó´6¹)’± h‚•ñ‘©ö¿D8|Ozš'9qâEß§¡Mà]76†ßýéÇþ%ü"ÏØ5bõøÞD퓱cc\œDf"KŒðR²„Áº¨y£?WÃx¸†æ0%œHK‰È\k¢nö½qz¯Ç©o£ „ß3‰±W袩-¤O›Ýb™Ä¾¤êp&™:„‚½tB\jý ·Ø‘:/ -pj] ;-W>ÈóñTYîHÌ<8#¬žÕoåeaÆú½‘veóØËBn8ˆE{!B6á\!Û’±Ãã0ê†)K-m“ËOçŒ!twÝTËíVnô|ÔjÃvì„ã‘ÔiEÓ¡¹íä"Œà+yOÞ¹ìý±CqRW¤S PnµEu“ÙØ›²ãõ<ÀÐ(˜Év¦Ä%n5 -ëÆsÀ%J &Èf'÷yLIŒ[“ÄÄR®>QÅ’CÐ`,&¡ûUáɨ åãŒ>°w€(†&2|$~%oɤ„ÇE¹?B‚•048ÞŽHsj~ =—zü ›‚¢¦'äJ¦­äºûçƒ/…ÍÜp® dŸýüÜûfö ?9#â`–x€¥ì°¥âºíêÚÄHJFA¬Í8€s^Žì‚ÌÅ.ðp•Å4õ"ÙÍ톦öcÛ¡ˆ‡–%)ŠH;?\ë|t·‡dÀ-ÿŠ%' d¥æåÄ Ã "-‡fÞj%ƒC–]m.þîhú -endstream -endobj -1570 0 obj << -/Type /Page -/Contents 1571 0 R -/Resources 1569 0 R -/MediaBox [0 0 612 792] -/Parent 1564 0 R ->> endobj -1572 0 obj << -/D [1570 0 R /XYZ 72 720 null] ->> endobj -706 0 obj << -/D [1570 0 R /XYZ 72 372.584 null] ->> endobj -710 0 obj << -/D [1570 0 R /XYZ 72 183.554 null] ->> endobj -714 0 obj << -/D [1570 0 R /XYZ 72 155.811 null] ->> endobj -1569 0 obj << -/Font << /F15 1136 0 R /F8 826 0 R /F30 1094 0 R /F28 879 0 R /F16 823 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1578 0 obj << -/Length 2687 -/Filter /FlateDecode ->> -stream -xÚ•ËrÛ8òž¯Ðm¨-‹æS¤ææ‰ãL¶Êvjì­]'“$B+¡%À$ž¯ß~"eíÎìEF£ß E³çY4{ÿ&’ñ—Ç7—7ål®–Érö¸ɬˆ£0J‹Ùc5û83_diTµ=4jž”Á âÀÕ{ÍKÖ©ýÁ2t;Óñ\« âïë÷(ÎÍ+uË0Å÷yžª«µèGÙò¸5Ý^9ÎEº >ýëšÁÕN+üÆãAQp­œÎT[1 ·B»3ûù—Ç¿ƒ(q®òœ/ÛðVó0¤»‹ù"-òàcr}ÿ€óeÁäpò±éÿöqNh[½q |x±Nïç‹8°?1äÚØëÚ~åË´qº×ngè˜ -ï˜gyð¡å¥Oo?þ–Ê$E4­ðâvš—þ¹Óº9w‰5 Ó!ZšµÅ1 z«+ž¡fq¨Ö èM0­ÙkÆØöíÆÕ¦µ¼ „„âÁêMßÕN$C§7ªÇü]ËØé½ñ|¨ÍF[!dR -‡”á*Yñ HÙi"Ì'¸ÙÕ`,ËôS1h-&ƒsÝâ‡Ó]Ý>ËF';[E—BŽG`’C,ìY£ ^Ãìåœ,EÏ€¿W£“ÖlŒ¿5McP ßÉ Î0f(Õ0~ÕÁ%üöŒN8£>PøQšòÅ 75šöFy•Àé0+³vФ0ºLªôáL÷ŸèP8ªÖJÇ+Ð;±S²ËÈ©ÇóU§˜fVÁÇ £0p½±ÂŠE•^,åH,€<ˆ0X•]mz{NÕÖ@ä­yð}W -ŒÆiŠ4¢K„q°õ¶ºäP”ƒŽÅ4x` G˜ÑîqŒ+ÓCN¶ -žæ%h°g”ý1æƒÔé4¦µ†(¶eȯº9È&°xõ¬'w\òm¿ßƒþ`‹MÑLì óª~\°·b`á Ø1+ù`wNÄi`â½ÏŠwâÑxÚJucxiá¼·¯Y©±±¶h#£ó*m7]-ŽP GžÑユ(‚KobXŒfÝóŒ'¿½3ûLœÅá’|b‚}hsáB? ÃËdÔ¼}h[SPúyBЗ7i4ÊwÀkR†å*…œ<ɃÏà=?ù¬¶í\~ù,ÿ‚„§iÓ“I˜Ìôµ8eÄ s -€jâæßk·ãÕÖ0DuÏý^l”}¼¤h K“4‡#G˜¶$«™ ç@9ÓBİÛÖ/,®Á úºq ²U¹U}ã„CÓVµ×3qÙ4~{÷=‡ìu¡îqÇy˜€ßd¹ôgYüÅ\‚*®@b8Ðy¦Í6/ eÿWí3ÊëÑ~äÄq¡©[9qjÁBMŠùbùûDì'†ørÒ™ ³î’Rq!âÓÛ»$ñžá›Þ:³¯ÿPœ©±©}ƒ[ ÓRVÃ¥UÀŽ6xA!^›¬v<ñâFÿYèmßiÞívJ@»áÛûÛ‹Ñ×Ñ#V mÅóÁYpã+&dkƒºÒôlÄÛL)¢²ê4yå“xßI±€JC¾n$gp‘:ø ›:-U»X–¯! åû<ãS,d8ÔôŸg¹,,_g9J&ÉI6I“°”, áâ ç‘x\ì<5(U{>#åaºL™ÈýAâÐr%>Eƒ_‘ºØ*kë8.Ü!²¡8Š€Žn(u $TvPÉ©¡ø£ÍÇàN6úú aV7`ÍÖá«ÆKqyÂ\Ò¬ÑlÈnÌßYóÀÚ}Ä~½ ‰Ù“a Ma€q/L»\Âlá_ðA€®ÞôêxµÕºâHI$J|uÆsÉ[""†±aµW•T"Ŭ©æ°S²Gª³žé*oâuë#¨ïá†*\‚05nÄÿªå…±ØÞéÃMÜÔ\_䘷ӄäó+œ;‡¶Wê~m˜q À ‘”JT„DÃ%b¶ÕP}šºbЦéÝÐàÊ"V“XŸ¼&Ä¿»"Ú -â Àü’Ì{ü+-`ì”äy6¡|é´åó(“½t –¢a±j÷¨ïùŒ ý“^Õ±«çØc0Èa=ðmü1 Ÿ3ú™8Ö©Rä±õáûç;Ç+é ÇÚ_Šó esZ؆'„ -“ê/×T¾žÇ¿ä¿ -.Z¸–BÀÍ|B 'º×EÔ2Ë,óE;`‘ù?ŘªLu-® §üãa8vÏ3ðOŽ“ÂëDM··—××—OOØO&Ü[¬Òà]ßéFñÿ1=BÚ2äú:¼½3 ŸžB†> endobj -1573 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.873 616.444 120.596 627.292] -/Subtype /Link -/A << /S /GoTo /D (subsection.1.6) >> ->> endobj -1574 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [442.984 486.93 457.707 497.778] -/Subtype /Link -/A << /S /GoTo /D (subsection.4.8) >> ->> endobj -1575 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [136.52 347.453 145.293 359.408] -/Subtype /Link -/A << /S /GoTo /D (appendix.E) >> ->> endobj -1579 0 obj << -/D [1577 0 R /XYZ 72 720 null] ->> endobj -718 0 obj << -/D [1577 0 R /XYZ 72 473.985 null] ->> endobj -722 0 obj << -/D [1577 0 R /XYZ 72 391.842 null] ->> endobj -726 0 obj << -/D [1577 0 R /XYZ 72 170.678 null] ->> endobj -1576 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1582 0 obj << -/Length 2052 -/Filter /FlateDecode ->> -stream -xÚíÉrãÆõ>_Á[Àª!„n¬ÔM‘,Ï85#•E;©±}h‘-5 @£A;ò×çmE¤ÆUÉͼðõë×oß-ö‹hñí›è ÿß¼¹¸£Å:\g:[lž¹^ä* -£8_lv‹Ÿ‚OÿºY®T”FÁ¶]®R*Œ–«XJåŒy°'¹Z…«ô2‰/â—Íw k¥T¸NSfz[V¶6GnžOBþPþa—+“Í®|*íN„|%ñŒ˜•üX7è9ãèù@B²þÌ‹ï?¾ßܼÿž_‡×wàŠ¢ ù,|¢ü2R«h}¡ò òTš§Á§û«Í;¿ð(†G3r)H¤Ýè}Ñ¿/&Bñ=D8É”0ɘɵ¾ôfóÌèÇ஬÷éì ü "bÈé¶µ0 -¥\Ü£ÄZy™º‹µb™ßœÛ‚ª‹ÀšbÇÁí²ˆƒ¦=^"‹W û"[#a§ÿ7ɪþJÖWɪò0Z‡2YûGc¹Ù×'ëäý$YÓÿ[²êÙluXdkš„ ‚A”Bÿß”ÎkÔZ¾ú9RI%°øDæ†n á®Ã™`G³aN$ÌwçîtF/$ip “59X³++ q#AñÞ˜³Ò…ŒàÆO‚/ª!âZ¸ß×ÐU…Æ´v:,*­§£ævJòÓ*ß<ØZ’Ñ0/˜> NŸÑÉÚ/»Ät>—*lìYrÄ>»“ *]NÕXE.Xw6ZzÛ»9M74÷{Ÿçïš¶üC²ÆT?âµm»rëƒð¢^’^×´/AÔºd8Û¡Ò˜K#ŸTFú¢2À×ßD«à“K\ôº"RÇ}AÜùȲàÿò—u˜>_€ˆrpìP@Œ*#ÄF›@ã¤b "êG@Õ`=n_þ†)jk¬ì„?ß EËɼ閣g!»¦}æ£ø óÏ1‡Y1>‘â¹o† µ½Ü'¼³]C‘Í}Ÿb˜‹xL -&ƒª\_lu–@éx¹½­{ܨë,“ nº¹ñL)óÛ2…iRV<ß0SÊzR'Ÿ®ï¿%Ÿž]g¾EXß”!VRÑl·Ö9FŒT1ŠO+ö­ë$GqžŽ˜=RJw"ÅÏœ;˜ O^ ¹úú&ŸI*?@|q&*àOšà0Lâ–‹˜ ÝÂjv®åç¡Jô¤å'Ñz¥‰Š(—}®”± Ç'’­HР†'T]pÆI×:y-|àúÑo€½åÍ Ôþ­ïú¬×$§»ƒ÷ùã¨Mð{Än{pÙ¥ŒUhÝÜ9ùqzãì•n~7á¾os͵ÎOènhù¿žm½µÿ%pÓ”KÜ Ý Vb’ñöЙãi&0™5|ÓF£4‰²àÉšîŒÃN¸?1ÖT{h¯ÝáÈG|>:–U%ô8€±u`:ªàxêÏáÊ(\´’ÜÔ–/im„Cw€g[èØ$Ñq¤qÐmEμ`{/6%æ(Ét!¡TŠ‹ ¾«ú™ hTÔ­H]ˆTù¹ ¤Ã¾WäCj -Ã΢Ñ‘ïÕ LqÔ;öñ2ô„S7%¬x‡ÜÒ¾*¬æzD‘lF; ÐÝ‹d¹k—ìÆ¼['Á{AvšÍ=AsØæS^åÈ~ƒJ÷Þ45ø?šˆ`7â®ß8X÷?Ësïh¤h›#C.î¯W7w|„®û¹[Ï~òQz˜ªÂôÙMIœ‰J–Rî3_qg€»{Mˆ|êD9nÐFÙKðrÃ~B ¼5gªEb7" -ɇ€¨©D/7Ö9Ö|Tò‘öÿ“qÎîÞÎÞá˜7‡’r\µ¤™$Ð- )蛽l0¯Õ£fò²]%ìèW*ØOÇEíkÑà…ÝW·žBZÏpùÁ€®ZkÜLó‰ãP­'CAôA×µåã™ãQÊõLqüçof¸÷ÐUyƒ³¦õý ÏFÐàÊJD±Št *BVêuØãÀèþKPt„k{n[ÙgPf ŸÎ¬¢4 uÆŸ#Z¾T°ÿ>Uå¶ì‰! <Íu/?Ö¾GÑW9~¿ñäÐÒð^ØûI¢½ù¬À¸— LøP -½aò #Ü -•çê‘¥XÁ¤Sß}G4ÿ±¬%?µŸ]ŠÔ„³ÿšÝ\]1‚-pžŽt‚k\Çj0éÏŽÉxÞöD -m¡ïO>‘=o™d¼_ÂqØÌ”¬}€¬›zų¥É‹rAþÄiRø%ÃB]7Z2ñu-oyÄïõZ‰Ï§âüZ `¯<À~­Ðo‚øÆ¯•Y!kåXà°VÎXÉKfñzÉDÇÎ,š²LC«˜Y4‡O5­³0…²JסÿšS‘š}³yóæêõ› -endstream -endobj -1581 0 obj << -/Type /Page -/Contents 1582 0 R -/Resources 1580 0 R -/MediaBox [0 0 612 792] -/Parent 1564 0 R ->> endobj -1583 0 obj << -/D [1581 0 R /XYZ 72 720 null] ->> endobj -730 0 obj << -/D [1581 0 R /XYZ 72 516.548 null] ->> endobj -734 0 obj << -/D [1581 0 R /XYZ 72 472 null] ->> endobj -738 0 obj << -/D [1581 0 R /XYZ 72 377.804 null] ->> endobj -742 0 obj << -/D [1581 0 R /XYZ 72 321.024 null] ->> endobj -746 0 obj << -/D [1581 0 R /XYZ 72 276.753 null] ->> endobj -750 0 obj << -/D [1581 0 R /XYZ 72 196.062 null] ->> endobj -1580 0 obj << -/Font << /F30 1094 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1586 0 obj << -/Length 752 -/Filter /FlateDecode ->> -stream -xÚmU[oÚ0~﯈öäHKb;v.ì©…±i‰Lݺî!%¬BŒâ¬ûõ;¾@ÂKN>Ÿó}çæ€ƒU€ƒ/7Ø?瀞dL‹ ŒËŒfAµ räÇ8̓ª ~#Ó¸ #B8F÷²aÄ8C#©w›:L)Ú‡ªoÉø”…Ðâ@Âr<ü…QZr¤ÚÍÞY‰ ªCš£½v`¿Æ`葤ì{ (A½C&*Œha˜0Ñ|p£ºI%·Â½Îûz»‹Ã(£%ªÖÒ³nA£@^÷ÉÒx™ND&õ òéB‰qɹKúÅD‰N‹œ9HÏv½Û9ž¶‘íÊ`Ø'‡÷î¡v½T­?S;ú Õv[·žù»lÅGcrôº– £³v'+ÑŠjÔ^Ö±¹X¥?ØlÜ‘mçKÈ3TËMý´ñ~¶1:¶Åâó2§v$”—¶™ÖÑ•Ö9tmÆ`Œ]§Lf/RCY[*ïe0F¿îˆÒ #í¹]õJ9»“B2 Íèh:÷Ð*`ïkyàVÇĆ€øÆ+µÞ¸ØˆkµÙ ´i-+Lkm;XæÇÀ8Ò0½8™'³ad²G.{cÖ‹…Ðví.0³¨ú»Z»—‘Òpž‹Ù¯ Ý»×…ê:¡]GUÛh®ÜÓ¬ùåbÃú²‚ Ûkõ4îÊù=LS´0Iup„1\“ þ*ûµ³zw À:îcÊÔÃü žÉ8Å'·äáb%uòch`[oE\í¡"‚aßæòŸ6åoSbc·ZÀ¿õÝKÍçc¢¹”×§ùŸ ³†Õp˜Õ8zX3gk[#Ï»$.Ññpºõfñì¥H> Y„³„Ф(<ˆ‹£.JÞÀ ÏS©ÌI §³_oR“wR|€ LHnYKö¼RÀÃì¶ú -<ç§´ì@‹óÇ'´G-z ^x^Ó2ŸmÛ÷k@[0¾,À€äŒôd·Nÿ (Íb<Ç$æ¬tŠÓ³˜ÏÕÍ?f¡ž -endstream -endobj -1585 0 obj << -/Type /Page -/Contents 1586 0 R -/Resources 1584 0 R -/MediaBox [0 0 612 792] -/Parent 1564 0 R ->> endobj -1587 0 obj << -/D [1585 0 R /XYZ 72 720 null] ->> endobj -754 0 obj << -/D [1585 0 R /XYZ 72 720 null] ->> endobj -1584 0 obj << -/Font << /F28 879 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1590 0 obj << -/Length 130 -/Filter /FlateDecode ->> -stream -xÚ3PHW0Ppç2€ÒN!\ún -–z–fFf -!i -æF -æ†zÆæ -!) -Ñ!™ÅšºÆÆÆ‰é© –‰L$3OÓÈB£$Beæç%æäTB”䤦•@%å$æekƆxÁíT022Ó35²PÐ53¶@Ødh`Œ¢Ì5„ g)n -endstream -endobj -1589 0 obj << -/Type /Page -/Contents 1590 0 R -/Resources 1588 0 R -/MediaBox [0 0 612 792] -/Parent 1592 0 R ->> endobj -1591 0 obj << -/D [1589 0 R /XYZ 72 720 null] ->> endobj -1588 0 obj << -/Font << /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1595 0 obj << -/Length 2026 -/Filter /FlateDecode ->> -stream -xÚµšMs7Çïù{èaÝ™éÑûCB’†M(IéL¡“,àÁ±éÚž–oßG+É^[Þ8**Œ½»B¿ÿó¦GZZ}ªhõÓ Ÿ§·GÏ.˜ª˜ \(¨n?V*Í(¡\W·÷Õ»údtÌÈú›³ë›Ñ1ײ¾YQ¯fwËÉ|¶ð?ýºšÜ8«¿ø¯ošMÛÌîšÑŸ·?¯ÿ·øy~{ô×ÃÒŠU ÿ3n+e,Æ«»‡£wÒê¯ý\¹+¦ú»»ó¡â–÷Ü´º9úuÏZ*ÍccàÝŒX)Ã?˜Ê«@9|ÆáJã|(QBz ®V#õ„ƒºiQ ÔÉ ¢ xňz6~hFÇ  Ô/g_WK÷+¯_»gÇ-^[6-êÔhTh¹jgͽ¿å­j<]5‹N°-$eD±ÿ·GEŒ´ß§±DS™«ñ^‰•!`™—˜ŽŽ…áº>£@¦ž£v†«¯P[V£ªFKî¾5à -eO-¥“@´°Eè$~råéX {3Ÿ" ç<ºˆ`v0Ož¿øŒs‡þ2L›=Õ”VP¢­(B+0ƒ˜`KØG{½Zúˆtõóà±*™ÒËaØì™¦°`ˆáeL˦åöM3¾w4}Ë -ÞeûfE;ï0…ÔZ7{¶)0ÎÖ˜2ÖJ„Öø5¦¾†êçûZÐõ9Bî˜X2qötSb*ˆ…2&¦†HÒ¿ į&‹å6¬¤T$Î|4{š ©´@¬.b[i‘Á—U=›´Í]@í±¨_>»FÏ5ÜAÓ‹‹Kÿë{*éËþíÒœU ùcùsLeù4© †ÊÌ÷ÚMgcQ4˜Þaž_zmLäÆxîg¸›åx¹.àùSL)•%Tñ"”ˆêAžíƒ4’îØÒå­Ï.ƒu&uß1kölS`© £e̪pAg7Äô’záØ‹ž_#Ûjéñ™¡ö@(çÏ/E’0É‹„²0¸$ð„:„òOM0]ºóô›3œ Ûµiç†è ø‡_v‚ ŠMŠÀ9aÖ+¢MPÁnvTàõ©óÝoK¿èx“¯Y;"HIù!ÈžzJ¸èe\1X[:z+u;™9G_Æ<…ß?¹¦1ÕwØ'÷÷m³Xxôxpq~>{æ)<ÅÆÏè"𠈉À\GÁÃÂlO);]½§ŒûfNIÔ¡/ï]ìçÉÍÈ€ÆÀvŠÈ@)±,øcA†u"ØR!Ô¬c¦ ßNŽ·»ÿ¹ÿ¸šû'üšïPIÏÇI1’pý]Ž v³‡2ø[p Dc}4Ñ­PˆË¢þŠЄ`dËžXʦ9vE¬-ܾֆ]k¿¡a›vá÷(œWïC×f¯÷2¶Lø™X/ ùœ©TŠ¡Šä¡$¡X¨¼T|Q¬³ÉâKˆ‹o‹eóàöj ÄE ˆ~$?ú_¢\'Ãzdäz‹  É ÅçBX„õ<_‰§eO'%âšHlAJXX0ÂD´°¾i¦ëvÆ›Xr‹ÿùÆÞ©‡k¦6ÖÁÚ¼gí‹Étx/*Ÿ)•$ö!¬ˆ¡Áf3ôã0Ù3Ia'J”±1Óx´± 6¾þêM7ëçXk÷­pæÃ]Ýòß-µÒ(Œï{çí·X)»1ïQ&+UÆdYe¨$¸X ʨ Ì‹é|Ñl©b%ë/‰( I6O" 7–h^ÄY0Î Çä%Ñë„0nû{Wçm ƒ¶Ûâ þ?…òñR…°èkSÄi\ŽpŸ^!sH¡«æŸN ªƒ@\¨‘릶t*\ù©NXñ 9­àÊt‹ “ :aiYnG—°êɾsÞ¶óöÉzdäz`Å/Ókq©‰Ám íµnš¿Va!=Oñ7¦õ€,«è(‹«ºn˜g¿»Uh;‰ê>AŸ\¸T\>XVÆ]„$¸>úÄ& ™ÄšI$"M:ÑábEêEê¶5uʦL…G\D'ΉÑbûòËø‹£möó§&å./¹´”—srÁRi˜Á~¬Œ#2¦_ñÇÌe„ÿWÊɆIõ Š’ƒZ¢â‰*ˆÝN÷ÕüÓdæ™ßº¨èŠ *Äîup—¯ž¯ïŒíqwç ¹‰`öYENkÀj¢Öç¬2ÙÛYµm³Ùë¡Ý©åÎAäªídæ2o¿5R!Ÿ!•ÁaeN`ÁH¢ã ,¨õ¢%’ürúÖZ¸ÙsEòC»œùOÙ5ŬŒ hNt<Œ½ë'Ó©ë»°¥µ&íÎ3¶#Á]Û}ìɑϔÊ" 6¨e\B1bâ‰-˜ý÷u;_îl0 6ÝádΞpÊ,vie\AXbbØ]OxÏ2úé3Ævœ`ß}ƒüÙ“Où¹ œ•±9×ÄÆ£ZNwÓ€¯Ž~ÿÊ¥¹e;ù°Z6Ý+X®%Ö•lw†ŸU)ó©RaªÈ1€$ñ¬“''g¯O½ÁwÛ7ÀVyO†HÖën€A!²)R!ðCÐ"§À8±k%`ã!ÏÖjü¶hÚÞêY;+c®PŸovÊÜf7>Îŵrç⛯V(ãƒó±ÝÆóù‰˜5Ø~ycPÏÅ#TØô_µ›3ò›¨Cwrðx¾ÌŸç^T"ç­Å­×[·˜q, ƽä ÅÖªˆð/æH|8 -endstream -endobj -1594 0 obj << -/Type /Page -/Contents 1595 0 R -/Resources 1593 0 R -/MediaBox [0 0 612 792] -/Parent 1592 0 R ->> endobj -1596 0 obj << -/D [1594 0 R /XYZ 72 720 null] ->> endobj -758 0 obj << -/D [1594 0 R /XYZ 72 720 null] ->> endobj -1593 0 obj << -/Font << /F16 823 0 R /F28 879 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1599 0 obj << -/Length 1747 -/Filter /FlateDecode ->> -stream -xÚ­YÛnÛF}÷W}(( Zïîìµ€l˪ÄI-˃b1P]\JJ›~}gÉ¡"‹”äµøÉÜåfΙ˙ñäk“_ÏøžÏ¿Ï~òD$Þ1§|b…gŽ‹ä~vöáOƸö2á ¼Kþ)vÎ%Þ›&óßÎà–e»óZÓ—wgçéϼ‘&¹û’®˜“íL$wãäCúz=ë€L?wºøo–wºBrž:Þ¤ëùýj²˜ãŠSé|4Ë:]é¹K›?¬Wá)¤oû£×VY¾Ä—µçé»lµÎçÙ¸ÜòG8j4ŵt-;Ÿî^ž]ßmÔ˜ÐâIRÊžD´ñšI±D7ñl‘֗<tº -À";£À @ún4/føXH™ö¯{ãqž-—aQ¥‹/å¦AGºôê2øÅòô¢^?ÿ³ƒÉ'«¬Ü{µ@ÏØtœíg7V ´ÂŒ3ÌKEÌ(bfUEx!vèmz,Ñcü=°9JzÜaz¢±Õ鱂“­Ðc>«G=W‹æaL¦ôm8ù/$&À>’Ôv $]çù"zèD«s£=S²Ð1À¸¨BÇ7Ãlõ8§ŠïY(:÷‹| -“'çç7èˆÆR§Ca²í„ŠŒë*Tì¦Æ,+Bn×ÓU‰¶ŸwD:ù&Œu<r;ZþÕéj¯ôQàÑV׃fZ´à™à$bàøëÁžÌ¦Ù,›Ï®PŠö£Š6©ŽJÓ¦wJË„r„ʪ_+g~ÄÈÿ7#ùO‚ç‚g¿”ÙýjQÈ·2HÃ]ì¤ÖéMÈW=tý`B¯b(ЫA±T–¯î§(_"\6Ü´B‘ÐLxr¼âÍÚ‘eàE‰‘óìM§ÔáP-ØS(¥æpHl¨I4ÚaÚ{†¹Ý -a°Ý£˜R¢«Pos…Q™+ñFÕq9ìò|+ =¶±® -½«Y%rÎ6. ©I¯{ƒÁMéÍ\sL/üx€4òXŒPçÀjfÕI¾£™÷ -ò $ùa]ßT¡^À*1¢ÜcúŸcÒ‡Zð€ßK¸aíÚhSëhQ°­;ÉãÒ`x’e€D`¹Ø;¬À¾öß K|Ežm] J°Ñ@­™B-ªò&€WoÏo ŸQÇm\*­³º•”UÀ”!*ólÑŽ7©Ž -•Ö·¢ÙÓœ¼¦ì®f÷o/JÇáµO¤Ô}J%Å•6éÍ«ÞÕ:Ï ú΋UϺŸŽX,u6PT½iÇÇÂ3­+»o†å—Ÿ·{—|Y „ú-½ÍöUØ÷ý¡(äÙ/x*6¬¨áO½÷C$6lÜOP4¼:C·S³¹eÚS¼}„Ð?lì^3_y‰÷݆ýÊkfP -û_õ.¯úÛ­$y2<£%¼l|.n˜Ù3Þ¸:>ÇY+Ý’rÀ -B¾¾ëí¦[Š­R±6ÕA¡ºû˜iV ª¥ÒL—xÁE4Ö£wå'6ÌeBzOr0,æÓïô(¸ó[s4™Ž>Wˆ uÏ£òÏûiÙnÝ‚èš1Îéâ¹Ó‘­7g9“ùr5šN³1+xÝ­>âYHÉðŠ“(P¨á™lÐúÔos~ÎNš¯JWÌU±dRÍòŠEó·3WÑ£¯Ë"X€ÍCc6˜†¥ýP£Íl€jS¼׃µ…JTAP‡u¨Þ¿:”ðºØyȱ•:ä×hC›ÁJî"ŠH“¬ò(²v¯® .w„MpˆV¶ùÖ¥r[ìPÑ0Pªf“ù×rÓŒÊišz¦¦æ ºQzÆÝa’4zܪÆRK‡Ã<¨ÓD $ö"hgUSß®¤IntóO†{äL3öØšù± O$GíNJ]¢˜;&Œ­2W6)U…VyÅ5Ò7M2·~ÒÞº’öâñÀêÜHzŽÓnN0+<š*ŠÀa ;Eé¶ é剂¦ëF,ÞªdØÛÛ‚×¥Ãj¨Måuh¨×ª*GÅüŽ> endobj -1600 0 obj << -/D [1598 0 R /XYZ 72 720 null] ->> endobj -1597 0 obj << -/Font << /F28 879 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1603 0 obj << -/Length 1063 -/Filter /FlateDecode ->> -stream -xÚ­XËrÛ6Ýë+Ø5Ó@x?:“EYU2“ºµ4ÓE’…bÒN%²¥å$þû\)–˜\"¡Ë{Î}8¹Kpòû»ñb=™-ˆLAFš¬oEE0ÂL%ë,ù˜¾AdúŠ*ÒÕÃn·©§¯˜iukÇ‹ùÕÊήóýC]ÚùÛ -F’fùýôóú}÷9?^®'ÿMLqBàÛ Ò0D°Inv“Ÿq’Á»÷ FÌèä[»r—0MÔ0Ý&«É_ϘиqÎvP‰¿N 2’Ê=¡€.5G‚KÁ¼¨ó›}ÕBg¬Guî7x (Nß¼Æxù«}‹I7£vÆSÌ–öQqkÇ?*ûⲞ’´®ê–¥#V¸‘Hó@ -Y‘f#”¤4˜Q ­(^/GJƒä,”(?BB!Ìù‹Lx˜ð^p°6£HŒk$•#ô²¥.”— FXy=' –æ›éÿŠ(Úé7ƒèd|!1‰%'…”ŸWQ´#!–f”¤¤&¼Ø Jù(J"iGèºØå³ùfŸ;15úh¥œ ¨R­ ÈÒ²ê<ûÑN¸…QˆŽ”’0F–½LIñŽ„X´@Œ°!JbÂ{¡bB¡$¡$2Ü1zo²ÙßSÍÒºèôt˜œ(—jprŠ÷>$@Ä1CRBrdŒW”‹ÖRÑ ˜-(;ø|W(ÆÛõ¿ØG¼2Du·à²Ì¬¹Ê tÜÛü47ÑÀBn¸AœëQ¸ ÚB'Ž^!-T!…ÉOÓò¤½Z4–¶ÛÓ¬DC -Ya -q3Žb8AXõ’¡N2óâþ¿ËšŸíMˆ -$Ø8Û #ïùÞõí¶ºÏ}ÛÚu+Eé"dSfÕξ¾Îoª:ë#gv$–ç)ˆö?¤T%4…¢Àb¿§ü0 Xvÿî§ý ˜§õC]”wŽŒŽsšŽh,!KTBˆ’^¢“øAàè<††ŸF4€ ® ´Ú£HâQÑKC.CìmÃåÎx_Š;»$ëè.ñ€BNdi¢†ô.CLx/¤@JÒ1z. bPl©ý¾ÏË,w¬ä«›£†~0ÉûÞÑc¿ïÛÎ¥œ67YòÛÍÝé‰ruVc5 -'pâePYZNºTí/j,,@i‘ñôƒïî>Å8]ö/g,}7»zryÑþú„¾Ø8ÂWm^€Gä4QÑ(C¢ ôjAF k8"sæÄ³ì«xŸñ¯Êíã'aEûŸ´‘£À‚Ó2׬ƒåkù“®þϺÚÃŽy­/Îõ¤ñÞ…¡¼>ξÐí÷ÍWêweS¿N…H7Û©r^_›Çy¯ØU¾àç…íí³€§w›G´GÀnCòo1,®XÁYÆL -endstream -endobj -1602 0 obj << -/Type /Page -/Contents 1603 0 R -/Resources 1601 0 R -/MediaBox [0 0 612 792] -/Parent 1592 0 R ->> endobj -1604 0 obj << -/D [1602 0 R /XYZ 72 720 null] ->> endobj -762 0 obj << -/D [1602 0 R /XYZ 72 720 null] ->> endobj -1601 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F23 825 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1607 0 obj << -/Length 1439 -/Filter /FlateDecode ->> -stream -xÚ­™MsG†ïüŠÍm9h2=ß“*$@Ž 2à(UŽVe ,véß§gwVhÀ€&Þì×ÐO¿Ý=Ý MšüÞ þórÔøõ -T‚p¡X2ºO4K4PB¹NFÓäSzÙ<`2½ìö‡Í3®ezÕ´"Ý,&ùl¹X—§>lf“&‡ôky8Èî³U¶˜dÍÏ£wΨñoð÷hnye,aÀ“ÉSãÓgšLñü»„nMò½¸ë)TK%~Ÿ'ÃÆ‡çµ&TšcÏã@¬”þñ“™Ä«˜*(5±Ú )”(!KÒÞæ©ÉYúXš­›QêhUE‹WŒHMHÇx5}Êü=ÝÅ?›Ü]äé­[b¼?ey¶rÞËÐùfµÈ¦åóºÇóM¶ÞwЪgÜq‘"FÚÿïb%ˆÆ‹‘.þ‘‡•!ÌBéaÚ<†ëô²ß5ϤÒ&í-èEk¤ÿzØ#Ñ&…D’-lDRÎUIžè®DJÒ¤h›B$A‰¶¢$ùo¼HÌ#µú½¡S ¸ztq~uuÌEÚ½wŸÃ{<}>‚mgˆÉ 1ü§”ãÜjq)Έ`^º‹sJ¯K€D fþ6¢h“B"Àì4µÇ(Ú Ç·Âu{(§<®…õz9ÏJÄÖ#V© ©#˜Ñv†˜®Â°ZRŽ"Á—i±Åìt9J¤­CpgL -v*£ 8¥eherJ«ˆôá)=æM×e!æEÈ›Ù:ß#¬*: ãM  -¦B#ˆ¢^Iåo?öZ˜‰’ ã-n¶MfÒÇ=PšŸ¶4U–PÅëÕŒ(Ï©=ç sÑî ð€Ã«’j13]½)ß–˜ñf†”R µÈ©°²ÓxÌëþûª)¹}ûVoRH$$Y‹nÂàž\Y4ìÜ´‡àö íÕì› ÐÌoØ6â¶îœño*)%h~ß%^ßœ·gë¯å ·î×'–‹\¿ -€‹éô˜öѨ¡§8'`J{š¸”"Úx_uλ‹™¯MÃlžMòìj>~Ào¸ã§Ôï¹Ûæ¡»pžøÖ”{âÙ´<¹uña?Dƒ„~`@˜¨%b˜ w²t-./bf4¸˜ʦ—­óQ‡ÌkGåC ]Ž.Gªb«Âùâx´å!8ÅéËè:ÀSå -À|Øi¹dÚ1–«WÄaª`É?Q¢í p…ÕØ­³:p1¡-T:³-nûý…Û„qîEÜâ Êâlí&@ur{Ž72d4’p]‡¤Â> endobj -1608 0 obj << -/D [1606 0 R /XYZ 72 720 null] ->> endobj -766 0 obj << -/D [1606 0 R /XYZ 72 720 null] ->> endobj -1605 0 obj << -/Font << /F16 823 0 R /F28 879 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1611 0 obj << -/Length 1549 -/Filter /FlateDecode ->> -stream -xÚ­WKsÛF ¾ûWðVª7ûâë˜ØI&zêŽuŠ›-ÒÇ|¨$•Äÿ>À+JŠìZ3:-ˆÅbeðÈàÓ™äõýüìíGÊ -ccÌïƒD‰’Bš$˜Ámx1;WJGáe>–ÃjvnTX.`I¢0o ">VuIÔ͘7+fÎ2v}“ÃìëüÏ·Ó Y¬c¼Eç:Ifé’ùÎ[¥Âu[}›é4,û!¯‰5J«$]ˆ¼±jøÀ=ßàö×CÉw¨ä‰è/7—ß™÷%IÞåÑ®¥u•/ðУ»ž÷Þ_\’|Q=Tã fçq’„ŸGÚýŽ¢ù@E¹¨ -8®¢wJ‰,ŠÉ»q™Ã “Z Ê‘J NÀMþ—%I”ùP•‹“s$41¿¤’8ùjUW‹|¬ºv ­Uß=ôy3°ÎޏÎÌ®ä¯j\¾2‹9~^bc DPiV ùn¦Âºœîx‘wM‡æêL…}‰1CŠâƒÔ¢+@;a‹Z#)Þ¸í=dšOû]úhg¬Îä±Ý;XÙº]02îtϲ£ÅF@ÎÛí黮׿_$÷åb<ä4V纓û 17fJGþ@b -;ò¼]b£6™ÎHíM׸BÒá¿RÙšiCÕ>Ð×t…‹$]åó‡.®ß^!åÜaéÑUÛ G±‹ŽÖ¶ý…]Ïjòºæ³KæT-YPaá þUï¼S!ë¥hÀo¯ÎŒ§dÚ¥.¬E5<º”‰ÂÏ-o9;€XäSÝ=­ì2Pì2Šo»L,Ê*¬åìë™_ñ‘–/‡jÂÃߪ\%·tPH¶mú+¦Ë»Å¢°Qhéj|JdÄmx¾EYŠzù‚wûn=VmÉç]fÔDŒñ†sÚµ-)ëbØh¤‹ým¾£éŠÚQ’Ër_üS9êj¾Õo%5}9!뱿!uÜ{h)µ¨*ˆ¹èØ|Zø¸‹ª1“غŖI=¿'/ñ‹ ßÑ{½‰xÆT˦§ô`A^–œ:má¢mmD¬œ Ð+Y¢qåÈBuÇ ,kè'›˜IO}§ýþöᙫ±@øÎÜ?yŽ à˜²gõ}×Lç^Q‘oÌX{ðP̹Er£¹l˜(êz+î•n ]ˆIaýD[˪(\|Pµ3¹{ÏJüƒl®§Û%NÄÙˆËh».pcè¹Vw®H19¯œöM¿žž 'ãss ¡ÐŸl®#ÁúPŽœž=1š¼­VëÞƒ½tŸ¡†•Wål3zùuþR2 -j ú‰ˆ}Ϋ†¬M—›LäÝ æ²§ÑaŸ8Ëãqf4y<˜e\ËG#>ÌÏþ;Sp¿ N|6‹„É¢`ÑœÝ~•A|@XiðÝI5‰#¡Òè:¸9ûgï|j„¶ê¥ó Ia¡ãnòÜž“DdI -šb‘jž=矯>üIi)Ã:¸œ5E€f2bùfñä².çw‚× ÅÚW™O†aÝPl­§M˜¤ÛÁ¶a–qÿ*kÿ~kI[¬à0¢Ö$«ãaÙE5QB§ñ)PM¬HAㄪbTî½KrïV ¡ô×\:Ú¦]—¢Ls -b-2µ'š=*|#ôþõ’?Ç´ëŽMÔÖ)ü‰$²¶ü1ìϲ[szÞJ!´yÉ™£ÍÙõÆDÂêS8c2!åvp¬O7oÖ¾[¢KQö’KÇÚ´ë‘6ÂÆ'‰NÔú–K»4”0¿¯uçhƒ~ñGÇñ1}Zþÿ/¿Š"‘H˜ x ÿ’ü§ß}Tôüó£ñùQ¯z~à‡AÄÑ‹¨hHíÈÚÃω¥cNf[!Ó”‡¿«wîõI Êðsë“–ÏéAFï_§ˆh’íi–^r|up:D8ÃbTæ>Þ·]hl -jNñ†˜H eôMÄÐøŸ›c I6ИCм—£ÛÅÅÄP©'I+…J’ å'–+þ«û§_Ð1Ï cwÇ£c7è˜×¡s´{¿ c^>¾_;ýe&A tøñÜAìÿ VÜüG -endstream -endobj -1610 0 obj << -/Type /Page -/Contents 1611 0 R -/Resources 1609 0 R -/MediaBox [0 0 612 792] -/Parent 1592 0 R ->> endobj -1612 0 obj << -/D [1610 0 R /XYZ 72 720 null] ->> endobj -770 0 obj << -/D [1610 0 R /XYZ 72 720 null] ->> endobj -1609 0 obj << -/Font << /F16 823 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1615 0 obj << -/Length 1416 -/Filter /FlateDecode ->> -stream -xÚuWKsÛ6¾çWðÔB3M‚Ó“q’Î$ÑØJ§Ó¦˜„,LHB(Ûú÷ÝÅ.eÉUOZî.ö½ $zŒ’èû„¯Vï.nÓ"Jó8Ë ­ÖQ)£2Mâ$+£Uý%nfó4• ñçýÍ×ûÙ<+â³î­Û}Ùu¨T4j4v æOôóÍ«G=û{õÛÅmÕq]È=$Ñ\VqYçä`µÑ³¹,+1X׫éZôìù½Úsmq8$'™iõ0“•M3Ù-©\//>%cI"5´léî`)_Hè÷~Ô½gó\â~Tn4Ã#)©‘ —R¨®C"j»í ­„'Ñ–\òzò»CÚðQO'Ÿ1ëZú‚S¡R ‘u(ÏsѪQQÛðd¯h 30ä¡>`ä¡{e†ŽMLóR&µÐ/ºŽÏe4íz–‰–ükOŸƒÅ -f¹ða'ÉncÖ{+úÁ¹~ Ó‡¼Ã -À1EàR‡€À>—ÜçÐcàzŒŽ¸Çл×X«¸–5Åz?éæõ±.úË+±ZíH8%\ÚàµCB¨ÈçS -³ -vöÄØæØÙ 2’Ôé^™ÁOªÚëÃyÖXÛŽç™V¬(’„Ä•cÓ¼¡´¡ÒÀƒÍ8Ó"ª_Yp­pmËL\wÐ}DÀnSŒxS¼ñ“öi…€Cµ(KJ‹éëë%IqNŸ7fTdm`Û;ͧw>”(CVµ[«f²hIô&V¢ak¢{6ÁÓ­•ÕâÍRÉŠƒG‘Û ”Ç’–õ‚œ¢èЍ7É ÐJÎ'ÄFÝr-÷FÏ LÑ–ö`hOBš2³–UÝ„¹¦@Hg®‰šy]Q¤H\}ÂHóºæHÁ[ˆù¡òøAP¸!Ò"¥¦bNá–S¸Qw -éõnhB)êꬦ»ðz«8 Œð|äŒÊr®mÿSªºÎî >¸B­A—p]œ%ιø±©`ãÈá;hÒÁP‘ADo=÷æq0¸ñ:¶ªÚ§Ù~††,ãð(Ž:<ÎäÙ«–Ì T–CƲ…%Gð: ©F÷D3 æ¢7Í„ð¶ß;å>adŽ`j¸+ð… –KSd„õ~χ:¸áÚ=éö(žÞJP´6ÜØõJÌÇ,˜ulwš™_ºþȤb¸Dýb°äHšt}Ÿ©çÆò\ŠoCg~ðÍŸÉ @dñÆ7rúãTˆüd ÄÀ<` ¬(ÿƒrÂ@Yðõ„Óÿ쌛,R»€˜îŒÉ²Œ×fûì]úþEõ[€D34ݮտÒpÝÝÿñ3 ^ø¥˜{¥÷Çè -ÝdÁˆa-zÅ–âÆúã òUð¦½^Þelu‚'¤OÒF¢ÌО*…Ü[T¹^òýœ÷_~?‹`Ÿ¾.p³´°™Á G‹xo¦ÕÑ£5^sÄ/ÅÜ5jxnöÓú„†I~S¦uxL ð¦‡'áž8SR|ÅŒ®‰p! CêFƒ‹ü¡*‚F+ŠgKPe½-ÿ‹")‹x!«†¶„-””pšÔ'jïWïþSú‘ù -endstream -endobj -1614 0 obj << -/Type /Page -/Contents 1615 0 R -/Resources 1613 0 R -/MediaBox [0 0 612 792] -/Parent 1617 0 R ->> endobj -1616 0 obj << -/D [1614 0 R /XYZ 72 720 null] ->> endobj -774 0 obj << -/D [1614 0 R /XYZ 72 720 null] ->> endobj -1613 0 obj << -/Font << /F16 823 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1620 0 obj << -/Length 1814 -/Filter /FlateDecode ->> -stream -xÚµXKSãF¾ï¯ð-r…¤ÑÃÞœ›…-(ìÔnHrÖ€U‘%—$Ã’ÚŸ~, HmÅ—yõô{¾nÙÜœÁ§ŽŒG‹'ãÁÄž„^8XÜ "o¹Ží¨h°HX×óo¿TÑïL¬¸Ô<É‹rgÙ¯²b8òÆÖ2®uÂ;éz­“Ö†ä–(4PÂðÈ{ÇÇWBó¸Öë¢|Ž•eGaäZ‡Y'®cõjèZ ܵJ¦-65ì¤Eg¼QááSU뵬õýZç(®niÿ×â3X=r]{lßÎ¥Ô3[p'fÝI󇡡¸tv9çꯔßèï£þ¾Xg¹°È²}žÕ+Í´•¨Š›ryĹ³Ù°Ïâ²âªXëz•æ÷¢iú7ª$üà úˆæ55ãÁ‰rZáõBÛ ¼ÁÈ ìÀõØ'ð;Ž/°öF¯þöÈ{ÊµÕØëºðß…˜H@pe,¤9«ÄhÔÇéü~^G‚*ÇyKS¹\øoÒ®´›ùQÔDv ü—âFÎÌqÞka“"‡^OÛÀW%ºáOKT.XÙ ¯ÀüݹØUa#Ãy¡šëEçU -Æ’®Ê⾌!÷<×yý&¹ñ°Ôq'r/éÞ–ß>íõ€ã¾ßý¯xÀ÷ÀŒ£¸Òb^|8½ý”çÝr»`Ô‡koâ[‰Þ¤KÂF\!òáH°FÇiŒžG´s<«ÈV½  Y’”º"ŒÖUû®ÚÝeqv…0KFâ*ΓgRâ°"?aWÜ=cWÕqY·Ï|kq…ÅåP˜”Bø§ãúß[õÄRD¾yç*P‚n€órB‚nÚÑñiãZ x¤XÆÙr›I½ƒRÃ"}0Ø;uÁ#¾f›/-VrV¥ÿháˆVâÙ ŠŸƒ ì¾p0ääã¯Px|Ÿ« ¹¼U¯à եR*ޏJ/.P/\ T§Ô™ªQU¦â£h©~Xj#SÒÐ4Sƒ+ÞÊ k dcÈØžxASh±â¬ -wÖûQd­Ñ™Ûªæ#q¦Ðeµ.9ñBþ$y“¡µáªˆï!RÖYÍla—:Û4Ñ"µ^ [†oœ%ôè6ü:ó$¾Í„dMôä¹q%‹;åiB!7¬ÛQ–·kºMB4ka®ßÁÒn{;”ßýŠ@t>Õ¥ _j°WHõ÷x½Éäðq•.‘ߊ—ÛÊàjž_‘)¡”•¦ÀÃ’{Yó;$ÐîÉçZc19ùÁ*—ƈµÎ—²"û•è -kè·ÞÕß;ÏZû³‹éÍü#÷çSiØNÏ÷1/áç -˜Ñö¯LöIKÅ9³G2g·E!§&;ÑLߵǾêÚÚH›ÎöéÉá©42"Å4Í0…Æ ß,NSùF¨Wfv—">ûœzx1•>J{4†VNDgÚ\^Æ%ˆè¹È›”ñuŸÛîƒî‘ɳvŠ3€«.€Ÿ]ý¾˜½kñ¹…®¡§9ÁŒØõ…DQWFíTu¹]ÖÛRîÖ+*e0Û53°h Ü ךٚ> çüiÅçôð‰«\•ʃW·õŠ` ÙËš?UÓ#16_=^ÍÒuÊVCÅHKÈ–ì1hã·0µe*Íß ­³ƒK›‰Øs-j^¥u¥3á³0O+ÂçwŸ¬ :£&Vmð¥›%¤†4JØô‰Êd4ŽFø1ˆ(²Þ<ÅGt|yñßÐ>r Õq¢K¬b._O¯wÇðٱ͆âê7fÀ;ü%“óaÜÏ-¢¬¸O—ø•Œ‹Ä4¬øoÕ’¿°eö”5‹ÛÒº×ôCŠ…ç˜STÐqÑ4ȤNU¥÷9„¦¯ÐRFr馹ž(k+ÿ/1Oá€e’B@TJÓ“REZ‘èŠ#2R¬²;•hàÁc¾ ìñx̸®Ó¡š->ü }ì -endstream -endobj -1619 0 obj << -/Type /Page -/Contents 1620 0 R -/Resources 1618 0 R -/MediaBox [0 0 612 792] -/Parent 1617 0 R ->> endobj -1621 0 obj << -/D [1619 0 R /XYZ 72 720 null] ->> endobj -1618 0 obj << -/Font << /F8 826 0 R /F30 1094 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1624 0 obj << -/Length 1173 -/Filter /FlateDecode ->> -stream -xÚVKsã6 ¾çW¸§•§±"‰zy{ržÞt’©uh·Û#ѱ¦zD%ãýõH‘<ž¶>˜ ž”³x]8‹‡ ‡×ëäâê>^¬íuè…‹d¿ˆ¼Eä:¶#¢E’-þ´vy•ªåJ8k+/›B•ªZz±¥¥ÎëŠøõžÖ/O×$w,Ûá[uƒr² ®¬2"ºc§U¹ÊT³\6Ue¬öÎ]ßJëªë MÂú H™¹µ\¹VIûRÂ¥ÈêeÁÖôAòT–jùWòœ\¹®½rç=×Â:¢½ºoq‡˦ת¥³}Í™†óL}w\¿ÊÑ›ŽÎš¶Foy¦2☀€ðTµ`_mDsuïMcØb{í­ Ûõfw÷³ãoáZ,¬.¾uÓ·-ÄFx–&þM]–GØ<†œ¥ªë æ¡î%Ų6ÃËŠ¶£7\î;ð× úPÉÁ¤2Ö zuÄàŽ¸žõ~P-³nnž‰ètÝ*>§3%G0ÉÄøÀ‰›¥k!TH§¢‹äcD0íå*=ÃÊŒ[X8S0Â*  !E/¥6iMyÅäšA9+”Xl±7ÔH8çJæ…J4¯^g5!¬ —Æ€@ú¾Ï áÀÄ×H·ûÿY—]I€3Ú¹!‰ç\a&Ž|fœ£@ù«èU0/ª¯}ÙC×´^ß>íþ³Àa_„Ð[ET`n#Gf$¼£M@Ke"#j¸EŒZ¾íÐøì¼1aQ-4bÉ&hÙ÷UŠ=±Ž×ÚÖX1ï&ü”„’ê‡.ö`=HRY}Ò¤ UÅ‘(ìVãÄáì¤}:Í„1‚‹-Ý< Åù3AInu>V=œey«R¦’&?0fý‡ÕúÖ¯»k$·ÀÐÃÉÒÑÔ):8 -Y¢0ñ’ #ßš#e¦ª4d’laƾ!_Ù<á >ð$K(¨VV]þÑïÀ†YõÚÊ’6›VIljÓ„9“€RšƒóŒ´´Î˜U­‰à¦¢ ?b‡Q:éK¢'Ïu·Ã3Î`®"¶*«‰Õßv¿b¥²e› bgmªªÍôJ3ºnðAަþ†äo¥TÖQ9PY@Ý¢Žƒ2ËßÄ_¤.ÿ¡ˆe\ƒãÀ01z[Ð5y!_ -f'ÏKèý mºCÝÙ8¨N4P± ÛÔì¤-Nˆ$‹úeˆ€N&3ÎꙀzƸ|¦2or™Wêä9–eÝO»jÁYÏ…UÒWCÝ1fNܯ׾(ÌSþ>Îø”º'csûV¾–jÖÆª„ÝÂ+3äìN±<ä»™Ìy ¬ò3ú9~ ëÕ½pæƒ×‹íxíRî’Ý—oŸ¡_¼Àz¼Åo¤À±¶—ßÀ_¸Âeö/$ö 4cÆpƒÂÕôñ”‘> endobj -1625 0 obj << -/D [1623 0 R /XYZ 72 720 null] ->> endobj -1622 0 obj << -/Font << /F8 826 0 R /F28 879 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1628 0 obj << -/Length 2096 -/Filter /FlateDecode ->> -stream -xÚ¥koä4ðûýŠ_ÈJmÛI6á º«®PÄq¨]tBÜÛ.›”${½"~<órm -Hô!Çãñ¼=N´º[E«ï^E2¾Ù¾:»PéJÅ¡‰S½ÚÞ®6zµQQ™Íj[¬~ Þ®O•ÒIpQVn}j6IðzmTÐ÷mysì]·þ}ûóPaž$Ä#Zš(ÜdžE¨„ɇ½í™‰m…ÛÇHÅž³¸~Ël³Uæ©N…©NB“f*òİ ˜ýþ½H€Nå^Çù«]k«òOW0âàlÝ1Is˨û¶Yë,ø\e}ÇKe}Û´Û—M-|oÖ§z4Ǟ笀0êFö{9¼¹ê,€“ûe‡?v½;ˆ€µH»AmԔɚ‚Pw­=à <ìËʸçé„¿LͣȮO“4 -~© ×òÂùÏgïÒ¡>(S°©zd\ÌÖ¨á”Ãì 0µ˜åAR× -Á±s…°dîÊÙâôýpj» åõ¯×de“8éc—·²€C>ˆ„¨²c\çzF  pœ‹ëG6®°bèúiw_Yò$ļ盅¹Î™ïkTFM"_Y‚Sì0ªôË ÀIlkWx[ÞÛ_ó 䚢Lhý ­ð®F€ôÀ°wíÁ¥í… l‹aBÉ -Ëë,θ£ëm½s”fÚ§™šdç’GÍL¬X3ë1¼ã©wcï] àú«f5'f=q™ÐÖdGÙcPÆil÷eÇË<¼w–B1ÎQ^@x&ëÈb×°©Ú¦ªøÂÑ>x—Æ’©LW⋾+kKÑø›²g¤¥«#„Ù¡ -¦xË0d™òÞ¶}¹;V¶e4‹üuÇ«¾È ӊז2)›—j<®.&øÁn¼ø1J¢F¸_½w,TÀ«³@]€Éçƒ)Y,‹m&Ë'éžQÆÎ}¨wM×3꺼«KTÃMÏè7e±G)`Þ]¿9aˆ -ìÈÛ2CH(ºfmkw½kçìHNF]p)—èû!JÔ`¨ƒk×Ô²ˆæ3Š™p¥}Ný§k›)9Yu±^\ ³( 7yà¾ØÃ}Å9>¿#Éo à´`R–ÀI?òêçuÝJuÄŽs4Ž–©‡â(Œ°‚Á‹Ëß¾Fq¶Û«ðü -9žó†I/ƒ„{Û1ž;,çjžòÕŽb6ŒÀp[0y·§{ö¡ö…—Mõúúü’Üpyˆ½û"8läoëÐûñìÂD“>tcB­hF³0˵Tg8ÎP 4±ß»/pšŠ"=òÜ‚¤§K?D­wœÎ‰/€] -Ísœ -óH©h‰ó¥'Î'Äø·Dü£'>ŸÃ?Ÿf&L³ä‰0Ôv'@ûÕ“‚Êo=Ÿd&¡:c“Ž×íPÓ/ˆ¹š$‰ñ7úßÄWžXO‰£Ñ´Ú„¹RLìtnP$³RÿÅZÛÇ{o­>t‰?963kÉÉé&Ìó';þZÒ–k%JCµò¶„J)¨’CXX BvTˆž= ÄÈ7þKL´/wªåÇDR]=Ü›‘~V#¹;#¨mÊÄR'¾ -yé§n3¿“²ÈÌsÝŽ´$5ËÓ -8«år sÜ<9N8P)D Ý­^0¡ê²`ây­fú†ž‰øæQ%XFS_Fq^àµe¸o—²ãë.³>j¸  ’Ò³hè\p“ŒÅÑñ&ßïKמ· ºGY þV²<¾1béûÌl¸Ý~¢GÊ’úGð§A‹Ñ­T|÷ :ç; K{y·§Ëž§7}HO}?nO¦€éÁVü„¬£½yÇÓ;fÜÍ\çÅ£gd´*~zaWT3ªr¶“­ÝBoáå^0EÜ*“®Ñ˜Áè&É^hÕ¦æÖŠ'ì áø/ï7-]³žUltÍ]´ž¿Õ´oª)IøÃ"%OŸ³é´¼"´šÈ©ý³É8? ³†G즩 ˜—¢ª‘²¡‚²½ûÃ{¬âì'o”L’3•ÍÁÉRSï|ÎÞÙRºVËCÕ À¤'Lý,ö0O µ ÞËË9ô“¡8÷e‚Í1•©uü-Gðþ{‘yѳ_ X:—“ºüãèü[FÆQ–±vÍ/”pÖo¯´NÃDCs‘Åá&‘®K)=£z»}õ7ËÒÞ -endstream -endobj -1627 0 obj << -/Type /Page -/Contents 1628 0 R -/Resources 1626 0 R -/MediaBox [0 0 612 792] -/Parent 1617 0 R ->> endobj -1629 0 obj << -/D [1627 0 R /XYZ 72 720 null] ->> endobj -778 0 obj << -/D [1627 0 R /XYZ 72 720 null] ->> endobj -782 0 obj << -/D [1627 0 R /XYZ 72 700.172 null] ->> endobj -1626 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F30 1094 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1632 0 obj << -/Length 2570 -/Filter /FlateDecode ->> -stream -xÚ­Ûrã¶õÝ_¡·Ò36—xíÛ6›mÓ™d·±2i’˜‚-Îò¢€Ôz•¯ï¹¤li»êøE€ƒsÁ¹2Z=®¢Õ߯"ùÿÛúêÍû8[ÅqX¦©Z­V¹ZåqF:_­7«_ƒïCu}Ç* Þ×½¾Õy¼½Öq0Ž®¾ßúÑš®î‡ëß×ÿ|ó¾X•a™© F«[•†:ÓŒïíÊ8hmw­Š`¬ûÎndî¯oUô×ðóíÍõm¥Aß5Þ2"ø z9ãÉ´´fåYïêǺ3Ms‚¡nwõ—ö8 Û£`ßm¬ã=ß}|ó#T'QAx}›ÅYðC»s=žýŒTNˆäöºCþ‘e–(³,èâ4€³Î´ÏL·áA¿#Æ­3#ÈaÃamËcÛmMWñe9_'Á€dÁqPáÈ2ô; ¿S¡q°53Ý ytÖŒ$Z8H²ø²ƒ“@—ÊÆ­l5m¿gV…ä‡SœÖÝCïZƒJEdÁÓ¶®ðÔ§yÐ ^CmD -Lª¾›©;7¼2n]¿ÜòÄðßoQœ4ö/cß*Iëà¯Ê,øÏÝ»w7<ÞïcÏçl h…¥ ©Ü3?«lNl$±žÙÀ‰†žæUmFäOõ¸åÉØx‰ „/Eº‹$øÀ¯ÞñÉŠqš°×z[£U8Ú~yÊñ‘C Zo*šÞÃD½¥Iß°6ž?âu)†ŒÅ:l7ìAì~µKUŠ¡ƒÕÝê,å -c³ð0½¯é1g p¤Îòx°#/“¢àÿOëdt”du+XÈ|Š…ùd óñÓÖvKR¡ÅÉ}šÝ€Ò$ -þ=í6‘<¨åà¸wè³N< zö€ã·(˜ ]2ŒóðÞ›Œ ï×À0 DÕ¼¥ ³òNñ_ä’, þÁž±ú<=,‘%šÀ KÇIdÐcHAucîý6ïáz2%ÙÜdŸ5rôBµNØivuŽøÀ^Ø ÙNèÄÖ¶Å®¾__ýqÃEÑ*ÆØ”:,£bUµW¿þ­62B]«'ÚÕ®T‡QšÀ¸YÝ]ýëÙù<óTí|$áPŽSŒTˈ–ça™€ -ÂZ".~kœ©FU -®å}0û@¡}l])ˆ Ó —ä±íßÁsyÁ0DMbårª_0šÿ[hi&—Šì”Ä2–…x÷1kmER Ð|gZ{Ë–r^’sÌK’‡Iò*ܤ 2 7ê,7Ší>VQ|t5ÛØhý~6Éuðqß@¼\.œÂÅ|‹A§aR”¯!]†QϊA/Äð¶ªì0ðÖa4-æÌæ§^ÜôžÈúy9\Ìȱ”Sý*ÏAå!¸È!9+‡ä<î‹ :æ–ÒüUô§aœ‰g_œå§XèÜ™mx羃ˆ6Ú -| Â »Xò çep1G2HÊ2ÌÔ«è4Ò¡Wéz᯦@ -BXstãD\×mœeð³5>²¹ >)Šh¥²æ¬.çâXEfYñ -BH 4(â×ê[¤ RxW;Pvï òC ÒÁgfçù¾˜ðc¾!*ç±~ ¾ó2”¢u­¿…k½àú§~Wæ8ݯ?û¢&‰²8xû|^3ôBi|Qì)@“Ea¢¼—‘àQ…™¹Ï‚†¡¨¦B^ë8ê/2âÚö ’Ìv÷uŒT/nn¦ZûAöL™4}‚ª£=–j¹ßбR¢Eéɸ6ì‘Åœc1Œ)v»(qù®È"·È!ÊVëB°Úw²É‚]ýÞ1h.‰<Ó+B…/Z°xoz!¤2yVúä©ÞXJÆ‘*ˆ¶»Ñ_Ör‘ÚÕÀ<¤ð!wtÔ³–ŽVa1wˆB|öqÍL1§6˜Ý.뾂íèAù@øÕ~Ñš;jF c<Ü‹º–!T%Áé(Œ®ong¨YÁ¾¼FàüqûVvRÑ'µ4Û³à[*¥æ\wüoøoÑ­€>,×tNµT„nNTÄMª…ž4 <€ËKPy ,’o¨üg–zÓ….¤«Sµ€\ß>ÃoÒÉ(šö²–ƒe©å`¹±°ŽR_ë,щN¿bZÙÑÓ‰|5pb#òÝ‚HÚ:Ô-$wC:g-º;ÑÔyªúÖ -$ŸQÅS_õF‹`n©Ï†åì}”[·Æ$ÿ ‹æ«rO§µlh‹÷릛ÜPìá&jôq®½Ü)}ðåul% âu°©‡O Û8 2'Û4?`¯(+g×ò|j•à„º IV°°‚ÂÆÖà j˜läÀà¹C‡æ¬°WC0?/BßM»Ë ,ŽwðkŒ,w¼ÆÝ10Ë8b–qqbùæTßÊ6u[wS¯ur:è¬÷i°«†x ”¯wÞåTý®¦w3yÍ–®½s&óÎÁuÕ²%гsÛ]tÞd‡¨ w¦òÎýŒž(ö»'g4ì\Cʧ¦‘’Ljé9'-/Mœæ Nõ‚S-œê$0SOaèä›bKW%íÆ?o|8F™à?=%Ur—ô”¸›àz<Þ–#Ÿ Là ›Nг="4Òž‡ò¦fR'{)>&çù9ᨛFöK=5}'D‹kÁñ [¨àÞýTVœˆÜT¼h["Ì·-U¹°!\€˜ó@IN­ÄDÎ2.&¾Š™s¿a¸aïßúa¨ï›c«Ì~˜(—aä¶žÿ'3ÆIƒÍæ“Îkó¦wÇoDÜ”Ôöñö]…ß¾-·P’[Ps X4Šdjú8ÅH8ÅÐßžb¨RÓ øïÛ8¾ãT©–7àJ-;ž'»ŸT'¡ÏS¢‘lŠ, -×G=D{·áµ£lúx»á¿9©ÀÙ”TÄÏ’ -Ð5„µ“¾A=Z5==ºò¹ÓŒkâ>ˆ«|êãÊ'zðv7ðŠà‚J¯w²™è-"acMöTHvŽl]S+Œ ü7½c8B_óŒÓ2B¼>xq,E®U†íS±¢å•¤Ðbê7‚¨W'ùÑJ -I4Îýû\²xXA©¸}Å=ú|î‹ç’}'ÅtÆ‹‰¡†Ì]YU”7‚ÊËÇgš>Aì£ Úì++äýDÌcáã—;gÿØCI¾á¯~D(~ßóFµüè7åLø=’¥' „R«bþv¹sGé³ °ÎõNÆòù.ƒ ¾™>pÎßb`"©&ì¡@H¥‹D;ðÒÛ~*¸‘rBS³ ] ¨ ˆ§[#1L<ךh¸ó—f‡/ kpÿi|¥T¦àšnË(̤ÍÇúhìÿ'ÊÞi -endstream -endobj -1631 0 obj << -/Type /Page -/Contents 1632 0 R -/Resources 1630 0 R -/MediaBox [0 0 612 792] -/Parent 1617 0 R ->> endobj -1633 0 obj << -/D [1631 0 R /XYZ 72 720 null] ->> endobj -786 0 obj << -/D [1631 0 R /XYZ 72 720 null] ->> endobj -790 0 obj << -/D [1631 0 R /XYZ 72 432.593 null] ->> endobj -794 0 obj << -/D [1631 0 R /XYZ 72 252.262 null] ->> endobj -1630 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1636 0 obj << -/Length 1850 -/Filter /FlateDecode ->> -stream -xÚ•XKÛ6¾çWøVX;z?Ž ’-ÚK‚Ä@€6=p%îšX[2(:‹í¯ï¼(Ñk%M.9g†ß<èxõ°ŠW¿¿Šåûv÷êõmZ¯šmS¦åjw¿ªÒU•ÄÛ8«V»nõwô~›n³õ&IŠ8ú²×ú°Þduìàtëp’GÊ9kîÎNóÚ׸ˆïkøMÖÿìþ|}ŠW›´ØfeÆÒÿúüîÃçõ&E!‡Ã°N«èiäù×8Éš&Eä&Þá'ÒLuþ‘Õѯܭë™Ç£vÎô²ß8Oý†<ºçépÏën/²µyØ#ƒÛóB‹ªí•Upˆeï)"êû›(Ü«£Þ®79ˆ5{tÚž$Û¦(Øv·7Àœk•ydÖI4òÔ¾ÁQÍ:!ŸÀËâˆv8jòI«nó¡?<óôio<ï$àIî$9áðŠ pD&Ǫ¾ãÅVõýàü6ñ?N´U£îd§eæå²kí“5Î-Ûî/(O“è8ŒG1‚êÁªãŽ«â’G dòŠH›-À´©Cêçy:oñ^ÃUõ LÏd´¤BK’Hœˆ ˆzksîƒ#o‘qàêÓÂ`È2À ú6C|“ĉhNᦷ“ zÛ¤ z‹®Êè<2|aÈ𬪠ú@ûè#'Þ)7xD '>Ê*7Ø‘Y¶ðµú7ªmÉ@”Š—ˆK½v(ç ûÈ‹ãóèôQ„&x Õh¢èÉbPUT9LœÃ&÷v8^ø¬ôp 5ÉNtÉ„,òˆ|æq?ô›“5ßÚ~ýcÏë¶p“ÕYã­¥8“4|Åðz"Ô Äõ½Ð¯@‹3_w(Rg,døÁ>óBH˜!fJ,Ìì1}{8wr¨œÞxT.˜gzÎóÁa˜²fD=GjfJÀ€‘bÁ.€Ãéî‘âWΔ»q4õaÕhTƒ®êÇ~÷¦ã»ÆIP=*®4‚:ùØ8EKq±äj€Õ<¨±`ô¥“Ç/œJN*(#ës1œÝ8òë…£Éͨz¬Ì¥‹™!ñ“Sü¬ƒˆÌ%„rĹ»Tæ_m,ty2‹š²LûìÂíÌB•U\ÉÞ…hò}ë ¯ ø2V»î˜Ô™ñtPìJ¼¼Ž9¦¨&–@4V×ã$þlÙ,%c½±í:KÁ÷ßð£¿ûÆpÙ/¤­2”]'’- '¤'¢L/Na€KÜå³,Oö–Òd"oÅ*Îb¥ÔNP: -Ù¡õ·"îEå ÙOƒì…2Âì…·Vú”¨Îh»€Q¦¸NH@1¤žù5‚9îÈdB"|M}ÑÊ0p`å‰Ñ^¬}9HÜ —¥G*³–PBÁvÝAÀã7ÂôdØ‘–XatttYÔóUùlÂ}i¸ ]|vÐÔÜá—c d|1Æx$–Ô|õü÷·ð`p¬y]EÜó†©ZÁ8ÔŠW'×z89lA#.(u¼:ñ*‰ïÑ Ĭì„΂6°pÁg®·æÀ‘*‰+Ÿœr@…ˆÒ\ôý0÷É‹>iÆ•cNhÊÙr”9ÊYÆ]ž3åšÜç¾LªY÷BËô‚šsΤ:Ḡ- k.EgñyuËï㲉î%…G,ç'ÕE5zíààŒ½® èš…ë­.{¢Rò7|u¿W}+<^Y $¤"„à½ûÁFôûÎ_µ$]€õÝ…¿† D` –»ÕÑãœùÁ§ËŽCAo¼§$F=ËøH0‰n׿¹Frì¥"¤`ázqW=»B‹ -—ý9*Héÿó$OÙélã%õ&IYå †B;òŒÃ;õG§ÍK¹ä+øBÃD +mü¿8Y> endobj -1637 0 obj << -/D [1635 0 R /XYZ 72 720 null] ->> endobj -798 0 obj << -/D [1635 0 R /XYZ 72 720 null] ->> endobj -802 0 obj << -/D [1635 0 R /XYZ 72 602.047 null] ->> endobj -806 0 obj << -/D [1635 0 R /XYZ 72 521.84 null] ->> endobj -810 0 obj << -/D [1635 0 R /XYZ 72 413.85 null] ->> endobj -1634 0 obj << -/Font << /F28 879 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1640 0 obj << -/Length 2119 -/Filter /FlateDecode ->> -stream -xÚÕX[oãº~ß_a82v¥ˆÔ½hàKrâ6^±¶mÒíƒÖ¦c!¶ä#É{9¿¾3Ò–lmaaÛ‡æ!Éáp¾¹Ñvï¥g÷~}c«ï0~ssÇüs-Çõy/^÷Þ ˜mÙNЋW½w}“1î£mÞ7f,ûðïÈÀ3ÆEú‡¢PcQ.‹t_¥yVöÿÿåæ.ìEVäs%Û=“‡V¹$8Þ¤eßä®kèoµD,E!²>ŒjûÍ,û=ð#/*±¢Û´¬òŒ|­ö ~°h‰Û^‰·Býxú©ÖyAÄób<[™dJæóxÑq?tŒüL­]ò5Ý¡¼ÃŽÎ_+T34*Z€j†F^–é§­x‡ÀK3fEžO—–²×6²d§¨/( )iPŠ­XÊ[â¨Êé»/r\ô9]©= }–Ñ\x_~++±S‹3-…|#%Õ:´ž”tf=)ã°ï3}'4=ØÆõÁ6ú¼XIäD<´ÖQ¨iÙ°W·ã%ÙÀqéúÀ©6IEÔ¾%L2ƒì+eû“¼mŠo _<ÂU³¿mfS%0S·ñ‡ùó"¶P“£ß÷·XH‡ä#½XsÍͯ{/ì˜K}‡£øqòV7¯ßö£íÙ²×L"ø%#­Fùn¨D“Œ–á+–¸ì•VÜ—ÖHïʼnÁ²*Ò¯gW2IC“E–ïGt8ïp¥‡Å¼ùpµÎ7✟݈s$s ¤As &Ù’^D.LÖ¯Žãd¹e‰HË œu‘ï´Ø¬Ì·‚Gw¥á—´Ú¨ãfçøö϶üclhµ¹&¹¶§uªÁ¼BT‡"COõÐÁˆ9XŒ&Rû ñK@&{¡9\ðNÇc”óôô÷ûûét±ø‰lÌXÍÈ!.R¬ÞÁØ‹Œiº,ré)8»¨’btšÌ•è…8Æ;J{É 4n-x/d×Vþ ¦ #%¡%À÷|ƨÙÖÝLc׌ߕøœ.…âe+¡ú; tkŠ3ÔQˆm*ÔVÆð-«=M® ß³¹}꟥Üx?‹oÿH“±ÌÄe[—›ê|·NP3zpìo‡´Àƒq„I‰(-_¦d0‹![uøn)e!)ޝSrÁÿáJjIºØ©«'ô¡½íõ8J—z{ î0’Š${ݦJ‘gðAI Ümh­TVÌòŠb¡þP9 º4ƒÎGu½ ÖA$›íäw  øþýøfw‰ ÇeáW«rìè2kÁ|£=…ñ¡¤ÎÈx#ŸI½ìè(sš42/ç¬KO B‘[÷E"_ò8/Ä.ÅwÎ.òuµ$ÿ%ýÛbë´ ?‘'L,ÕŽoÄñb˜<›*aæ£çÄå+S -’e+Œ<ÈÅÇì|ì×+ùÔ•€çÙG›¹/‡BúæØ±ŸL‹ø±Sö´9eOøÊ”…c=mç{œodO+ì‘ŒÓØ%eESŽqoÍ,š¹HÃÀ«Wd£[\JáÆNc¹•ðoÉ>M¤sõxÂÇHmÂmuðÌ‚ héÊ0òO.Póšµ>ûGð;áûj•O;žïüþ‚ãRð²òuð[zà5rìC?C¿Ð¨™`¹{–€sß48p–-Ç©.(*ÉHÉ<„¬Í­}‚Ž>èºC½ù"? õ&Χ8w5ÎhŠë¡ŽºC=éèPÀh×QÏTÀ³ZÀ³–8eÍß"pÍZoÄ@ê@…± -÷áݲëÞ4T­Pªõê™zÂóûê?€ðÿ.™Ã[™ñ&ÄÌþÏÓ–ÈPÌ?¼wÊçó4Õ¯ÏFÜÒ5×h&aL·"ÆBÛ[¦Â–]„- 0lÁDõÈe-‰‚½¼Ø1’A„l¡¥Ùå…3:[m9¾‘®] 2èñƒ@Æ"ø¯`Í:cݽvƒontè \q¬Â4lÖSN…iЦA³*ØÂ6¸ÒÛà¶ PqØŽ¥÷„%ï€åpò«9›XŸ¸q]†¦X2§!j¬Ã$ÔMŠæð,p#¸¡zR!Ë·‰sÿ;¿óûRxfK™>mãñøPÃ%úW^Ôj+V/‚Øò—Mý8˜£JåOù,:ý -ÜRTm€Ÿ~Äw辨:3Îpà6³|Îz&¬0 uLyU·ñ›`5µ -endstream -endobj -1639 0 obj << -/Type /Page -/Contents 1640 0 R -/Resources 1638 0 R -/MediaBox [0 0 612 792] -/Parent 1654 0 R ->> endobj -1641 0 obj << -/D [1639 0 R /XYZ 72 720 null] ->> endobj -814 0 obj << -/D [1639 0 R /XYZ 72 720 null] ->> endobj -1642 0 obj << -/D [1639 0 R /XYZ 72 642.956 null] ->> endobj -1643 0 obj << -/D [1639 0 R /XYZ 72 610.779 null] ->> endobj -1644 0 obj << -/D [1639 0 R /XYZ 72 555.244 null] ->> endobj -1645 0 obj << -/D [1639 0 R /XYZ 72 512.218 null] ->> endobj -1646 0 obj << -/D [1639 0 R /XYZ 72 468.639 null] ->> endobj -1647 0 obj << -/D [1639 0 R /XYZ 72 401.149 null] ->> endobj -1648 0 obj << -/D [1639 0 R /XYZ 72 357.57 null] ->> endobj -1649 0 obj << -/D [1639 0 R /XYZ 72 313.991 null] ->> endobj -1650 0 obj << -/D [1639 0 R /XYZ 72 270.411 null] ->> endobj -1651 0 obj << -/D [1639 0 R /XYZ 72 226.832 null] ->> endobj -1652 0 obj << -/D [1639 0 R /XYZ 72 183.252 null] ->> endobj -1653 0 obj << -/D [1639 0 R /XYZ 72 139.673 null] ->> endobj -1638 0 obj << -/Font << /F16 823 0 R /F8 826 0 R /F28 879 0 R /F11 833 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1657 0 obj << -/Length 2422 -/Filter /FlateDecode ->> -stream -xÚ¥YIwÛȾûWð½ >±ÌM¢(qD‹Ô“Ç™`ƒƒÅ3š_ŸÚ°QЄT.DWuõþÕJcô42FŸÞߋͻ³+wäM<Û´G›Ç‘ãM”79ʘSg´ GÿÔÔt2þ׿ïÍ ³+³;D9G™ÐCÂóùZ+ÓÕÎonæ7ÿÀ‘ý%Œ‘®ÔÄ›ÍxÀoÆÌ˜ûIü˜åiìõ©5ÓæÙn_•VFc]i92-mý\”Ñ®` Ó5f0R1u™Ç?ưd”3 sñ˜‡±;Õü$ajždcÄ‚±éhßÏ6cׂ!»8õËLF­ˆ«}gÞ7¿ˆBž!K™uû=æÆrÉ3wjâQO7ïÍwÒЇÅ,Ó`æ6ÞOƺcXÚyøïª(ýoIÄÝ{?÷wQåÓq$U(óÕ=7Š=-EáG`XJ»ôKŸ»ü4aØ7È”y–ÈÔ4&ËK Ã<*Ѝ:Í2N5לͰei;<”£á^ ²Ý®‘ú†+=—Òõc<³áª¨èc–`Øè -aÊRÊ:i«ûÕÝxjj·úz}¡^šÝm­ ¶nšÚ®‹·lÏf@™æ´(ì$@aƒ¹Ê3¦’“6z_tÆ1_ž¹t#ȳlW¹Ì›øìî¹2à¿Êzªrq0,foˆÒ~ý4Öm5£ù€À –í¯Õžïê^¼ètzàÅ$t½Ë[ wÍÊjÌâcïŇZ⪰·u”-pNyøÍZW®q}ûᨇ_ÆAž-cv—hGá -.`üÙÕøX}aÿo``ÕÆ Kã€e9Î``ÓOdÞ(ÿüg6Ê Ù-µ£?ö~ZÄ„E«Ö82ËÝG…x»˜u$d‚™é 1нt4îçw”yF_èðJ8‡bÅ„ƒ v. Þó@WEP‹•¦eBžmZ¦bnúqŽíp¸'€ãgåéëûÕâNyG¡ãçÈ/·g_£”L£eyšò0êrÍõ˜Á ð4¯ Ù ¸ÀƸZ–Ëï‚}‡†¼Ç* Ð1LîAy¡óG¢GÇX<[`.þ(ák‘ F¾ß\šczfþvò\à[êCW6åì<ªñ‹®Ì˜Tbr¸'âÜá¼·Ë Sl½`yâ4¡Ï²Šœö”Û<«ž¶Ü]Ös€©+²D(ã4"ÔM•v›&Ïâ˦)ÅkæÎâÀÙAÓÆt --ñCeÖ ƒ$”mâ˜ÃÀÉzqnì”È7)Æa9ˆèeŽìQÌãë$™…xïDÄßߌ=[ÛÜ¿ó¸1Â<î1O‡‘û¨1O¦½›’µ—6|Ôà)Ê잂߻u„röXâ<åm<Ä‚=ÊŸYì>)sôzwÙn2{Žù¦–=ÚZÝÇæ\ÐnáËDľHtáëBº\t(?°^•UžÊ¢a¾7¦Œw>¨sš•̘oÈx¶¡ƒQ°Âª8'K  »ä(Ÿ?ë°ÊLÃÓ~%kâç¸*DKÉ'·BC0©´^6‰N&+ÐûD”‡w¸| h°;ìpêø}Å]aŽUG$lj¦q¢rHí‚4äëòü—·èˆrDGLÅ: >’Ûêðz:ôc-ôBG°³£#@’Ž8 #xóIר ÈåºX÷^þ )úm”Ù÷E”¿—É>P÷Cà¡ÃÝ’-›]ÔDöË Cg,q@Gk(*¨µ¦ :F‰Zkxê&0a­€ãJ‡(®ÀGgwçç~PÒâ +C'+JLFá|içèigNdÍ\X©¨ `-×}©?(ØêRþ4s8ýÁ¥ôç$ýÁ'’!T§ê;vä<¶Õ–ëü_þú4R§¨ëé×›¯ ®Ì¼A{ B$¥Á/åÙð­•Û—hÌÛLYœCTú¹ŠœX`ŸlQËŒ1ŠÅ5˜õ‰)Ž-¬º,cIYÆjÊ2Ðz-Q?¡,C<®¢äX¡¤EV›=Ý -Þ@%¦©ì ýl+2â4"Ÿ -MM ÆÉ3å`•øé‚j[Ç ¦y"@Vse¾Å®:36§ð•â„ciµI&Î+(wŠÂN -Aã`·ö"ä~’D 3àÆÓ(àú”>³=y¸Þ _ê} ÙÅPðYHfm= °Ã¸­ê¬T•S0L"ì5±½H9ürñ»cÒˆ]½J.2ê$™EdHqJŽ)µ¢ÃúöwËËHsò3,r&Öᜀ·EKPxb¾HB/Ó{‘¹­Êÿ-ÔVºåeªègyxzÙÀœžÓ‡ëËO‹Í[€ê¹šËÂ’žÚ 0ë?7<ɱAyúC>Q¶á‰ûÎòïX'@šb¤Cß~±KùËnp -¥ŸËÄàÒbý -g“H‚ù÷8&øq— §§B6)‚[+‚Õ-GÝSâP"åPU@µ±)EÖ«5OìäªI¼gª)ȦLK9Ó™q98òjéêzÂ<ÎëÕÔôD§ùJºxPönã†zÖ¿ážßZ7­“ñ»^^½†¨Ù…hÎ4Dc\ÀÁÐ]yÍÖ¢“ø)ª‹fØÑüY‡Ä"}‚x.âê?2pQÜ]» ùnÆüp‡Ú½™3¯…¥ÿf]gp“´¼Jª›.Ò_uÀrûËš¤ÞÞ´-·<,‡‹o†×+±Ä׸ΨYÿv𪦡&¶©FúÔž˜ž%Ù»²{R‹Í»ÿf>{˜ -endstream -endobj -1656 0 obj << -/Type /Page -/Contents 1657 0 R -/Resources 1655 0 R -/MediaBox [0 0 612 792] -/Parent 1654 0 R ->> endobj -1658 0 obj << -/D [1656 0 R /XYZ 72 720 null] ->> endobj -1659 0 obj << -/D [1656 0 R /XYZ 72 720 null] ->> endobj -1660 0 obj << -/D [1656 0 R /XYZ 72 668.25 null] ->> endobj -1661 0 obj << -/D [1656 0 R /XYZ 72 624.414 null] ->> endobj -1662 0 obj << -/D [1656 0 R /XYZ 72 580.578 null] ->> endobj -1663 0 obj << -/D [1656 0 R /XYZ 72 536.189 null] ->> endobj -1664 0 obj << -/D [1656 0 R /XYZ 72 480.952 null] ->> endobj -1665 0 obj << -/D [1656 0 R /XYZ 72 424.608 null] ->> endobj -1666 0 obj << -/D [1656 0 R /XYZ 72 368.817 null] ->> endobj -1667 0 obj << -/D [1656 0 R /XYZ 72 301.071 null] ->> endobj -1668 0 obj << -/D [1656 0 R /XYZ 72 257.789 null] ->> endobj -1669 0 obj << -/D [1656 0 R /XYZ 72 201.998 null] ->> endobj -1670 0 obj << -/D [1656 0 R /XYZ 72 145.654 null] ->> endobj -1655 0 obj << -/Font << /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1673 0 obj << -/Length 2137 -/Filter /FlateDecode ->> -stream -xÚX[sâÆ~ß_ÁyIDÕ -늤¼fƒã•!FNÕ&9c46* ɑĺüïO÷tKHçÀ>MwOϵoߌ1xƒ_?½v}ºúâ‚Q0¶Æƒèià#3pžiŒ ÛDñà/ÍrGÃÿF¿5ƒ®¾Xí!¦7òL z”ò¢ÔïNl tÓ®Kj®±¢Úê~´9Ôm'Ю‹äûÐò5Yÿ”3Qm%_¦s"îe)E±Aí-IxeE?uèÈE#ïk›¡njéÐÔrÕÃ<íe4ÔÀÔn*³/eÙ[- ]ß{4Ç,mûÚËÕLÔsJ$2 bQàÁûg}K*Ü¢móĶ£½«SŠ‚Ä[™ÆD%õ³¢­#“ˆRnò,.©;¼kX–l¡›hF‹Í7¾Ä|óÉ0kÑBŸÞ,×ç›nfìkfpU›Ó{Z´MJêhy8'p•,žÄF²Ž ¦+ª)ÌIsl:·N*¯EŽÜ÷$–1I‘o& ýxÚ -³Ë\…Ô§¥¨?†¾Û)“<#5²ÀåG§ ¸ÂÙE!vvŒ&0]°ºéh¢"A’••HÁ2jFì©’¤>QHmY2[=AçóØ%I«U=0‹{E²,Iš?‘{>ŸñâŽVVE’=×›˜áV¨€Â@S›ómNÒ°áN’†>JÒ˜´àPu‚[äéN¥SPè$càûwú<‰}È|Ý-8°…³œ3¸äRT®û¶ºÚ–¶Ô}ç,moÌq]Ít;Žë¨m{Ð wQ+Ìòâ•® PÙ¡$ÍÇ}’V:f|Tê_ -j¨KÁNu)H„”,b™Ö†2æ>$[Ö™ÍqÏk -ž&$–ªÛ‰ŒÐCŸ5‘¡ì§\ü\qGÕ ¼]¹©n×ÉsR‘ û…®U#•3œºÂ0Ò1u·Šž}YѳKü`~.ïõ?£›ðBà¬äšu­ª“Ÿ€¯å”§€ tÄ­Ì ñ*Æ Z…É_)HQPG¤n“ŽžåiþœÈògšw<×oˆ9Jií5ÛN«”9­–§¬_§¾1×kì 2³NѺ:¸¡&¯¯,‹üå¢ä¹š† Ö°ÎJjjJÈoDƨ㱖ª¿(÷ï¶[ƒÏòó/©óÄäÛ?æwÑy‹íuñò”þ€˜Ä$'|D2û‚Ó(ɺú„~Р &Z4(ÞoªÌã‚ìP/P°ëyýp(¨©Bþ„ßtãþûÐk"ÝËbÿ!K*}ýøֶ~Äx_ç¿Nš}û±P÷Œn€{dø®`š¼”¾Êg±y'ú(2AVÇÍ‚@(x-à ˜÷ãˆÃùÛgsÄu×õêuU6‚6®‘‚+'¹Â)Ьn–Ì+LêÖÏ$”P<+GV¡Òvÿµ¨Do,À:Lq»F 0v^T<‡ -z$š G†@7uÐ#Ý zݵLí :¢ -)ÞÆ gíCÓøLNH‹´ëïúê]²C/X€NÓ.kpÎ]#ý`ôtq–»Û¸{xmë!ùùíY~æ=ªÞà¾'`‡wÜ®Ã;ŒK”Vò‚®%‰›¤à”?—ÄôQÊnà„jÅ öÌnëeím›ÔïyT¢÷8v¨-ŇCøGËË Ã×ÑBV 8ð0¬²ç+s2ô´\—-¸º9ËVÎ%¶ŠîLøÕUU!DzùSɱÝÞS %mÃ!O€ÒF¹§Â ¼€zûFï\IØÔgÃ0ˆùmŸ&‚U¯ß‘Z´ÿ+Bè!¨É³¿ ÓyÖOÂŒB<¦'­½¶Ÿ×ÀÃ.~X;Í©XK¾¦r–áeÀ{š«+J‚ÛRÆÒ`ã©‚jÞæù ŒJTÁ‰ .Ĉ½â)p`ý×Ó/N¾ªÕ-A¼“¤|RÌ3žN>V±à~òK°âóG‰dšd¢`¿ŒE=va+ù¸PF)'¶r‹Í¿G×€iõÀóÎòàKþü–wsÊ5úòî?gùî2“‚wCþïÛ²u¸}ˆ½Ãû~W¿Hð+®]!Ï:ã%cËè~r7Ñéwl¶8ï”U!2¬¾¡©lWU¢ù'PžÄ'‡þióìiûô¦öÍã¯"P—‰‰z*°¤"Ewå«è+ó”G¿¬VÕúh%xdû@OV²¦rP™—ñÚ”_”òŸ½Ì6òb(H¿òÚ?ÕβÆ%ßJ«Ÿ"}1ŸÜ+kL£Ëó¥=÷ò%J®ëbPOî])+*Q/©; ø 0z‘ï+’ò?t¨ïLzÒ¨?Mì=v×ÞrúÝt§0»CïDÂéD "Õ‚ã…M¹IDJÜn’q\½móRÖÀ]éUõ¿NR6Ƭk†äô$ØÞ†á硘K>­~ÖßÖú -ÑYFÅ¥Û=”^ƒèø=¢v­®«¼Zs),ò,Ù”Wäê÷‡­u\^ ø ÔQgû“ ùßÛ5¾¯ñ HÂð”ýÍØŽ×ô¾ÓTѦ`‚J§`O_ÌNíª YõK%Ⱥ¥´J(uʧ UœªhOÑq©–ׂ³0jÒTV‡þdOœ°AÔ‡Ûê9e˜£±et+ù¾OÃLÓëhÍ£Oÿ‰¤J -endstream -endobj -1672 0 obj << -/Type /Page -/Contents 1673 0 R -/Resources 1671 0 R -/MediaBox [0 0 612 792] -/Parent 1654 0 R ->> endobj -1674 0 obj << -/D [1672 0 R /XYZ 72 720 null] ->> endobj -1675 0 obj << -/D [1672 0 R /XYZ 72 720 null] ->> endobj -1676 0 obj << -/D [1672 0 R /XYZ 72 680.571 null] ->> endobj -1677 0 obj << -/D [1672 0 R /XYZ 72 625.514 null] ->> endobj -1678 0 obj << -/D [1672 0 R /XYZ 72 584.349 null] ->> endobj -1679 0 obj << -/D [1672 0 R /XYZ 72 550.711 null] ->> endobj -1680 0 obj << -/D [1672 0 R /XYZ 72 508.163 null] ->> endobj -1681 0 obj << -/D [1672 0 R /XYZ 72 464.507 null] ->> endobj -1682 0 obj << -/D [1672 0 R /XYZ 72 423.895 null] ->> endobj -1683 0 obj << -/D [1672 0 R /XYZ 72 366.901 null] ->> endobj -1684 0 obj << -/D [1672 0 R /XYZ 72 323.799 null] ->> endobj -1685 0 obj << -/D [1672 0 R /XYZ 72 268.741 null] ->> endobj -1686 0 obj << -/D [1672 0 R /XYZ 72 237.041 null] ->> endobj -1687 0 obj << -/D [1672 0 R /XYZ 72 196.429 null] ->> endobj -1688 0 obj << -/D [1672 0 R /XYZ 72 151.39 null] ->> endobj -1671 0 obj << -/Font << /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1691 0 obj << -/Length 1104 -/Filter /FlateDecode ->> -stream -xÚVKsã6 ¾çWè(M+Y”d[:&ŽÓz§ïÄž­§Ýh‰NØèá’Òºù÷ʯu;v/$|øàÐyuBç§»ðìû°¼<¥Nd£hä,7Î8 X6tÆ, Âxì, çw7Îïå§½Óà):vaã`Ì"Ø1Æ/Ó_î½lä.g_¦èuz|èøŒÙpHÆ_Ãax_{Qê~x~<ŠÜISm»V(Ø`¤Y¾IMR¡ä74ŠÖ÷¢qï¸ö|XZtZ$Éš¾¥I͆¾Üîð¼íxIr^6pLêæxÍûñ­p´ú8îÏΕ¨„ ¿µ1r{PÓ‘b…œ?{ÓàØÈÜ\õF«Bêw’¾†,)Éó­‰IÔ´¤ëA˜”ç'qI²Æ¼µR…wº¥ÕšÎ …V[q%¼¿ü ÍN¶6˜®•¥lûÒ€¢¥Ü4¥¦õV5¸ûM¢ÀÔ°ìWâÒ»+.)-ð5Šcs£©Rœ¸­y(OJ ëÜó™Û˜‚l+Q5êÃK÷œp#áÑg»ÈÞœ„7@xÁÂЦqôïøð‹Ö@~€Ÿ¡;›N§¤e#2ª'gàBƒNËú•¶çï’tÏÏô5\ðô'¼uÁ™€ä–VûÄÕ亶-‚2¯É&†CÒ|þ< H7‘*ï ÜF½C'®/U°:WÒ¢ÉVª»ãAJ¥aYÊHE€!$û½ÈºiÝ }UñØ-Å{`ièÿüb8èay=Ë\5Ï›ø¶!c‹›Õ˜hgÕyÌݶþšk ,h)+AŽß•t˜!´ºpÏÃl¾šdC.Èò‹—Æ€~-›šö¢ÀF²S²m…Õ®m¢ü©±x¡l¿âqJ¾¾™›‘4’¤ç -( -DÄ”*Þš NS™tÛ¨K½ú]‹Ò³ qRù䘇@}à!<ÚðØôÏ@å)ïÀ¦j@ñÕB“â˜xþ>¶I“èfø¬°,ÿ:IÈèˆÁÓj $ ÝÇý¡µhÝ!ŽP êÅ=Cƒ¨ZéÝŠJÛ• ÊX¬yýnN+üƒ’Œ¡¸£dìî_pôN–8íƒÉ—‹mK²€ËM%A&aº\/™Í ™fäñ=63tõ43¾³~ø©Zå˜“Ì GÑ.ÿ«‹!ŒRô‰44}@ÜjŽKOÈü…GîI`$pÉÄ7 d5}ñâÈãÏÊO£ðªI±þß„cpógg> endobj -1692 0 obj << -/D [1690 0 R /XYZ 72 720 null] ->> endobj -1693 0 obj << -/D [1690 0 R /XYZ 72 720 null] ->> endobj -1694 0 obj << -/D [1690 0 R /XYZ 72 668.25 null] ->> endobj -1695 0 obj << -/D [1690 0 R /XYZ 72 623.861 null] ->> endobj -1696 0 obj << -/D [1690 0 R /XYZ 72 580.578 null] ->> endobj -1697 0 obj << -/D [1690 0 R /XYZ 72 526.725 null] ->> endobj -1698 0 obj << -/D [1690 0 R /XYZ 72 492.354 null] ->> endobj -1689 0 obj << -/Font << /F8 826 0 R /F28 879 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1801 0 obj << -/Length 1006 -/Filter /FlateDecode ->> -stream -xÚ­XËr›HÝû+X¢ªÑ/h–`™ ²\‚Tb9Y`©ÇCAPj2óój9%ËN_µ¢,èÓç>Ï½ØÆ“aÓ+ûè9I¯F×È1µu°‘þi¸Øp‹{åéT¦{ã  :¥¯fíÿ~yà •Öž+˜îõ> endobj -1699 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [180.704 672.262 192.659 683.111] -/Subtype /Link -/A << /S /GoTo /D (page.33) >> ->> endobj -1700 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [137.311 660.307 149.266 671.155] -/Subtype /Link -/A << /S /GoTo /D (page.22) >> ->> endobj -1701 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [172.623 648.352 184.578 659.2] -/Subtype /Link -/A << /S /GoTo /D (page.53) >> ->> endobj -1702 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [99.01 636.397 115.946 647.245] -/Subtype /Link -/A << /S /GoTo /D (page.105) >> ->> endobj -1703 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [110.329 624.442 122.284 635.29] -/Subtype /Link -/A << /S /GoTo /D (page.60) >> ->> endobj -1704 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [126.379 624.442 138.335 635.29] -/Subtype /Link -/A << /S /GoTo /D (page.63) >> ->> endobj -1705 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [142.43 624.442 154.386 635.29] -/Subtype /Link -/A << /S /GoTo /D (page.64) >> ->> endobj -1706 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [171.654 612.487 183.609 623.335] -/Subtype /Link -/A << /S /GoTo /D (page.20) >> ->> endobj -1707 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [187.705 612.487 204.642 623.335] -/Subtype /Link -/A << /S /GoTo /D (page.138) >> ->> endobj -1708 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [104.766 600.531 121.703 611.269] -/Subtype /Link -/A << /S /GoTo /D (page.135) >> ->> endobj -1709 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [122.007 588.576 133.962 599.424] -/Subtype /Link -/A << /S /GoTo /D (page.65) >> ->> endobj -1710 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [138.058 588.576 150.013 599.424] -/Subtype /Link -/A << /S /GoTo /D (page.69) >> ->> endobj -1711 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [154.109 588.576 171.045 599.424] -/Subtype /Link -/A << /S /GoTo /D (page.136) >> ->> endobj -1712 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [149.031 566.703 160.986 577.552] -/Subtype /Link -/A << /S /GoTo /D (page.22) >> ->> endobj -1713 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [165.082 566.703 177.037 577.552] -/Subtype /Link -/A << /S /GoTo /D (page.51) >> ->> endobj -1714 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [105.043 554.748 116.998 565.486] -/Subtype /Link -/A << /S /GoTo /D (page.13) >> ->> endobj -1715 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [121.094 554.748 133.049 565.486] -/Subtype /Link -/A << /S /GoTo /D (page.14) >> ->> endobj -1716 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [137.145 554.748 149.1 565.486] -/Subtype /Link -/A << /S /GoTo /D (page.34) >> ->> endobj -1717 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [101.03 542.793 112.985 553.531] -/Subtype /Link -/A << /S /GoTo /D (page.34) >> ->> endobj -1718 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [97.432 520.92 109.388 531.658] -/Subtype /Link -/A << /S /GoTo /D (page.13) >> ->> endobj -1719 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [113.483 520.92 125.439 531.658] -/Subtype /Link -/A << /S /GoTo /D (page.34) >> ->> endobj -1720 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [129.534 520.92 141.49 531.658] -/Subtype /Link -/A << /S /GoTo /D (page.38) >> ->> endobj -1721 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [145.585 520.92 157.54 531.658] -/Subtype /Link -/A << /S /GoTo /D (page.47) >> ->> endobj -1722 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [161.636 520.92 173.591 531.658] -/Subtype /Link -/A << /S /GoTo /D (page.53) >> ->> endobj -1723 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [142.68 508.965 154.635 519.703] -/Subtype /Link -/A << /S /GoTo /D (page.42) >> ->> endobj -1724 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [158.73 508.965 170.686 519.703] -/Subtype /Link -/A << /S /GoTo /D (page.43) >> ->> endobj -1725 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [174.781 508.965 186.737 519.703] -/Subtype /Link -/A << /S /GoTo /D (page.46) >> ->> endobj -1726 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [153.03 497.01 164.985 507.858] -/Subtype /Link -/A << /S /GoTo /D (page.25) >> ->> endobj -1727 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [136.896 485.055 148.851 495.903] -/Subtype /Link -/A << /S /GoTo /D (page.29) >> ->> endobj -1728 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [152.947 485.055 169.883 495.903] -/Subtype /Link -/A << /S /GoTo /D (page.102) >> ->> endobj -1729 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [130.282 473.1 142.237 483.837] -/Subtype /Link -/A << /S /GoTo /D (page.17) >> ->> endobj -1730 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [98.955 461.144 110.91 471.882] -/Subtype /Link -/A << /S /GoTo /D (page.65) >> ->> endobj -1731 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [127.514 448.636 139.469 460.591] -/Subtype /Link -/A << /S /GoTo /D (page.42) >> ->> endobj -1732 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.565 448.636 155.52 460.591] -/Subtype /Link -/A << /S /GoTo /D (page.44) >> ->> endobj -1733 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [133.547 427.317 145.502 438.054] -/Subtype /Link -/A << /S /GoTo /D (page.65) >> ->> endobj -1734 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [98.761 405.444 110.716 415.794] -/Subtype /Link -/A << /S /GoTo /D (page.65) >> ->> endobj -1735 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [143.454 393.489 155.41 404.337] -/Subtype /Link -/A << /S /GoTo /D (page.19) >> ->> endobj -1736 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [128.566 371.616 140.521 382.353] -/Subtype /Link -/A << /S /GoTo /D (page.24) >> ->> endobj -1737 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [155.41 359.661 167.365 370.398] -/Subtype /Link -/A << /S /GoTo /D (page.83) >> ->> endobj -1738 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [128.151 347.705 140.106 358.443] -/Subtype /Link -/A << /S /GoTo /D (page.87) >> ->> endobj -1739 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [145.101 325.279 162.038 337.234] -/Subtype /Link -/A << /S /GoTo /D (page.120) >> ->> endobj -1740 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [121.869 303.96 138.805 314.808] -/Subtype /Link -/A << /S /GoTo /D (page.113) >> ->> endobj -1741 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [97.294 292.005 109.249 302.853] -/Subtype /Link -/A << /S /GoTo /D (page.18) >> ->> endobj -1742 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [117.496 270.132 129.451 280.869] -/Subtype /Link -/A << /S /GoTo /D (page.50) >> ->> endobj -1743 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [153.666 258.177 165.621 269.025] -/Subtype /Link -/A << /S /GoTo /D (page.32) >> ->> endobj -1744 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [127.044 246.222 138.999 256.959] -/Subtype /Link -/A << /S /GoTo /D (page.33) >> ->> endobj -1745 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [116.943 234.266 133.879 245.004] -/Subtype /Link -/A << /S /GoTo /D (page.134) >> ->> endobj -1746 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [94.388 222.311 106.343 233.049] -/Subtype /Link -/A << /S /GoTo /D (page.56) >> ->> endobj -1747 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [110.439 222.311 122.394 233.049] -/Subtype /Link -/A << /S /GoTo /D (page.57) >> ->> endobj -1748 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [111.685 200.438 123.64 211.176] -/Subtype /Link -/A << /S /GoTo /D (page.41) >> ->> endobj -1749 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [128.04 178.566 139.995 189.303] -/Subtype /Link -/A << /S /GoTo /D (page.58) >> ->> endobj -1750 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [110.854 166.61 122.81 177.348] -/Subtype /Link -/A << /S /GoTo /D (page.40) >> ->> endobj -1751 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [125.798 166.61 137.754 177.348] -/Subtype /Link -/A << /S /GoTo /D (page.42) >> ->> endobj -1752 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [141.849 166.61 153.805 177.348] -/Subtype /Link -/A << /S /GoTo /D (page.47) >> ->> endobj -1753 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [157.9 166.61 169.855 177.348] -/Subtype /Link -/A << /S /GoTo /D (page.55) >> ->> endobj -1754 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [173.951 166.61 185.906 177.348] -/Subtype /Link -/A << /S /GoTo /D (page.56) >> ->> endobj -1755 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [115.974 144.738 127.929 155.475] -/Subtype /Link -/A << /S /GoTo /D (page.29) >> ->> endobj -1756 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [132.025 144.738 143.98 155.475] -/Subtype /Link -/A << /S /GoTo /D (page.60) >> ->> endobj -1757 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [148.076 144.738 160.031 155.475] -/Subtype /Link -/A << /S /GoTo /D (page.65) >> ->> endobj -1758 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [120.596 122.865 137.532 133.713] -/Subtype /Link -/A << /S /GoTo /D (page.113) >> ->> endobj -1759 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [129.008 110.91 140.964 121.647] -/Subtype /Link -/A << /S /GoTo /D (page.28) >> ->> endobj -1760 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [150.567 98.954 162.522 109.803] -/Subtype /Link -/A << /S /GoTo /D (page.92) >> ->> endobj -1761 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [336.414 672.262 348.369 683] -/Subtype /Link -/A << /S /GoTo /D (page.35) >> ->> endobj -1762 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [352.465 672.262 364.42 683] -/Subtype /Link -/A << /S /GoTo /D (page.53) >> ->> endobj -1763 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [340.565 660.307 352.52 671.155] -/Subtype /Link -/A << /S /GoTo /D (page.19) >> ->> endobj -1764 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [356.616 660.307 368.571 671.155] -/Subtype /Link -/A << /S /GoTo /D (page.21) >> ->> endobj -1765 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [372.667 660.307 384.622 671.155] -/Subtype /Link -/A << /S /GoTo /D (page.98) >> ->> endobj -1766 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [351.081 648.352 363.036 659.09] -/Subtype /Link -/A << /S /GoTo /D (page.65) >> ->> endobj -1767 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [361.514 626.434 373.469 637.172] -/Subtype /Link -/A << /S /GoTo /D (page.65) >> ->> endobj -1768 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [343.056 604.516 359.992 615.254] -/Subtype /Link -/A << /S /GoTo /D (page.101) >> ->> endobj -1769 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [343.471 592.561 355.426 603.299] -/Subtype /Link -/A << /S /GoTo /D (page.13) >> ->> endobj -1770 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [359.522 592.561 371.477 603.299] -/Subtype /Link -/A << /S /GoTo /D (page.28) >> ->> endobj -1771 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [375.573 592.561 392.509 603.299] -/Subtype /Link -/A << /S /GoTo /D (page.108) >> ->> endobj -1772 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [348.452 580.606 365.389 591.344] -/Subtype /Link -/A << /S /GoTo /D (page.132) >> ->> endobj -1773 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [350.666 568.651 362.621 579.388] -/Subtype /Link -/A << /S /GoTo /D (page.14) >> ->> endobj -1774 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [366.717 568.651 378.672 579.388] -/Subtype /Link -/A << /S /GoTo /D (page.15) >> ->> endobj -1775 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [382.768 568.651 394.723 579.388] -/Subtype /Link -/A << /S /GoTo /D (page.28) >> ->> endobj -1776 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [398.819 568.651 415.755 579.388] -/Subtype /Link -/A << /S /GoTo /D (page.109) >> ->> endobj -1777 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [419.851 568.651 436.788 579.388] -/Subtype /Link -/A << /S /GoTo /D (page.118) >> ->> endobj -1778 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [440.883 568.651 457.82 579.388] -/Subtype /Link -/A << /S /GoTo /D (page.120) >> ->> endobj -1779 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [336.414 556.696 348.369 567.433] -/Subtype /Link -/A << /S /GoTo /D (page.77) >> ->> endobj -1780 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [349.421 544.741 361.376 555.478] -/Subtype /Link -/A << /S /GoTo /D (page.23) >> ->> endobj -1781 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [365.472 544.741 382.408 555.478] -/Subtype /Link -/A << /S /GoTo /D (page.105) >> ->> endobj -1782 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [386.504 544.741 403.44 555.478] -/Subtype /Link -/A << /S /GoTo /D (page.115) >> ->> endobj -1783 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [335.722 532.785 347.677 543.523] -/Subtype /Link -/A << /S /GoTo /D (page.35) >> ->> endobj -1784 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [368.031 520.83 379.987 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.23) >> ->> endobj -1785 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [384.082 520.83 396.038 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.25) >> ->> endobj -1786 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [400.133 520.83 412.088 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.29) >> ->> endobj -1787 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [416.184 520.83 428.139 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.36) >> ->> endobj -1788 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [432.235 520.83 444.19 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.40) >> ->> endobj -1789 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [448.286 520.83 460.241 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.41) >> ->> endobj -1790 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [464.337 520.83 476.292 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.58) >> ->> endobj -1791 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [480.388 520.83 497.325 531.568] -/Subtype /Link -/A << /S /GoTo /D (page.108) >> ->> endobj -1792 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [348.59 508.875 360.546 519.613] -/Subtype /Link -/A << /S /GoTo /D (page.35) >> ->> endobj -1793 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [364.641 508.875 381.578 519.613] -/Subtype /Link -/A << /S /GoTo /D (page.108) >> ->> endobj -1794 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [399.87 496.92 411.826 507.768] -/Subtype /Link -/A << /S /GoTo /D (page.20) >> ->> endobj -1795 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [415.921 496.92 427.877 507.768] -/Subtype /Link -/A << /S /GoTo /D (page.28) >> ->> endobj -1796 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [438.752 484.411 450.708 496.366] -/Subtype /Link -/A << /S /GoTo /D (page.15) >> ->> endobj -1797 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [389.548 473.01 401.503 483.747] -/Subtype /Link -/A << /S /GoTo /D (page.33) >> ->> endobj -1798 0 obj << -/Type /Annot -/Border[0 0 0]/H/I/C[1 0 0] -/Rect [337.244 461.054 354.181 471.792] -/Subtype /Link -/A << /S /GoTo /D (page.123) >> ->> endobj -1802 0 obj << -/D [1800 0 R /XYZ 72 720 null] ->> endobj -1803 0 obj << -/D [1800 0 R /XYZ 72 685.159 null] ->> endobj -1799 0 obj << -/Font << /F16 823 0 R /F8 826 0 R >> -/ProcSet [ /PDF /Text ] ->> endobj -1810 0 obj -[818 0 R /Fit] -endobj -1809 0 obj -[818 0 R /Fit] -endobj -1808 0 obj -[818 0 R /Fit] -endobj -1807 0 obj -[818 0 R /Fit] -endobj -1806 0 obj -[818 0 R /Fit] -endobj -1805 0 obj -[818 0 R /Fit] -endobj -1804 0 obj -[818 0 R /Fit] -endobj -1811 0 obj -[693.3 654.3 667.6 706.6 628.2 602.1 726.3 693.3 327.6 471.5 719.4 576 850 693.3 719.8 628.2 719.8 680.5 510.9 667.6 693.3 693.3 954.5] -endobj -1812 0 obj -[525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525] -endobj -1813 0 obj -[1027.8 843.3 877 767.9 877 829.4 631 815.5] -endobj -1814 0 obj -[670.8 638.9 638.9 958.3 958.3 319.4 351.4 575 575 575 575 575 869.4 511.1 597.2 830.6 894.4 575 1041.7 1169.4 894.4 319.4 350 602.8 958.3 575 958.3 894.4 319.4 447.2 447.2 575 894.4 319.4 383.3 319.4 575 575 575 575 575 575 575 575 575 575 575 319.4 319.4 350 894.4 543.1 543.1 894.4 869.4 818.1 830.6 881.9 755.6 723.6 904.2 900 436.1 594.4 901.4 691.7 1091.7 900 863.9 786.1 863.9 862.5 638.9 800 884.7 869.4 1188.9 869.4 869.4 702.8 319.4 602.8 319.4 575 319.4 319.4 559 638.9 511.1 638.9 527.1 351.4 575 638.9 319.4 351.4 606.9 319.4 958.3 638.9 575 638.9 606.9 473.6 453.6 447.2 638.9 606.9 830.6 606.9 606.9 511.1] -endobj -1815 0 obj -[777.8 500 777.8] -endobj -1816 0 obj -[583.3 555.6 555.6 833.3 833.3 277.8 305.6 500 500 500 500 500 750 444.4 500 722.2 777.8 500 902.8 1013.9 777.8 277.8 277.8 500 833.3 500 833.3 777.8 277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8 722.2 527.8 527.8 444.4 500] -endobj -1817 0 obj -[777.8 277.8 777.8 500 777.8 500 777.8 777.8 777.8 777.8 777.8 777.8 777.8 1000 500 500 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 777.8 1000 1000 777.8 777.8 1000 1000] -endobj -1818 0 obj -[816 816 272 299.2 489.6 489.6 489.6 489.6 489.6 734 435.2 489.6 707.2 761.6 489.6 883.8 992.6 761.6 272 272 489.6 816 489.6 816 761.6 272 380.8 380.8 489.6 761.6 272 326.4 272 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 272 272 272 761.6 462.4 462.4 761.6 734 693.4 707.2 747.8 666.2 639 768.3 734 353.2 503 761.2 611.8 897.2 734 761.6 666.2 761.6 720.6 544 707.2 734 734 1006 734 734 598.4 272 489.6 272 489.6 272 272 489.6 544 435.2 544 435.2 299.2 489.6 544 272 299.2 516.8 272 816 544 489.6 544 516.8 380.8 386.2 380.8 544 516.8 707.2 516.8 516.8] -endobj -1819 0 obj -[656.3 625 625 937.5 937.5 312.5 343.7 562.5 562.5 562.5 562.5 562.5 849.5 500 574.1 812.5 875 562.5 1018.5 1143.5 875 312.5 342.6 581 937.5 562.5 937.5 875 312.5 437.5 437.5 562.5 875 312.5 375 312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.3 531.3 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.8 312.5 937.5 625 562.5 625 593.8 459.5 443.8 437.5 625 593.8 812.5 593.8 593.8 500 562.5] -endobj -1820 0 obj << -/Length1 1846 -/Length2 13448 -/Length3 0 -/Length 14468 -/Filter /FlateDecode ->> -stream -xÚ­–eX›Ýš¶Ñ¢Å]ƒw-Š)îÅ  Xpww§X‘¢ÅÝÝݽhâRœ¢_Þ½gv;3¿#ù‘ó^·\ëZ+OBG¥¬Æ*f -1IAlX9Ù8ß$Ä?qr8Ù88ÄQéè$@@'0ÄVèz àäHŒ¡ ï·¼Øš@LÁ¶æ.^>ÐÁèŽ -½=PâxrÀ¶¦ 7È ª˜Íâ-@-ñ˜APÿ9P>^»Ø?¡€]üñØ%þ€]ò Ø?ü‡ø9ìRˆÀ.ý‡¸ì2ˆêÊâ°üCP-rªEþAµ(ü!¨Å?Õ¢ô€jQþCP-*ªEõAµ¨ý!¨õ?Õ¢ñ‡ Z4ÿT‹Ö‚jùô‡ Z´ÿC‚P-:ZüqCë€6vÐozƒþ“ÿ!h7“?Uhv0q¶1³†žê‡99 SLÿBè–AÿAè­`ÿ÷=ÿÏ`è¶¡7ÂhóW Ô³?í`öþ³þÓ‘ûtùkÄ?ëg‡¿ÚASÌÿB¨p‹ÿ ÔZ w; í_Ðø/„:eõBM±þ ¡®ü¥úÍbÿÓŠZj ¶ýµÝ äÏth1ä,CÕÛýY†6³:€l­Af,ãáü¯¨Ãÿp’ê-ôÁ?îó@wngíìøWhÄþ/„zñ—SœÐÿIæý‡@.9à Mwÿ9lèö­Žµ€ªø£‰*ÕÉÂô×ñ@·ää -ù«ÚÃù/„ºëòB rýëì¡ÕÝ5.h{÷¿jžÇqÐN ‡ú¿ÏDqqˆ›'+7ô~²rAEA…ó@ï4Ÿ÷ÿÈ4qv€úìô¯_è£õ¿Ù }ƒ@n Ô刉PeJCH±Ï‡¼©D&XqóÆ8ÅÚ®Ùv´À¥xXëÂ9{¦õšO÷¥é¸»ˆ»”®¤Žm^*ãRgþöq©óÏ».F»éͤŸ.ÒÜÚQßa¶6Ì]óÂ*ͬ'iç÷gþ8úªÌ ©¾‡´JÓ­ëR×ÄÇÿI*ÝZ#4¸†ž›J+Õ¾8Œ'tÍ+)am2ÐÇ2¹‰yåÒæŒsŸ‡œ“ølóÛäUd¤#IØ¢Úëï'¤¢ÞÍuü¬‚¼=!ÛY{eÙ Åõ -ì¤]?u6™¥$Ü\›oôh¶[ê(î·%׆KI…G»€qKï5Ïw<±Vm§¥\˜Î!·#A@>IÃCÑAé5ÄÉ<‚²ñøÕåÆÕð*ý-S±uã3Ûà›}¾!m‚W?~Š®‹æÌ8 xYwJ4@všÌ½+O¿&„‰G#=W_Á–Xx”Û¬ìpÙ+º¹—]úú•á’-’‘¶ÍOì|Wqâ½Z_6ê18ݹé [vr€Míwl°6L wDxà3•ˤY!ÛÛ3›ø¡¨Ðõ*áݱ ¥•4LŒi'”s*×w®0Á5à¼.B3âvLŒËþw¹œ‘_CPkZöYWÈ$~Þo$¸¢Ä²‰wݶÃ,£g¸rÐêÆÄ„Ã7S+§"}ÑÈóQÔ®`ÊâkàÉÎíʨ¾¾’Q<4Må8B6ðtЛ•éF±^0¼bšÌÑÔDÅôú˜vÌÿ~ÉqòŒ6RrW*±(@[a -̬ÐIIÐ7~\˜Ð‡!ùÔq‹€…MÔ¦¦¥{ñ†sïÖÞ§Ü^§WHŸÏ½1hø½Ôî¸0êÆô&}µ"÷äwÛšý>É{c n—¿ã bûãˆöõk«¹À§ÁßûS´ºRï@9ç,ôCßN±œ]>÷žsJ.jÊú[–‹e{‹hJëƒÓ/PyÇ­|0sʃU&v( -½–R±¾VËsß? „°q X“ök‚l–…¢^kÛbemU—Ô¹ßÞ空—×YÒvÐÏ¿é¼>Ù4׎!t#ŠÍo{@S³"Uu´&¢CPRêø·úIC­€&¹æ‚\=Ÿ¸ïóôk˜Öq°hxçW?n—œš}ZL82Æ¥ È»y‰£Zžë‹¿°Ú¿–è•»FíƒõN+í¶kÐMçzj?"ËiÙµÔ;í§Þ0?Çsåù°Ž(IüxW-œ´ñíx«‘_æMAÏ=Œo¸yŽÔÄj¬Û÷ s!cé:ÂÂg3âÆ-Lc–‡…§¬Ï ’ÕYË#Ÿö£üsø°ÈåOqèA½U’ƒÁ%þ}Wb°ä³)%˜~Ëë€wj[Ú{FÚ ±JsGÅÏë _~„×ÌàhG’õ «l4÷WH‰cÉðn€ELü%4Žà‘0ãͲ¨«à‚sNP<\óÙògKh:òlW\Š“kU§ÔÃEç qzMñÎoµ–%ºä‚FAv2·š'ºÕ7îé=öeòÀ8êjjn,ÚÉã´4 MM±ï¢B(ߣP_¾S°#Í"æ¹~³’D%jÀ段ŰðÙÚëc”©™Z\§åŽóë;cñÌœWâª#Uc{¢Y¹mê­Ä@&isõGŸôP•s“Œù!¹°ÑŽ±Âƒ^,"Ôý\‰ ¢ÃâS•"äC‘méæ¹:Y~³D£›ÃWÎ%¿Ý—“ýâŒÊÕˆKX€Áj†ÑQæ?W‡MpfÙ$öFõ3ï £‰ å ‹¨$fÓ;!1ìâ/‹‚zùz“Ûª4¦TŽ3|H„î r6x@°ß†ò½øhfÑ¿cl“ÂSˆ -Z[0­=äÍG€ÌFw"ó NrèÐ"QG.où_¼Ý.zG9]‰N§9Ó¿_+VÐ%ÍÝ*½L“w -Ђ/÷–>QœS¶û¾ú0Œ¢ß½Oõ«Ÿ ö`üWúzS|#wݸ¯h³Ül;4té·Ÿ¹§¿{“ôîÝ݇Žké¦å·Bΰ¬”É¥Ú`'>IÙTãlˆx·ºý§ÁµÏ-ƒ!nÞŒ†ú°k-Îa¯„V}F0D+#‘gTXÍ 24O~dÁp_Ýî.¼'"u™ñÖ9½ócåür©cji>:GKÚyË/¦´,E¤Ç€ý¹þl2w‰Í©0RÕ$‰oMK+p;K݈zÒvj¹äS¦:\ZEÃViùÓ&ÖpY4,$ÊÙd_¿!6ª7 ˜éWô;Âm<¤÷Ͻg±}‹–Øô;Š>ôŠäÜAFåh¨x÷w«ž_sãY¨Þ׆w#_¼}¬°z,ËŠ[¾¸¸Z É'Óa=¨”åPz'|ÒӜDzL«ë4´rŸV\ûXƒØ9y¡˜ÃËѦ-ÃêáØßví$vGePq—7E€ïM‹øµ½þ—7{|ÖÆ6S=±¦yЀÉj¬8㾇VÄ6Âï'ó!ÎÉÒ»ßIlà@cÒñÅs‚à rWü€@qßí¤JRÚú§¤æ“)ÉóŽÞA³iŒÆü™ȘÔDÇ”…âÒAñÕž&bæ$ Aa>K8ýòSWo'ÇÀpeȬ×m˜Ü¯ ¬™¬¹”qØÞŠ#l¢FK:ôuôZ ã+~T,×µŒà3q‚ߣŒ]–jßvý3?l l< - ü=F[n5•ê@ê€À‚OÆ-JqBñÔp'ÆSO¿ ƒÈý:e©QöÕRÈ-+kŒIÒV莧 \¯Êõ• îîr8ŒÞ™o¹Ûáeiç›=±%ˆ?°‰¥ëæ–æÖÛ8f2W™·8„]Ú3iƉÖ9° oôZ?øaÛÃQ-Ù‹æ½S×»'°¬roè&aÔ­Ól6`Ç¿P÷/ƒ” Ù¨ðU0ßöúâàÛïHáD4üäÈj‘ðX(øÇ´ô‹¦ø0[¼¬žñw‹¡íÆ¿ÝÉãï׉*3¸„ÊÖëSãY{ãd'Û>ópvD»2Á®7«#¾¡ÅY“.:M× 2beÛ•Ö…­+û6í¦Vkºyr ÁA;ŸHœpªrÒw_N9æOÅ£yèŒÔÙ©”ƪåôÙ¥@ Bùq]?þ%ó´#¹óåxˆñ­ñZ -1ˆ¬;Eüûi>YõŠÎÍd#—påëåkBÉ"ïß-I˜Bìû%'CBkoxàG©¹¶p3í®\¿Då0íoÔº2‰?õ4¯Š€}‡içÚ/]Ò"77UÇn_“ÏmÐÛÞËùÇšYp -žÚЧÑÛiÛTr4cÇØ…oŠJ¥DrQ†Re9wQf?ð;1RŸ)ÉÃr® -èúH¢ȤÚEYUàkß%âPóü𥠤ÓÞY¦á1í%Y#”Ppƒ-ÀY¬ ³ µÖ²gwU4'^SKùÍû•§ˆÂ–ç<ð~7OÜ6»Kwm#<„ lNLÝT~ê:¡EÅ}áÂ7Å]‘÷€µ¢ÔÙàµ{¦œS§Ƽ©&a¶ -69:¼B4ii+¥9k™nO ‘PõÜRž!õÖ|R‰ZAdY÷²ÖH› ðöyi‚£¦ä—.oTwT¼ÒÀžÞ„YщÅ©ÜCÒÕZ¶}QÝþÛ¼iÁTÍçívÂWð=n7ƒ•É6ˆ¤g­_{*Õq&¹Ê«…e¼e-_>ù­=ÖšÀ¹©q|©ÿ2ÿDŒÔSïò3øŽNÆd’v’OõÖá ùéo|÷Éçc´˜1R±Ü¸çmpð{$q’on­T…C¸kþ ’º/E‰œ^}ÞÑÔ—)ÚöŸäqUCpòØ0T’ý”JO~µ¨¯Q½vbâÈøûOÓúNïÂËpÑ86L< •k’á"…8Ròó]pÈ$·§ì× ´‘të,’(üÙÆBÑKs¦‰ÍÙœ÷îV×Y䉿¹¿~‹™÷‚O¸ˆúµ+¥‹%Zå±+’zò5/ù<·–!sÁâŒ8ˆë‚~2“¢7þôNZ)<øð—òZe‚§¯‡›Žï³f=kháê¸ýP(:Њv¡]ñ£|¿$í‰L“WçWBcßÕO[-Úv?;^õÂ*5Œ¯wqSaÌ7òþ`Pâ„pNé-¼¥’ß=övX$ˆf;¦ŒY8ÆÂßÕ蹟÷­s» bt.V/Àå‰Ü¬’…½c-`7%Ãl÷lO¼;E¤@ñ¥;þ-¸…dx¼ÚÁÃNty<êeTó 3-¶Å+mú€ŒL'^›dœLÞkêÛêwDeò˜ªV™²l…ˆél.î²óW÷åÜŒ›>œ¾:Ú{÷xÉ‚Üh¥4ýø`Òá¾\d¾J}ð5±œó$&›cD½Ã¼»2ƒ8Þj²ìžþ×(ÁC¶´Ù?£×¼]­½Œšw”F$º&KWëO3©áÊæ±øesãäØIñ:±È~­jÝ"RÁ÷ êP#ú•ŸöQ -³„DƒXæÅæwû ôÎèš¿7v™ºæâñµåÒ¸×ÊÄwÅbÛ;/Ö I6÷59µmfÉâèÆâ(1öíH>XY/O AìKDò°ø4âìÏ_áR_µæ­gxšŒÖn Åb“ÅÆgÐLE꡼¯Æƒ£‡×ÊUku@Ÿè¯ß‡M!(1?‹ª<íðúí´#OSLê=>wè-$ˆÃY wå©•S¨gÆ,°X³L³ÏViuÑ8§. ’æ'~åûéX¨Ø„ÓØôÒÚ]ßôÓ‹è›_ÈÊU„¸Ÿ"J~«×jËq£õ÷L³•DŠàH0Á—Ï;¯Èš sÒÚ¸oÔ£Õ&‡"—-a -ÞùrDn/•Y°˜:t%G¡ZeI"¯…âË£^ÕÜŸ0Ž{œÜÑÝíIIKRÄùÖr]ÙfÔº*‘ÌÁ,f¢4™äÊ ÎµÖã³b\¼ùŠq¿<[¼áNõ– UâBûl^Ô­tV2¯J£_uÆ !èª m™ -Ü;ªéÈuרkJÛ¯ƒ‰Þóv܈˧ .@ZÞ6iLJT©nªétW—çÖнꘫüö†'7oàÍF©29)öÍWcŽo*hCr¥0”¼óW[ÓÍíµÂŽ/mNN®ó_Ò*ȶ¨á[V .’ÄgŒú;„h©îu/œ% ¸G ^åŽYí‹-ýC¯n»‰3Íëï(wc«”Våu)±êTq DÛ4Wüx·Ócà±yô] ï>ê•Ô*—“¸ì AGÆ¿¿¾äÖÈ|Í—=wåp%öâí?ÙN‡ûòÕeG–QÁ«,®^I¨wa„“/¥„wªÅgö(kRÙ»[3·ìym¾Œzî{U–8pùäð3ýÜ¥ˆϹì^S¯®0#)_rW_y·¨Kóó8Y†¡Q<‚5]¤jNN[;Œ:hÁ¯%b\[kjaÅ=ssá~¶Hjƒv®hêxBÇHIÖÞtñ*ÔÖõ¹rÄ Æ½u>ÇöÉJ²Ð™‹+Þ²±ƒ¢'Ü•dDb‘a­VÚS¨DªXh†Id$–ØjR¦ßÉ÷n¡Í«2.ÃS0û -ÿR©fÜÒ"½i뜖*/ù]¬ø’DÀÈ’C”ü›¸¸“l†¡r½—àD}<8 -;Ùßi*Gi§;qýñ¡`ýÝuOì€ -KÔÑQ~ähÀ[ôJq3Øch u÷Kƒ÷7|+…ÒÖ EÎÖ¼a¦„ ýz#¯¡ ýbDLê2iÑôµï^¢ÞDehZv?{Ê ^Wìœ[_íë뀂j_˜óoa(”¼é„“(>ÜÈÉ­÷þê­¡ïÛøêûFpʇ3&ި壒}8ÅÛwJ°&èžIoA;À}E”X룙‡Æt¨aÈSêcÄíˆ'ÛÞ4,S«6ýC0¯VT­°'+eýJÎÊRà«ÑÐÛDíÓi¾Z'>…šìVHc|—Ëç.L*õvøqdJº»w±C0yjP“,æ#!ˆòóqÔ7Æß猖xµÛZä{x?.SõM êù8«[™RLe2“«ÃÊRÙ‹¼±Äš(ëWhr=W¬}êíOº‰Eµ_¾Jí ~¨>GzæOÌÞ×¥qúÉFûj¢âocßø7g)}`Á.©lô¼›¡áÞÍê¡å"%«BŽÉ%Im|’=ó&V©ý‰y¥ É6‘’®té£ZOí Piµ¥¶ù¤Cß䫯B3øEÍ«ú|—eKS g‘ 1+;:'%%ä“Üáá8cf6ð' Þº9Õ7œuR{ÚÜîÄ -7æŒ3ÇY„Ù÷k‡uÝÒlާÜRúwm~·˜¨Aû WÍlsPì/Õ€.³æ³†OÞ&•ha8m{þc8¹¡€ÿ ,ÿ'}퀋‰Ô2˜ãÐÌŸS4Ãd‘-µúUY¥ÀDù`îÅm߉ßùÚÎÆâ¯/rì¦WˆLY„$lÕÌѾgâhgAÞÕykÉu•…$ž£syG{Uê½ýaíq,g¥Ójræ(R‘ê†ùe2¶ØÔ£ÛcóŽa õË =B„ÌÚ>Ý ²Hµk»f÷=w‡åN~ô{\’Cá¸òˆd2ê|¥Ê€½QJa¬ÀÀ•ãuëdÊå~ý´2¡…bùÒãKÖ°5DZÂ[–nú֥ܢþ6Œ2Óç°2¶igèæ©_«Úáôo‚ÝÏõz|íÂG«›6ª¯\pî†.Úíê³$:ÆYÉ)QmnÑ4øÁhÑããG ²ÕºO襞R*eÙ1„ËJd¼%”—]—‹•Ï{61ÔÙmñ»R¬3äGáë°PBFURJ°Ýzi/³bõ¼²ýõ=§9%|°¾×¯`Ê0&êò\ ìõ:e~ºq3íd%c;t¾é)µ@¾…ˆ—ªÓTðøî”kùø¿:±¬“]"PxR²VihàÈm¯µ¯Â$“Íø G@V‰k7'–7.Z1“õArß—³õŠêbʶèáûqdoòk=Rt3<šÒµV-”†$wWœ2}¹{çÙg?ŒÏ½Zyç÷×È?çKªˆ' ÐÀB¢sMûîG (÷‚¯*,wd:=ž¸—Oà~ð³C†Ûñè$ͪ“"8ªm¾ÚžeÌ -Só9åW¸cþ|õ+2ß·Ó‰ûŽáK¦åô¢s«§z8е_|·.}â0ÖâÀæT6ÙK:Þ|4'~¦l⊴öÜœ5öÛ+×eIëö¸ÁSJää -Û\.o.òЀ9WUÂ+ -„Û¨xN0[¸á°T¡Ùà;‘#åÁ|öò‹=v½ƒshu÷a»ðøÆW õ·/¢ -–¾ù¹n¦ü…ož)Ðê„Tá+ßwßÇŒ]čޅM=ÚW"W\MÎdÖ€0ÑKÆ2ðzð›ä‡}èÉÙóçr|Ü—Oô'GXŸ>Üífs÷1À™ -h²»/°4|ãW Ï·°oj)¿~…‘ì$ÞNyf§uÄxÉ/dôÁ¯ëŠ‚(繜7T¿BÜM›î]ÍÇnKw ípýzR{§DŒóöñ‰y0zVÚLÎI½Ü•fkÅ€z£á {Ã=7@“9,Ù€O߃‹ŠÈ¦om¤…æUOC«Ù´F˜?!}¹ï·'Z|Küöø=}g'É©U—O^ëZ†§ºL°‘+ÏäV–t—¯°Ü—ö¼cäsp9„™+4¿l}ÁóIÄSlYq–—è´ÞÑî—þÀø¦9É@ðó¨•gŸÉË9o5¼þP{‹Ÿš‡ï8åĉ<‹\¶k‘—ÂhÆ£XËÑõoÂ…DÊÒ¥1—͘J]Žöðî7îªï0 Å…òçŽ -?liP½ò•;‰ÇüÔvß“!ô44 _)®v(üüãhòÆ='Fðòö‘¹;pDUŠPnSJ—7i+AvÊžŽ/kZW¨ÿ6hÌ̉g£1 µ¡©jSÖGŸ=NAù"…âú]mÚ.ÒÍUäò˜&\T3¡g„;"sœÅ(|hžÙ;¥œí‘j4Ú(ã­£éeìÁ·:%ð±–E޼á9Ä/Û‰ k2OÄØ#²vì.žÍ«<—Û?œ«`B­WXM_uê¡4Á¡“˜‹EHĽÍÌgîN˜Û‚_ |\å2ˆ¥=ƒœô™>Bê* °8 -±Ç¶Ç ½DÖ«ÎEh±‹/a›œÈÙIoÈÌe–„$~¿›Å}"ŸÌû)X:‚ Çœ5Sˆü}Ár5ÞÝw6P2Þ°hqõTd`[ÞófŒúÁiØï°Æ˜q„OÒëqåÓÐú’ ã…¯±ç5O_~}N`ß•‚åVù½¼~u†£»’›±x `ƒ¿`è›^Óð%²ÆþlQ4!–Xá‡ßg*A2¶ý“ê|™‘åËk“p²ïö“nœ‘ûš±„5Yˆ •Ô´”?[íÒ]C–€_IÐËV×ÇV=ئ¿Eþr±Õ­?B£ž_cAdó<ÐPyšfy)$åzåÅçœU¶üy÷§XÇ=bÓ&Ïíãôø.é[÷ucëí8׈:. - p ‰ÇÉ¡5\äñɇó×9EºKßìßTpQP­&µgdžßT¦P°ïÔ¿~h냠îËï®¶Ç%Úz¼çÍêð­hÿòN¥(µùÒ%ÂíÄhL<ï%öU y·IÛŽ*q댒@HÇK@ –Üõå(ü£­s˜€ïÀÚï@ň¸òkIOaÓºDý´;ܶ¢5ž©<ìä¢3ópú/»”U>ýtkÌ[xëéÞÙ­;_VuS9c7ü4LÓ^ä¾5Û­O8;wí÷øQF¡± 8ë5§ÍGÅ4esSÝȲQÕ?§‡ÔúbçWÜâB èœzêd–o‰ku+Ò@Éê pHų́+¥ÿê•îÓF‘nA!‹Ò톳KPù•5¨×Âk©?yY*£µºCGg‚Gnfå¯,ùòØÀ*"úU] -Kµ|—¥ „ «‰Km°L_Q¿;ø.önZ® ƒL7¦^oƒDž,,½¥?4~±µx"㹸vœlIª”vò”êŸ 2”zfŸs™h)6é)áK³Ì‰ª ÌÜ”å ^°PœpëöÕ<´ðÄó§bï3Üä›’Ù Ç›.3;˜üƒ:…aRÕ²mÉ‚\¥`ÃßG V~Y`Ä~$ŠìÆF2Æ6Þï˜u¢Š u± É ì¢B2I:*}žÖºX¸=Ìý!ó,~””‡ÓH_ìõ`ý¶l¹búGÇ -' -EkÄ;™×X[o|ÜØž.ßÂb~´„IèãÌ­pÙ}ÉBf?›Q‹R¹q&·è¬%˜LE8"›2ºäg®žÄ’^­^ν€ùÛ‰.fuˆÉãüW4ôì¥`Ûß³ô™C+ü¸-ÂqÎë—™Ön§5ÉfåÜëÕek D] -«>†˜ÍΙîË–Ì_ã,ÏŽ\ýg[8›äC];bÈž—Ûì[Ñ•¬ŽõL6ì~"ëó†æ 42tŒIà;`ï\™š±ÓÏŽñ){VóÆwB­¨ÊwìX"/Šõu“!uvÍ ÷oí7³.¼i¸áüyŽñírßÖØË^.GÌű -£ â’S6Œ|#ýžphW66Úž÷=ñ‚x«Stê·¥»…!ø…ØüÄnhÔx‰kU3¿sk_/U¸DzQjd[¥åOì®ßvc|}ŒÂìŒï9mÎI“|wï¶"åKÜŽÎIÅAKë§X —º)IG(̃wŒ÷ñ”÷$xc¨´ ¶oAöÞég=&œˆÿ#–ZîYv½€YÊÑÛ¡ÕošÓ¼²=aÍúß‘[[,1b©Ó×ñ¤ZÆNÕYåËÃaA¶ØÃ#GáòäÀTÉŽÆ>Õ±’¼·à±€íú[ÜÕŸ Fã:©ƒîu‚gŠ­+úÈšK+‰)2=MJˆñ NçfJÁEŽròm¹b˜wi†öý¬p8 Ï‹Y²Â€——’—ñågíÅ‘¶•T}ÀjªHü °EL™)¾qáÅ)q7ÑË.[Ôx œ~üM³É;'µëEÂåcSöÙYŒ¬¡ ¿;ûó÷õäwê{gÀU)^·— %,ÿè“!uB ÈýIQÅ6ëÈ6“-½"‹æxgÊÜE—;ZK³®¼HQ -5Є¦~ïäæ§G¶Ã<Ã4&þ!eÔøl$Åá£kû«A.´°È ?kŒ<é°çîD¼Šõ5Ìv yh}°öaRÖ…“:Z¼÷aígyx܉{G[X •øPì ³WèD]ð -‚ÈlÞ•œ:%ÿÇWæWHÆkBå¡\4Ioèù(eé•üÄ–ßÄH§÷&Íâß ¾÷7?óÓÚ|L*¢ãG&Üã±S‚Ò%‘—¤¥7´7Óâºù¢€ömM”8Æj¨ûVƒY|w2Û¢“ ¸Qšä^JƺÒôK|¨4Ñc)ûúäRgçÛLgeæØ•ªoý`t‰ÖŽ8i@¾Na%q&æ¾ -ßóªòTßhôÝÉ”nÊ›zY¥rQÔš0 ‡î§ÃaÃðœYeoïKmŽÇRh¼¶ .ãü˜âUZ1[ß”Æ<+Îc´ªÞ›ïñZO²^Ë àH—i"eÔ5¨n"Eˆ VÜ*E…'s+4Dî"àþüaÄmÕtÑç“sCG—m«eÕåH:oéxØë` -“/é:ê„ÎöõçËÌò¯¢œå´ëË íèŒÆö$à]êˆyIf©âÉ0ÓÝNûÆyWÉÀ þ…ˆ·x.«]®áKBH Æ› /Ò0K"6Íã}æ€ó#ØÈ ýÛ”Ú²ÜbùœkÚ,ýýïÄ=Y(c¹ºüÉXu[Vl›©•ižœ‘矱gIÄg‚ÕˆòÙø½6.ͼL€ç4„¥Jgu¦»‰40ûø3mŸkÈ¢½hô)°ì¸1Eyî€Ñê¤gä ­àŒ‡¥£° - eòÒ¤a‰GÍ€:c@_@hûüäH~Gßtq¼jÄÖœ'Í©-HlÈÀz_¥¨Iû¶Gâ ¨µÞ8·I‰V¸Œ!¨+ŠÃ'0NEê(òÖDÙÌ1i½ -Xlµ -FßÒ )Ò)Iöý8ãÉØë6ã0è¤VsíÓñ 1è.Ò^Wäfþ8önhªó:lôÕ:È: Œöì¤Yc‰ÝN¾ŸÎ3l(AÛ“FÌ;™+Õ›úz¥ê§F¶¦g²Ÿ§GÕgµï¤‡lÜÁ¢¹„rÖƒùmo7¾Ï2í¡¾xÆli8ߟ$;ù—I“i»osܺ5lϨÒýYè $GJÆÓ°¥ ùÍmêÓ·¢’$6CŒŸŸYÔ6>;‚{~êãèÑ]Î]ÅŠŽÝQÏ) V’òÚ™^7>×´‘~'Ù|d÷™®h^dÙâ‹gÔû¶I—À2®¿z6`zÀ¾¿¦å*ýÖ§¤ÎöI~¥6Äcx€æs,,û½™>,¢CÞâ}ÌgÝðêaa<¥¦Ï21ôZ‰Nç´Oº¤br³HO„è=v„Œ£Þ?1|ÆÜ|än+d•¾OË ò%~ØßigZ h~«YéšÌöžúìFPÊmÅ.}%üŠÍ-ó6+ÓÖ€ -•ª9_—( -‚ºg—­¡ç‘ý¢Ü+g7\»-ºÚ¼A]›¿G¦ 26|S‡>Ù=Î1j[ßb.P¢ht<~òsØdfî0ahõ{„[Í)ÊMq­péœÍªzñkf$åK6ü_€±®öZïÕí˨.úzØá~¹&û”ÄÊh›c~=¨8qxƒƒ/{³=k;ZÝê2]YÁŽdB ó5Š ¢û´tLÄ}¥©ÖÙç଄õð—Lö£C DÁÑ /0÷K9ÖæñU'Ðæ¦öõBÐÔâ :Ö€“ĆV…_i_µ‰+Å'æõ%~Ã]Îu„ænûÍlGÖò8šækÃ.´¬kC†º†/ü•S¯'b’³¾È½'U+ŠÊ¹È½¬§¯\x*m¿>›’²)“¸ ø9Èé\FâŸõ0²Tµª/ômÁó€ßÙ²¥bç«ÐÇ ¦˜#þ¥qmã×Ò§æIFØ¿‚É$AÇ1ØUDy -æ²ØÀ2XG²+¶TkY€sïÁ'äý=2Õ¢HVXO;UÕ51wטa_`ÞÏ\‹Ü#iAü:áydc›E‰9,3¤†øôª29JÍÍÊÞlÖLúfWrÞrž7ssa÷G å®ï«[»BÚƒ/cz6ø„3³)´ü|/_üC굊ÀÎ f­œi†iÐGþŸß¸¯®OwÝÞ´#Ûò„aa !Õ›~\k{,‚“ª íþ<Žy1¢G òµ’ 뙀ƒ”6O«hÑШÒT¶¾£#FlñØóKÌ ‚z¿Ê—¨é`dX EœøPq„R—“òÌœu¯N$§^ 9"ÌéÆlÃÆK¸k M{Šþ°}íÛpBÔßïhDØÇÑ×D€Æœ{aÓštH°A÷«‰ÈÏ!5Wµ^\cÜ´¹Á+e_BÊ\ TÉ¡˜åG_­`ßh†˜Ø"³9;áGäñË«9G16«åþž#®Ç¾µ¹ø ¢Ã)ÌÏVx³ê˜HöDŸ\‘Áë&OHUQûáRô@4‚ìüѶ ¤o˜v»Sy±„ÑΑkV·ýí\Ïñ%BalV±¯/Ú/œx™Ûíi!e úœæ¯6‡jÒc¡;àÌ×Ý -í¬›ÝJÅ›äí~ RN¦‹AC몊ø£=Zd~ÔOÐ¥§W³ZŸÉvïܨH¢û%¸;?zµõ8èóÍï$JAJcã\­rÖÉnqžk³-O%RAª2½Vm‘%ÖÅZR1½H~ÞdC¥bÜ#¯á\f¡U¤"Òž.ÓNºóH埭½–¾L2²ß\uw§Hå”ˤÜX}óTl®E§kºÜ£|ûX‚Ì3õÓо ì ‹Øew»Œ26oò³3ó “–£Hú¿ ±ÚÞ»~ -1å¡=ì„y87&YâäSJ+ Ž©±˜ñ©¦>ÙU}ÊãÙ…ë)™å¹U­±–ížµ ÀîÌ®ûu†ŠõK3Œø¸þˆ$–×7Cû¨Ö^‚9 -%@qqÔ›µ¦¬O€—vÒNY¶#Ý9q4z„\ Ó´¼懆hߣ? €ªd)rwäAüþ½ä6§ÌÇkCxÇP~äIÇþnddù¼œóÆ:¡2 X4±`×d«xj>6ÿJO>½¨@®_òÙ,#[ud%5Á{ݼhÀu6ÅYHzdò·Ñ’š°öç÷ -VQœ9»˜þöç3°OdYwz0mðôr.|In#™?© Fáqˆ?O·é¾è~B–Ã|f<žÉ“Ä\»ÏG´¬þ•LDpâ+t®+Þ(ÖÌ©ühûˆbÍ {% à¿’ó]t¾¤V—w\¬´VÖì¸a¤{êRÚ¥p1z;7½rþû£ƒÿ`Äúì^ʪ5• -î;O·{‘/ËÒCq'ÜTÆÀ!mö{'’“©µæî¼ ïŠXIúwÓ©ß:­nx½ 9¼æB†“dþ×SQ¦°j^˜º]]`™½ÆP6™‡ŽïÞ\Jrržku£¯z\+Ð{pâî1XŠ}ulì¿Ìs`D‹Ô|c%ŠãÓ\²|Qˆ{?4š$;àâGÿ5/Ü3–À¶H Õ#ŽèÏΈÓI2’‰x‘Ç6j>ï'Þ>Tàúð~Ó*Êó¤ÓšadF%GÜþ• çôú)û AÁ®Oa)xþˆhÝEÉGN<< d]àl64f´´/EŽ£xóz‡-n• L°'G„s]Š@¶;¶Ç™€Ê8›O}-¢ðÝ=g É MɦGÕ*99÷õ²¸ÕŰ?Ì|6r9ÝÛ#êv·c]Áy ¹gÛ6M:ÎÎH¥|ƒ©RÞgˆ®+¦©¶>>Å—8¹UoÆ:͆bšë¸c³A/ñä+¼c3z ÍàGAÎ:ÖÙZiOZÇnˆeâXÿ‘tÅ!ç*éQcªÃv»…žT3/Çë“í‚ÍO½Ww@åðw’,þ߬t´õä}û½Ès™ý¦'`—´C©ý#¾«^MºO°ßbx¤¿Ú3}£›[µ<ü»—æDH=–ãñUSî¶_‘¶Ñ!²ÒʹQ£³D˜«)~O¾NçAýíSÚš´E|Æê=åoüÄû QO\y%ÆÄñë&®iÎ2Ïhýn‚'[1n\0l2#ÇÇàø¤]åqª-ò,DW$Å5IJ§²›¥ôžaÖ÷_YájWÕl¯mÝJ w”ÃUaC -u¤0ßк’6ÀÒeÖ1bjÞ¾FA±»REšÄ#/®i»ÄÐdF¨>H/ð¡§ø{ɘ'™ÑZ<îzã¶Ç ܸA«¢Œè4yîõy£¢·v®'£Í{³iÛèÅNl2sð]%γ)å]zòŠCdj Ú´å ÊxpFÏQWVf#Hžà§v)-—a‡çد— úæüû^‘Å7}v#øDÔ©]ÝofQI‘DólÏW?ÛjÐñËHr@Êguc“Š™å%]ïžZ’3ãœß»uE_cŠo÷ ëŸü "“‹/q‘!Û¢÷Ç -iס²… ²Lð{ó½DXW(i37ïC7y%Zþœ‡Áð\~`8Rß#ˤž¢‡¤ÉûäÂn¿ ¾_ìv¹ àƒµ¬2+.•˪ì4Rbö`¤ íuE”ßH›£m°4ŒÔ´Ö5ðýKïéÁhмíÑæÄ'Ð\íPÃÓï2Ö䜑¹2kçMín?Ðýâm /º_æØGq* -ÂM1J‹»¾×¦™,#Ʀ!W}íF2dGæ7ˆ™FLˆ4©½*²,Ù¸?(§‹P©× à\0\ídØ—¬EJÖÂ{É@·Á"mwS£HâUŽŽ•ÕßW)S¨ù‹Q×È[%QÏWxš¦ ÛéPgP9«Û×?M|ÈèǡܵÛHb¢óQ÷ÂR8²G2½¢ë—«Æ¢QŸ›%W÷%Áác61‘p«@:½[ÔºZ¶=äöVÜ”’–Óßd‚ ÏJ/ÁмOjç•/°IFWĽÈ,Ÿü‘:"“­Þí¨¼vðk -K´áŽÀž¯ïcuˆW$~Ðô³ÝQFÓdÇœ·] x £–:iL-EE}ûQ5аŸÔam¯”²ušŠ9pÑdôjù÷ŒRÜ|äAx@Y3ľg¾Y¾¦ék5—‘ehu§=zñ)±¹Ú–¢ºÂí)’ÙÌjã¤%#O³ÙøÏñö™w ˜\„—üT{MEO ‰šT3˜QášÐ–ç‚eI÷û¬™÷>MãWòûv;"èŸÃæè ™'LsõR3ž$r¾BvD瀙RûLÃ14 ³wýL·MŽ® ƒ%îuÅdYP*‘PÏ–ûÅZ÷‘ÜŽ“,&k¥rß„Êð-ÿÍ·l”¬6‹@Çν3Œ‘MÁ3JàØÁ§ôŒžu®ñ¢žEê£pçu]C±‚Ìþo(έhË'Ó`hR-ã+q´Š†ý -Þ0 [MÃÎØÙªè¦AD]Í5TÅ%!>#”ßËBdÄ`G$\&Ð}j#ü­ÕßÓáîF Öªþš/;òñåQÐðŠqdCÎtd\‹Ye¢®1‹W -GrKsØŸŸt1°p¾Õ0»ðó¯o”×¼’Gìðþ…'’x‚¯X=¹æYœÍ®¦CñÅÕU.~½AÞàˤ·óTV„êR =›~ZoÖwuß,âïð”Uµ‰ž8¥¥&ÏÞ³‘ÀÜÑt)Jj¡,)eG, ´¶JQüb²¡{ñþl°vUméW A§«–XLžÈ˜5_Þ÷«"cýÖ̉)5>¹x´ -5ßm÷N»…‚õϸ÷}ÿß k- -endstream -endobj -1821 0 obj << -/Type /FontDescriptor -/FontName /IDSUQC+CMBX10 -/Flags 4 -/FontBBox [-301 -250 1164 946] -/Ascent 694 -/CapHeight 686 -/Descent -194 -/ItalicAngle 0 -/StemV 114 -/XHeight 444 -/CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/ampersand/b/c/circumflex/d/e/eight/exclam/f/ff/fi/five/four/g/h/hyphen/i/k/l/m/n/nine/o/one/p/parenleft/parenright/period/plus/q/r/s/seven/six/slash/t/three/two/u/v/w/x/y/z/zero) -/FontFile 1820 0 R ->> endobj -1822 0 obj << -/Length1 1799 -/Length2 11435 -/Length3 0 -/Length 12422 -/Filter /FlateDecode ->> -stream -xÚ­•eXÌ–­qwwwww× ÁÆÝ5w÷`Áww Á‚»»åöwÎÌIfæï}øÃ[µk¯µWUwS‘©ª3‰™;š¥Ü˜Ø˜ÙøJâÚlì6fV**  ‰›µ£ƒ¤‰ÀÆÇÇs·°³ظù98ù¹8¨ŽNÞ.Ö–VnZ ºŠxbö@k3€’‰›ÐÔÃÌÄ îhf tófˆÙÙÔþ9á -Pº]<€æÌllsk37€)ÐÒÚåGrŽž/›»;ý÷–ÐÅd -@ 2IY4wt°ó˜-X”AZ@“ÿ¦þwsiw;;eûÚÿ+¥ÿ³obomçý_ŽöNîn@€’£9ÐÅá—jÿmNÜÑîÿÈȹ™ØY›‰9XÚ¬ÿ^²v•¶öš«Z»™Y,Lì\ÿZ:˜ÿo  Øþe€Eꃬ¢¢ÃÝç¿6UM¬Ü4¼þÓöŸê1Û¥ãbíÐcefee‚þþû?ƒÿ%&å`æhníz\ÜoÐËÀ— `í`ô½@ŽY˜Ý@G HüŽ.ÿ\'7€E쟥7€EüñX$þ/€Eòñ¦ûñ°X¤ÿ€Eæ±Xdÿ€EîôÿHOéô”ÿHOå?Ä ÒSýC ½¤§ö‡@zêˆÀ¢ñ‡@³kþ!ºÖ©kÿ!ºÎˆ¤®û‡@çLþC s&öN O‡ è]ü§´jú‡@ÝÌþCœ OfŽööz°±‚ÌÿBÐ|Àÿ èšYþýpÿSÀô M\­þ:ŠÁâ‚ZXü…ÿlZÿiÉñzü¥ñϾ£»Ë_í@%–!Èô1NPVÞNV@‡¿*@kÖ!(%Û¿ˆÝ_JÄþ/³ ùÿ´âu°vþµšÆñ:è°ãÿعwú³ jædât°ZüÉŒ“í¿V]þG”œ pA—gíøWül Ñÿ<üÈèúÏWò_5 <þJ‹ 4¼ëŸþ! Ç_épÊ]AðÿÈ‚Ftµû÷ÇròÇÈ®›• ð¯+åæéø×P÷¿”°Ç_ -Éó¯ûöú Aí½ÿBP€>Ì:ù]þ-õ¿éÄŽ|™@Oˆ‰ä”€‡‹Õÿ𹻀¢vû×è¡þ7[Xƒ¾]@/ ÂÊ¢£™@ˆMzSXù'©Â™ -hzpqËæ冞¹NÄàåDp»’1gúzíçÊ/˜(ûÐû¤ž¯„®Q~&¥/2Þ÷=Œ÷¿ø´j_QòÞs">Amoš¿=åW™Ý/OÑ)̹:ÉW¥•Ô8€]#ëÕóøÞ›ÂÍ£-ýÅN3<´žšƒL -ù<‚3|Ý-% j}:ø“M8\ ÃÏ+ÇwŒçB¸¯ÉïFæ“ÎÓ¼‘wtŸ&0ê>”Eí¸UÊÔ‰«~5Õ[#ÍfÓ³»ŽÉš§¹atÓϬérZ­™Ï-Ò}RÃ笉”çA¶Žjë,"Ó«K¨¥˜n^/è°2ÖU¾'™(\$²RùÝá#p¶õ}%®­DÁFw‚RK›EGù[žC!t%~1Tê­ú{@&‰kBÊ¡tqm„E¹*åÂ^“ÜFãòéxêŠxð ·UQ‚³äG´KÁcx)ô(Ûž† -©d4eÐïÅPŒ¼Ì#üÒ'Åk_îÀû¦›*¹8)n§-ÒZMš» odÖKaj:GaHvB}MJm­¨È&6‹ÂÁ%цÊ:šiq$6û'­p¡¯Š—?©J¹ÜŠ6˜U˜ ”ã%`4¦8  -S{ö¦x(Wk†Þæ^ÁI¼C æm®€ÅZ ï!f-”¹dv°åZ,¢¶~Ü‘ÈÏJIûD°ëœÇŠø®mq¹¸j8hˆK@9× {QH5 Ãc~”5R‡¨]Uýl'mvÈj`)xÕo”P@]©ué+ì¯ì·ƒ2×|‚ÌÊ5ˆ[¶òÌ)ˉõV¶³–k'“+|þý«FÀ(œQ‘Áì#î-8¶t@@i»ƒæôÂ…KM/Ó—4wJ"g6[f¬Øí|Wn´Ü"éqv”ö탠ÀÉËHf—&gL®Ð -?÷:'’ä…®3¤µåTŽSø'ܽ1'ÁOÉ!Ø(®!"C&9[¸#2üö„ {XL'¡­ñù†æ³Õ­û2tÎ!! -¤Öï+‚¨Žªâ¤Y¿ýf_ô>¥©ªâS.y@£h2>ж´â9:)Úe(»Jð' ÷—_FQ³uÓ¼ÈãÚ€ᇇG[Êr÷µ›°bÁÒér¸M×Y[S˦h5ÔV#JhBžWS$RðßN£Ü,C?F1øg€§¹»:c™ >õ,.éL\[GB20ØÍqv`-Â2ŸöŽQõ|éUsan½O»f‚4Ûk“¤DL$ßûP””u§<¿ÏÓ›{wÜgfÉIû£ù€oÝ”q̦¿n¾=Ñ0cÅHuMØ\ü~9íÖJºz¯D¨?ª}ln¥©V~j‚ÛxÌÙJÍ*¨t6—_NãFÕQj'®%3GwCL‰¸ã·¥ä{ªôô.0˜›¥fv _¦1 T»b1œ80)‚‘ܤ؜‘£OÙ'|Ý2TÉ:Ò;ò% ÷Û>Ölçr 5&”&zù]­ÎÜSw²K"½n²H¼ ÐÐÚ#T´"'Yt&m0˜¾SØfx¡׸b!us§Ž~¾Fñ@æÅú¸n¨•›J¥ „¸Íp\?Âã|F"+êªvGg|ôÊ÷ïS«& ‡oË$a:9À<ð,û)Ú¡xÞ”À@äkÂtàòUi,HÑnÔYŒ£ñEÆ›v£„ºJQì{ãà„0@%JëË@acæ':Þ=æÏá‹;*é´Œm<8hÎ+ëTºä¬%Kѽž,æ âÆÆ‘8‘ËÐði´îŒ±ˆt5:mVÜpc·m+Î ™‚ID&ìû¼w(B¡ò€í]ØVÞ~,½’žs TXtÞµq à^רÍ&TÈÒ~½’WÚx°=óŒ9ÔÁâ} oV‚8&ÁÊS›÷‹üñFÃÝõÎXcÕã§Œ~„F¯)³!éhõͰû³*¤¢¶Œfÿ®:Ú.áæ¯Šy¹´mþ&›CÍ×¶,þ÷7V}g2 -ï"ê3È¯ëÆšý‘>åVÁèÖFc‡oµ™ ~e¯mܭLjA­6šmÉÞ&ÐPþkC.÷ƒQÍ•`Qœu Ö«JâH]è°Yü¸âF˜/ÐôXßáËÒ -È -YVÊ>Y¹´"û%¤’$ç¢ööWRœD&"TáÜ©HTS¡ºEöŽç°ÏE»$‡u¯™¬Ãó3tï -ŠÓÑ8D¸äZE™ñù`¼R'uÈ¡`À­¤`Åì»[û#ƒ²×qEÉ -5`Áyš`zh_›Ùeõ¸“áUJ?DŽq äö¾vû·ºÎ•«ö«§9½¥asvç“Þ˜Ä XY½›#¶ -Ñ ÒŽ Ÿ²t_ð¨åôW<.ÒÁwV½ÛÌÏ<*¤8Ðîï©DÅá•ÛÂðVK[‰’z×g¥ Ýcšë]Ÿk[¹" £)™ú…9\õ–SŸ=Ý"O™´ž…Ëò{)Ο‘Ã"eÙ”,>øÐk„âÕiîi,.À„ñ9ºpÑÝ€["_¹àgv’§à€›qÙ3ä0Ò)rµrՌڹþ£`Ø[™l@Np2Œ¤_×Ê×Ói?™(+w(×QY:cu$›ðÞca•<¹˜Q×ø/$ܪR¸¤Õ—¥Æiº™/yQ¯)coÊ©•GÅêõƒÍ(¥ìnXn¶©zjZP9ð?Ì]‘S Ãm[t}Y§x¹¦öTˆßÉ_‘N¡1Zwö°¸¡i‚â7c„%—†bB)_G…wá!L ôQOï6RÂ?²ðÄ‹Ÿ¥SIíô€ìR3!ÅÁhŒ§7OîÉ5@LÜÎÖLŽ$¯ò*05Úߘ_ª‰À¢·"(}OsÉ -ÝÞRYª’qÀ+o Ëì3Î<§Ï²Ôn¬Ÿ¥1+€‰Fl¶'/“šQ®{THp3–Ê[LònMÆòY3|b~Öìúõôb¹¿‹ÝÇPÁËѪO×ÐÃÞ•¹’óö"sjÓ‰ÃíuíŽSôc;å1ãm “}´àgÂx ÇÚ!:»#G#þ¾ -ŸbJÍ΢eâ ¶RUo;aŽ•Å`Þ’\¤Á% ç9æ$Vàóüþ¸„ø­Y¨€ösK¿Ÿ½8Qëj -ôÚˆw*kÅíÝÙLBe'§‚:ð,<£ZO_ö‹¦9çImŠêYèÆûø¡÷§Û2@Êæµ}¾~ëæm‹ØÊCnŒ{–ó`üë¹ZÄ&*ŵ›º¢ƒ‹ÝUØz@d-ÎlºÃ9Þû]å`l5JE'”v–³£øEœÑ ŸÌ¸å6 -It ¼™ÖÇð{Ò÷:üW›PŸÁñ¦דg†9)ð&0Цåý`pÍ^`bŽjÍb芠 …eÇñΧbÉ4J²Ø¬yÍÛ¼½7¹8ÈrÑXí›y²ÜYÊÆþYDØ;;_Ù{"k‹YH+_¼ÂN©`(‹/teøW¥°Ÿ“ëbÐÀ&ÕI‚6­óÜ•1ÐVÖJuùî¦+¢“l¿j÷…ˆÁ.nªA -¬ò7ø6:ÝfýT”›æ™"ÐWSÝ󯛦Öx¼ ^x1ý½A1 û­ïa=t+?õ›oNDÍ*¼_-§òT¯ÔYÅÁÝ”WRm'nã& }ø95ïœc‰È²Õß@}cÆÇ3ºìMý™`Çý ‡Ã - £ÙáG#b( $í×ðE#*D™Š¦/{Õ0ß—ÓK×‹Š©Ã½¬»ù†lsS`¢È-Qgï£VNÍâ~Ûlméù=·H£Š“)/ëŽÞ¹çf6”HÞ(æÏ<¿r%Tª‹D¸T8í¤yíAc‚¹[•¼LJÒQ­ÚHé{¨‘]5çÂÖ‰ép«KÌÞ΢{Ha«Ù¹?ý¨»¬[——¶™¨BÍm± -„.aoî²£+ËØëü‚‚CS]îö *±¯®?üNŒ£ü¼ÊÞº$”þ®sËý¦§XAZ u÷ÃvÞ -çïõgËQþFô]1È1Y]L¢è’³^yE—¥º˜`ü“ô÷¤S:´ÚI00NKfzVÛxƒ‡,QÛp¬3“D Žö›yföp† ¿Ž»­n.fä0º/)8Ì›ùmÁ+4I±éüˆ>È¿„™• ¹ÁM²Â¦’?k/x6„àhØNñ“@Õ¾êý¾Â’8ÊO"½Ä-fºäq´)÷Y«£Ÿ²Y~ê$9ˆ¯-êkJ.uf¢hyG¡äGÝî5i¶)çÐEv`‹ˆº×3ë“ÙË|!©?u½CÈçw.ýŒ¡>. åŒ= ùš£k‚xaJ0QÊÓt.Ý釷·×^xzÒªÓ»ÝÔgaB}5ãªïðÎÆ™ÚmP—Ý+gßð#úU,>è -I`=½{¢=ÑföµŸRs9Ç'ülnR?ÇD§ÐêA¹_yÉÇð•‘¼ zÛÒ"ô$‚¿'€UÝ «ÜŸ¦\òg\¶ˆ$å[ÿÕ‚œ¾ÐâÏ+p$‹õÚâ­;îÄåÍ/ÆÆçtå%;Cß6üE³n sïFoÞVõf÷j:‰^Ä,ðjx_y¶EÉ Õ†ý¦-¢WÞ ¨Üߦ9¢ -Yî; {>j.»ÃÉP¡ãUpóî>>¢iü@Ô ³oáH)¬H¨þM<ómkþÅT¥¢Ã´ˆfƒ´ä(\ÞûÞ<ñý„c3v#cqW—QïP“ÖÑERôûï÷Ī>„{߸,ï€ÑÜ ^¨Aä…Y|0$ðÉ5äItÓùP&Ù{9tÒax©ÙóI!Aãy’ÂÎE²àÒ„ ¨AïÊ/br¥ÏH‡V+›nÍ<õî -ñU\ÛüÅ%|¼<+è©wßPø1 -#²» ™;Ô¯d7ä²}øç&œD¯OÈu¨Yl»}–ïà8fŽ-Ì_×ý?ù-N[ÇH«ìóÃ\÷õZÍ=ü´¨Ÿxx½É|.‹Õ -¿£(ô~£ne=Y\YÁY,µ”›ÂξՌ”ט…En;œ ~‹™õ'iP‚î ðö{]ÙBv"´ŽÕŸšµjÇB¡KÁÿzõKÙÝŸ§’-*XÓFØaî0jìñ|¶rMýÆž{Å¿Vµ5ù๰QcX§¦XÓhʨß3tsoQ¬øÅÁL;ÀØÿ Ë§-w7 ;aíúº#Àk²#zŒqz¦1eDg´ët»OWxŒ"Œæ@öÎã6ïwãe•öð+;‹½jò±ñí—kñeÀS»;1o<¬À¯zGI ÓÎp¡|~¤·W¶‘ÆrŽ]Æë2œÐvläNëcbµq<¤Y¢Ýw«¯i?ŒbWýa›Òmj>o^ ÷?S0þ¾¯„Šøˆ‡ÙNÈÊ‹pÒ¦!ªPãÝÁ-ø}¦¬}t-ýò˜õû øT¹j¥]|kYÍ ÔKeEoâÌÈ^‘ǯ矹“x%Ú¬K¥›å-IšàõåŒÎ«×¾e¸ñK7í4½ë$‡íÐX·TÇ[ã‚þEÖgÔ -*ä5¬" màãŠ[”Á$îF³‚˜Ø-:â⽓B+û”¹°Ù(`ùt \X˜ý®~Tp§<ÒwÕyY7›“ÄÁWN/¾Åj(c|ÏqYA«ÅŽ‘¿0ižÍ ²j+–°K"êQÆ4äee{k•NÌ9éÝSGËÌ¢‡*à‘ÂD6q_ÁÚÊ À> N!—¼ƒì ÓµØXÛ¸yµ‚Ãë•ÀÌ † Jؾi©¹Ó'Ã`Ëü¶G?e.wòá¤@-Å+nœø½³Ç“¨t¹oAé -g×gŽ/ÖÔ®iYnlÖSÐÝÅ«8øû4í—|ªXzu^2]°hÝ”!Áq3e=ÜV Á¢Aè­«Öä|ÞE!+Áù±óÔ -Πø‹éa÷$„¿¤ð*[6Ríè) I´"ÜÛº ¿|nèqD“ÇaUðb°Â[wªâñþ FŸ6Áîզ@!ïeBs#‹ 1qÒ]¶ZÍTŒ¯î«=ŠõB,ÚF'ÞÓîúô™fKn"‹>)rd@Áõ—°ëö"Õq›êš;²SûZ‹÷¶å!ö`²ò'h,Íä0ocjüM†Bòg ÉÆ.%ï¯dº®ÜOx{[1·Ç(Ù±‹ÖdW}\/çLA [dÃfè]S£æw5,²i¹µÁ}ŠO -÷uø®y„>^ ,H IZ6]eÿúÎÊ‚:Ê?¾”öý*ãë Ã 'Qž5gIqdû¦Ð‡mf·£ ˜‡ƒDñH8.àBeN`ž‹³ã·6%jA>Aª&1ªaU‘ÝNUæ~Zûh•ÇWkiREÊJôÀÕw“æAeÑÙ™ÍÐÛBÅŠ³ñî‹h–¿}ŸfÃxŽÍ%ëMÞP)ÿ:5¾s»Ô’²Û½.‰ÍÅþhÖÒàÇ$h½øá÷³Å=G,Ž™2íÊdOm¢ºÝÃ…5ß‹}ñ†bôÚE¸w…£8Ïb -,Dßð`ÁÅÙ~ºèþî;zþ{k)Tïo’äÐÆ´ní)ô!Yû8Õ´1Xc °ÎØy;#ï³ä!»]žÕaK£rËÒÀzHŒ–¸í1.j­ÎŽ„)T_é¤ß¦á.dËE; 1ÂÎÚÊ8LjÞ}UGJF¶Ü~ðZÈá`°ËeÍÄz|PïB=ÓM´¶ªèò&C#¯· ¦Fìo¥2˜^ÉU¯K_ßQј«åA$¹5Ê‘ÙH§"jÊÆ—ëÄ¡™Õh@%e<ãe%Ò‹EU³¥²Æj˜°ößUù×ÒP ìפ‰­¹Ê,剈“eE qàâéÑ¥‚/ Y¹Û5?_ºŸ¨$&eNÞTKÆffmÕ ÉìŸýB?.”}ø~o¥ÿìAçÃ¥EWòa­úKÅOsRºUîYnäÀö·¬bÇ™Îσ}?c¤“k¾ž¥7e’r¹ŒÚQÉf#‰6h•õˆ¿“îfEªî»Ž"µ²å¤ú™“º0‹l{º‹ˆ³ÿZTƒ 0&÷†¤ÜÇ+G±|°ƒÃ$b `†7ŸC¬l æmÃS󤿹ðóÜ“ÇØk`¹cƒu¬›¯áÂZqÛ]~Sµ ÷X_ïÃ0¢\Žïí!\^&l»üÖQDB;iíEÖ ø^ìˆÌèØP-¢m­n̯6ˆZêfJ§ù™Yûš|¬ûÓ?% äÍd¨Ê²«¥ß—#.ØM†mJ_šÄChÁéH£å_aèn&2´ÒC:uÚf!ZUºXkc¸BÃxTK܇£5*7H+ŒÀêªNà%ÙC®ÊmN¨rGiφ§Y¶Ñú -|ë°ÎT:=3]‹˜•ðÈШy²~‹5óß3 =.ü§s œË"û ÚÎYÛž;Uœ’°•ƒ[‰3ëfûµºäà„‘ðÔÍ·ÔM¶xMé+À«Ÿo»L»ù -Ž&av”Ï?Ò’‹5¶JÙ‹Š}OmœºY|¥¥ìÕ“)bºy½k£~Ð —’Ñ•ž¢šIòWïúU¤¾§„6ˆ‹w…D›Éä8MPÅÎ}%à88ɬÍ™ÊnêDF眫°U ®ô˜¯pôm«Ùr¶“,?èn$üe5FÁÃcs)~]cq»h—yø c™#§&F¦Ñ­«ÐcÐ6˜’íºÏþÔDc²"n…ðç˜æúÐ8*C`ĦV²ÔIù,0’Fs‡—Ì„sŠ;=ÊA9î¬/[õt£99 Èt^åIbQ‚k daŸwÔt–ÝPøä8± 9“ÜÁ¢¨¸’¼n$©IÓ8ŸVKÅþZ-K¾å€¯TL¯|„”¼÷òýD"z]¤ïb3‚ŠFE¾¹Eó» 2*½\+ôQÆÑ±Ê¤ŽÃÃ}Ýc½a£6!1ÅîÀpù#fàÓ=#éèÌy¿ÎÁÞ¢¥]˜Jjiú¼V3ª³'6·¯æÇkþ1­>ÛõY™5®F8bîrÜ)vF~B#žwñ.™v¸Ò¥r[6.x¢ßiIíŸx5aƒ+ºCÉM!<Ð$®ED4„œêå‘ú;†ú±8ò¶Iמiz\Y÷|Ò€˜Ø`Ü3ƒ²†;@A2ÞsÁÆØl<ñ¡ƒ¸w[C7|Ê0u2·ŽÍ ùzVY;VoºðA©à×¥åÊQclô¤>¸j¿]%:=b%œjŠ€ë‹/¤- ǹ!™‡žTR[®²àˆ‰º‰Éèj49úz¦œvR±f ÓOAðËAB¾¡ÕeÝ&™0`ZØ™Îþä↪°Mɨ”ˆO^¬ÎԬ־ȼ¶dåCXz-¯ ­“Ù¶\{&²ߥ%ÉS\hêŒø‡7áÉùºp‡¶ éè7{$¨§Û% ö0uwl|ùW]S¾9Õ*…["s”[%Á^¾î*³ß½ ;]ÀL+DæÁEB]¢[8öC®SQ'üˆmù1¶)à`‹Oêe†ùã?9‡¶'}ÅY…×5ýPrí“%T—JYõ†ú‹â¥6*.'²Í†ü4~ømÅ9UõFÀÈü<Š;z“½iV~ÃBiþ<Çà±ü;þs”ÏYþe.moÆÈð‹Ê£AîkÄ(ö¢4[˜ÚyÑÍ:rl‚2!ƒ!¯à¶ù·wÇd-²Hsö ‡`2©$o«dß%ÃQ+ ½÷µ"­Àý) ÙmÜðIÍMDïe«£æÃ·OÒæu™—3 ŸO…ùÕkÀ¼æ´ÄSã:¶h%jë*GE/5áeÝ«DÄÐ 9ÅhÄŒ“ÚêÍi—κâ’êɉàùSýê¸úÙÚg‰Oê‚Â6q«]µzNxW®óŸ%S¾-rÄ2|:üú ÉøÊP> UUÔ>–3—ò?´'p?4} óÉÜäçU»q­à¼Cù-Ö ‹‘F,Nú—>®'9qížf‹žõ,j}¹ìg[ Ý0k¦W j˜ -šaawÙX™-Ôw–xøŸøÌjîIfoŒ0'‰Ç#i¼—Á¨ÔËÚVŸåR˜^e%µù‚Ф³¥ï”²vmǾ¶}zîêE»?ü‚x&›z&0ïÃçDËEK[|ííæþMÖ?Õ.=?ÌìÄ`LM¤«±þ˜Ë¾x”Ñ~i^AlxnÂÀu›!3`õ]Å)L©´CMïŽËc-×3¿4òS{â €vIØÎç,iœFœÅê~ƒŸƒ³êG8“¢ù\X»¨Üál­Ý°R½Ìª×öDg¸*c?·=ÆÎ°6Ï‹Sà—¯f1!~ -µÍxr† …{ÉX.Lf‚›óN¾ìšàÜð„Ð…_’›ëQ”žO5†­é™e‡‰‰{á*Hè’3± º•Â^Â×_a¨ -£Í™?¤?ìïa±®šeÀÅŽçÙ0« IwÔê¯Ü +ÏypUŒ5 Œ‚9%ÑRé*¾+!cÎɇÄr’9ó)| -I„+[È1}=ÖȈG*#zI®-ÅÞxÄc¤’KsõäêðLHcLÓmy#a¢J¶rC>ñôMÝøj°rAUã™ÚÔ\?¢Ì·µq–ϵüXÅ=ýu0ºt6¿œ5+\üÄV n‚I:þ*З‘“Ë [”–ÿ«|[i[­résekÜ[Û¶c.‹+2Sàå–ï ôúk>iîm\a픞¿š{ð×ðÃ;ù¸/aí><Èp¿Û–‘3îÐûDü£2«¹7ƒf,ÙÈØà·Tb|˹r*Òéwöz5 æîßQ—^õ}¤x^À0 r­ßb«j²[ Ý‰bt¾)UF“6™ T†…HÐ L,ªd­5#böý\’óÁ¬ñ³sÝ4€ïx¸ŠÔc‚­ÏŸê Ø{ç»±¸ñ›¼ÕøB -þ£žÂmt bÎÿªJö²«¼²a›=CòÔ´óp<Ò›ïbpIü¤cÛž‚Ø×õqĘËnÃ4‘ÕYý˜,$¡¯O­F%>Š 5Q^ŠÀÖíC'­üð…9P7lœ\¬|ʱR¢Fz’|~ÀbùôãôQ Ó÷W¸/|¦_ûvš•€7IÊilFuÒÆœU“*Xiý¾ Ì»,6w³>ù›¯4ù ³+)Ë%Ô(rÏåOSwùVrꯤhÉ Œ¨²Ë=Ü]S‡‘iŽHÖãÎÝÊ™“Ýý(dÖÁkÎgüJ•<¾"I)_Ç·Àéí]¬ý<Äí\š£vÖ¹ [„“0®ôO´`â_Ω3 !5™ -Õ‘¹ -±ô.-^IMÛVTëQÕEö$ž5Ä Ö…#Ç{“SŒ3`e(ým¤v\9¡Fg1R -\í·JæpÛIä†êé<¼ÅŒ(xrYOZIBÖyœ¾¡³î‡¡X¸T˜øV¢I¤y­à£SBu'¹Kiçµ”MÔ,Æ µÈ& ˜Òåäa§x7ü¬üáhw¿¼é#N"¦2$&A’€ò·Jñ;õT¨’.36vŠÑü\¯ÉÀ³ ¥Ò~¶·ÃP.7Ê©‘רu° ¿^Ѝþ3µºo3y…¾E¼Â¡¿f(­:ŸY‰"†½°{i7ž:lÄ…§Ë k¬M·Ú ©£²þäîž W{×71È´d<¨häú> ¨`lDÓÔ¡Ñ;²4îk–°{¼?§]•ï”R0 $¬âß~UöÞ~Æäü†Ä›™}@þÑÒ˜êS. n̉àéðãòÁp:}‰( Í´QNmžc¢³ za)Ìð?ú …¾"w2uîÿlRYú8îú £b*¥B²•¹eÆ7nÆ.^Ã_c|ÝèÐû ãî“,™íÁæÃ6§x—&ÃÆA¶^àÅ@æ»a‘õê;¿§4côF½mLKyžJþÞ›æþÉ©å쌰¬³Û·fÃZÁÌi\]åe‚® ÇÊ ¥­˜±iAw˜ŸJ,ƒy±””¸77çiâlkñq êß`ŸY鄎!-2¹÷6¡ˆ7Ü0>©.ë)™\¬q,oªkBÜdšE„MÿS½És´TQñ»øí,Á.ä5gçuhúJgÛB)—-U»%Á5G–›¢Â‡U!ceÆ1ôS8++îLuØ2cK<‚qT‹ótêUN.¾Ô Æ&YÎúd=Utê8~¤Å÷Ù…B?n„PBPÞe…¾\f¼twr(£ÝDYkI䨔óØYK8|ŒðÍ] -ãqÜ1@¸Š(…ýV­àú2[ÐK þiÛü‡sŸ,óÍžàéø xÍjå@ìë—ð %$§}âKƒãÓ÷!ᳩÔk,)£÷‰oßÜÒÄb¨Ÿ÷vVd¦þ õ¸ )–Ím¬åL)Œåà í¼Ẩ çgkî4vhÆ  †K`Þh™¸AýT¤–|sBÅäøè¯·ŽI‘?$ºØ4þŽláýÐGAhÜï¾fŸûçÓÌ<¬©ôÓÜ`£ðe{i? æ·5”iÀbuâ¨ÌdOW -m{ -»P´J£7Ú •ãn¶D”ñÕȾû¥u|æÕò“ŸdIÖ+=Å[…Z)I€0…|4ù÷ªÎ’d>=;’ÖwZzœ¯æ±ù…ÁlÐíà<æí·,¸Gå<=G²2–ú0ŸYkðî|æNØÖŸÏKû¨XéyŒ9ò¿^vÛ0ö˜^Nô—Å~‡E_ЧJȪÉmqëß«– q^AîôQê­JDñÃvB÷¹ûià™…êûFŒ§7¼ uDÁ‡íìÊjµÂ1éö†Ö{žj­°4,¹ †¡É‰Í5éÀÑrôá?/•:œõ½C|õlg¦ü²¡»á·Ê'ljç•䢙œ³\æl¶o3BĬc›lúðü»Uöš—1l2¸9Z—³*)ÐNWÓ~П‰ ˆCÕÔJæ,ÆE“ð‹·¾ ·Î+\Z´ôeýDò±ò!‰©1)Aæ•x·5p­þ§wYÒ.úCwÇÄ„<^[³¾ØMëçquÚPãÌ“\FgvYÎRïsÂ#ƒ}c¼‡öÇ9®¶=XŒoÝÀ ©ªÏ™w·ß-°:[KÀ[!`çÁ]ìÈÃàÛ|Ö8û?xÏýÂѾçƒÐøÁ`£ê«ÌÊ¡àkUÁñ½¥(whêˆh¥y‘â?V+ñÕR˳ÅA)‰Ê,qy(ïó¯àk•OÄé³uiAMûh´ï¯:EÖBÚ\vÀ61¸¡{×¥E” -Î -&ÐmÕK@™À2îrV¸T­¨Ø7’é.ú¥rÝâ‚°?Ç-ßtì Â.&M{ÿ- ¯ZÁ@øë(7±Ò£ÜÜäÿöÄct -endstream -endobj -1823 0 obj << -/Type /FontDescriptor -/FontName /EQHLLW+CMBX12 -/Flags 4 -/FontBBox [-53 -251 1139 750] -/Ascent 694 -/CapHeight 686 -/Descent -194 -/ItalicAngle 0 -/StemV 109 -/XHeight 444 -/CharSet (/A/B/C/D/E/F/G/H/I/L/M/N/O/P/Q/R/S/T/U/W/X/Y/Z/a/ampersand/b/c/comma/d/e/eight/endash/f/ff/fi/five/four/g/h/hyphen/i/k/l/m/n/nine/o/one/p/parenleft/parenright/period/q/question/r/s/seven/six/slash/t/three/two/u/v/w/x/y/z/zero) -/FontFile 1822 0 R ->> endobj -1824 0 obj << -/Length1 771 -/Length2 1151 -/Length3 0 -/Length 1689 -/Filter /FlateDecode ->> -stream -xÚ­RkTבª¡¬òRIÕzX%róÔ - ˆ±h €<$f&dJ2C‡ $ âƒJª²,b£Kž¢¢TXU꥖X…[ÀiáËëEªVEÀ×°®®KÿÞ5η÷>ß·gŸæ%gˆ l,ÁP‚Áar„ T&“rØ€<³Ù-‡•‚¡aJŽ@àVëµ€»°ùBÞ -!O¡P,݈#©ø„Ò'E| ÒÁ8¢R¢@¦$4°Žì¡RjS!0ad‘V ÖOÞÈëá Ï„!&…â"À&8A)¬IORTþ;Ò§¿§2a<ƒ4|¦lÒiÂP­@°šÂZ‹‘Ó`ÒËÿÃÖôæ½V»V©›l?•Ôßx¥ÑÿT`ºt=ã@†A0ŽN—ÆÂïÌÉ`Ñ릳RB©ET"4U g%“½òŽdH E!„JÔJm<…Ã(4Ý ™ß”–<^¢ðýói§È(%‚ÑÆt°ÿROÕœ¿j2$1€6“ÍæBò{Jš6LŒª0AS—ç”8®4RÈ%"+0q‚B°ÀÒ1‹‰byÉä5†S&ßÕ X©“«F†Eï06`iጌ)àï¿‚LŒ\ÀàòÈQì•þ€ÏcçüP¥Çq%¦Ö‡ è}­FÈLaØ«(¶[˜*`ÛçûÏì¨ÉWuw¤g,´ÝÖ~aûiKs¸7ÀíÞøK4üÉ®Û]?GN¸”ŒD~ǂԼ>êQ¶Õ$gmïqµ:{Ð+Èg=R '&ϸRÖÖú‘îÐÎû¶Åƒé¾~õ~~/ó‚cÝš~%u¤pfÍí[¯Ÿæ¦mîè³9} y•P’ÊήÙ+þ}¯èÚÄÃp¬ -³U_™Ÿxà¹ûµõnwÚg‹À\&s¸i |5‡M7¨û;(œƒi‹mq¥‚Õráì…~7å`÷q —%.¨¹)Röûì.º`ÀËòa·4?§$"V3ºàx…›ªf60¼šj×·nhÑ¡— -ë×廥Õwr‹9éûhëSÆ_ÓþX²k泤—/{_¼5S[©L^vž'gÄúú Îôñ¦·³©Ž×¿²zÅ+5ßÜ'DÁ½N«Ìmº÷g7É@œàfžÇ­c_yÛ¸”ÂqÝþòÈ6ø~ßdÝ›(6Ø â/£ŸöW>þÏåóAn²$4¡7å\ômß+µ «ÂÜk f&Y›$’ª%M³±žù^Aî 溈£f·íR·¡è¡æ|¶ob|Ñ ¡ß¡îWC¿”ÄXGŽú-ÊuÚº m7óaôr“ÿï"kSŒþµ§¬?Ï[¶ŠÎf¬ÛŸv¢&²f‡ÎøD0gßqAýcŽCyöùg¢¦ŸÔex¨ó‰Üü|9½¶ñjíÂ¥(êee ->×ÒŠâèàÉqS&÷Ügy‰©oºƒŽ®?\mÚ³ùÑ“Û+íÜH:õ÷ ¨éâ/Krßní ×;¹Š›Úlèýã–»?÷!‚­ç»ê½ã¾[ÔB­»ø¯±Uë\Wu´‰­÷-´ïŸ AÍ•ºZä1x%D™êcó´ÊÜ”>óD­Íéæ‚väõ©ª+w°gÕi?/bÍX¥•/•žÑ.·›qwæØÓÏÁçø–C×#ø 廡à;QF+&ïuMèóܯŽvüvv…L-{› ß—2_e4tÎËjê*]àRneøl;û™ékî7gÌ[ìæák¥QÐöšö7ܯE(œuœ­±÷ű¸Ž|‡s -WS©_ æ¥uc†u¥ƒ}Çv]Ίù¸ÀzÏGáY*.yc¯¨j·/K<º5ªëÍ{/U;ªÐ†â¥Ñùª¶;É[WËêNîqÚÉ9¬É.îš[Дz_Ü‘ý"ø§ ÃF—<=g),x9¨é=ë_^,¾Ú)ºÝº—VÛ¥mª.-Ø+›[ã¶ñƒp—#íW…×]÷´·ó¾h§.#^½I8½Üã{cJ'¬Ûü8¼eM„mÁœ×ö6ºµ3óòD¥!]7wh’:n”åý†ÆÈ¨mUæpbòXAm³ðŇY>¹ÿå)Õü±‹â–¤ë=_®ÛÅeKbÑ“ŠJbU7ožmÓ³¬¨#ùUÔÚþÿÍé'» -endstream -endobj -1825 0 obj << -/Type /FontDescriptor -/FontName /SYFPBV+CMMI10 -/Flags 4 -/FontBBox [-32 -250 1048 750] -/Ascent 694 -/CapHeight 683 -/Descent -194 -/ItalicAngle -14 -/StemV 72 -/XHeight 431 -/CharSet (/greater/less) -/FontFile 1824 0 R ->> endobj -1826 0 obj << -/Length1 2231 -/Length2 16865 -/Length3 0 -/Length 18065 -/Filter /FlateDecode ->> -stream -xÚ¬¶eT\ݲ¶»;ÁwwKpw—à4îîîÜ‚»» „àîÁ‚»ë×ÏÞçìdŸ÷ï7šÑ£¯š%÷¬Ys-(I•T…Míöv.Œ¬L¬|QyV+ ‹%¥¨ÐÈÅÒÞNÌÈÈ`ååeHA?@|œ|œl”Q{O'Ks (í?NÜa[ “¥‰‘@ÞÈÅh ÊabdPµ7±ºx2„ml*ÿD8T€Î@'7 )++ÀÔÒÄ` 4·´C`þG’´™=€ûßfSW‡ÿ]r:9ƒDhþ%“ijogã 0š!0+؃ªAZþÿõ“K¸ÚØ(Ùþ“þŸFý?ËF¶–6žÿã`oëàêtÈÛ›ìþ¯«&ðßÚ䦖®¶ÿwUÚÅÈÆÒDØÎÜ`ù·ÉÒYÂÒhªdébb03²qþË´3ý¿"@û—f--IYM%úŸé¿Ö”Œ,í\Ô<þ“õç1ëuÇÉÒ Ëj/+Èôùß_zÿ§–¸‰½©¥9€“ `ääd䉚q¼Y–v¦@Ð$˜™ÉÎÞõÄ`fï„ðÏrq˜…ÿ1ý›¸Ì"ˆÀ,ú‡xÌbˆÀ,þâf0Kü!V³äb0Ký!v³ôâ0Ëü!Ù?Ò"÷‡@ZäÿH‹ÂiQüñ€´(ý!å?Ò¢ò‡@ZTÿH‹ÚiQÿC -¤Eó´hý!íÿ/H‹ÎÅý‡ØAqF¶ ›d ÿµr€9ƒ†ÖÒÙúO³AÒŒ\þäEÿ!ÐŒL¬.6@³¿¼Øÿcÿ÷%üÏH¢Éå6±t2qµ5³Êÿš9A5Lìm@wü?Êþq´·µý³VÐöþHg5ÉÔÞÆÆÈé/8àŸ¤ àiae©] #g‹?»ý'ÆÑô\øOæœ.P¢Sû »F -Ö¯ëÖÔŸÂÅ­%‘i£Ú@ÅNª‚–îXÁ¾îŽ–œµ>ìg×F¿zißåŠñT—Ÿôöù;ݤ‹„]e›Kå÷§“²¯áh¨õïC£µBYsU'À>ô -œÊ˜tp.fXmŽ×qƒé Ü ñy·s†ö.-ÒWJ.½’]vz‹¯2KÅ,‰EöU±Ôp^oG€ÔÞÂ.Ù$Š­€sÔ$—‚XÏ´:ФÈíVä¸:ß2³¦°¼XQn²Õ?û!9|J~÷vÊÔö-qF°ÜA{²¡}ñS4FDP:ÌÅÍm&–“RÁub&þ"tùKä‹'SíÖg¥Ùtù—y5Ÿ^JŒut{(“ !•ÒjÕáB¿ÀÝÀd N3iìO¹taHÞFêaŽ,‚û50e( -â(¸0nnûMt™U]ëÆ¼½øßÊOyÇŸmÕtº†rõqÒLa+s’Õmæ.à(Î5³,ÀZÖøjC? Ñ8q}áqY‡ãª3‘è'q§`æ'e]u,(•ËL>K*~jÞl¹¢IÖ.ÒOŠÀÛj,ÐQÓ¹S÷/a°¤•7u]¡Ø -Y^‹š]uxš§ÑUö“ÃäÈxyÀËql[½IQê8ʾl÷éO•þ2žý­Åè{H^¢½®‰å… ãLó{çqÐ/¢!$^\i« ûìl7æ§IÄõ ÿùÒò¸.•YÕRƒªþÁr‘m¤ ØÖä3KŸõ©(µ³í^‡KûA”Å ›Õ̵¢d³$oSeµYÆý4̉˜P¯mXÆÆ+›1gêgSOÒ è+Ë“Q/z˜j–=£:Ø´ú‘1¶&U!×;i‚Cíé;N‰Žæ¹*þŠâöî²to×KÃüÌÑo¨Îb“Ø%˜’ÄE#?=?6‘ÈLì\³¬äÄ̶—PîG¬«aö6¡8f†a_‚¾Ï-Å3í"¸áÖTýð™cÍq¯°mÝ¢DTŽKµt…}í¾™ÒSðõMðˆ=Êðég2Ç—õ.ú‰x£öR‚˜ øhÝL53ßÌFü+v&¿^_µ«mg ͼef¡½Î–•¬”[TzŽñp¸+ÑúUlmZ âøôK–0k†ÑÙSÅøíèu´”t`Î* Í‚ < þòH±Ô…BOH»ƒ6¢ŠIÐI¢£â9ÒÅ…G ZJzÔ=“R¾.vܾ½— þy'Ôë&¥ôªQv4iY¤_| ÷²P<œw> k¸‹ñƒþè÷ýÓ߉Ø]é\pgýAj/NÝÍ ‰gΕÀö†gêF}NT®F·g–URhPzÔƒ£rg,ßQèPºæz½>Úòµ ¦§о§++8­Ñˆ”µ°îÆ h–眩çÃÇ–^›gŸNºXþ*ÌêñáÇýQ[hQ¥|o2Ä“¥§pþ£?T„‘GôÑ8`#(ÍTX 8.JÇš§ka7ÈIòô—Ät§N¸$‹Bn öÎLôeqþ•ûÚnè‡AНÌÊ#žRQ})pk/àtÄUC[€‰ÌBÅB"1Ý"J|Èåû”$#xö¯ƒO”xŒp2K:Òß <¨W¾°A¨O3HÆÅ­pP…>hm|R½œÈ_D¼•‘åŒP\Ô‹æÚ“MJêþ¾˜¶FŠN*õñÀ ­¹Ñ´" ì9œ 9âÔYôiLBhét§¶dºÑ?7cP–"3ƒîä—ã¿¡ .à!Sžê_¹Xbí‡æn`½™º„:Boíµ%ô-ÔT É0UÜ*Sì€ê,ÅD‰}=xËå.hyãW÷G«G›XœYm:Ð8½RT¼n>Â-_Âø×bÜÊîW¢–UE¢­¥™çõ>]™¹Ë§ÃX¼I‘³we9<ÓÛŽ¬äµVrWÏç\czÔx¡Cœê\YŸ,; Í1CW”qž7ý¤;§ÍytÏðÜòýóàU¿'*Ï‹þý3Ÿþiǯ°ë”*^Å#ã>W;½ÒÚ,5±Ò¶Þ‡»ônF?ÎÁ2é[®àǺo5;`°Ø~ÎÙ”2sÜIòÞÁUkŒz~æžÇØ=cˆftÑQ„} c†oßk8ÊP~Ðq6woŸ}z_Ä’ßE zä2½ðrÒà bó¡­áôóqcwÔü†¿…7#‚z g6A´zMn´o×ø,{ž»æX7yÂýsRT¯®3h‰ŠÌ¤m¥ÞgÐÁÏ zå³P;3Æ3[F‡ÐÅ¥^¥r’;oíRÁÚÓ×ÿ…™à•š-©’3i^5_ÞRNÁk9vnR'9×)û=ÅäÇG4ÃÅ{ fÏ7¼¹ÏÅÌ¡+ñ¼Ÿ…EÐ/%ˆT²ÐË·›šË~·pMù.#Ñ÷âÙ‰ñÑå=­D¨9–õ¥šÚdÊ¢£"6±ßa™*|ï†RaF–Kí*I71‚ ©1>ý7ßöë2HUvŒ?Q¢Ÿ«-c+øË™Ž uÙèvr†,VÂÎàv¥<(+^½?\΢Yî¯ÛêÏÕä?7¸â`ªÎt&HÁxg"×<Ø‹Ân÷®hFK)×Ç£®õùàüØÊ×Ú)öó¦Æ QKYƒF‘R1HÖÎê-]uo:ö|-È›*éÛäÏ®¶Œ„Sô³ÿ V7ÜšíÇ¢ º¢Bb61ÏÙ¤3ôº$"§µŠ¹RÐíK'è4µQ&sÀD§~À/­Á³•qƒ§4ëK/<áãïá=¨h'û€ÞúZ±ÄqY¼?Àèù=»¹N9)¶ºÏå—Oùò’QÑ”n da©rëôG¾oý„Éh¸‹’zšŠ©JPˆ¶0ÛÙÊ rþ g„„ý²ÕÈ[é‹¡ôwþ&£»}åøAÏÆOæ ºÓÐÁû0:vòí -áÀ…ªøbí%Ž©§#š5ʼÇ ¼ÕßØëŽæh®JìÈ&Ó9Ö4ÙKmW[æMÍfîÛµòãa<¿V¡ç“¤DêÜë.Ìë{²o.ÑöMh$=ŽZ~œ7uQ‘·ó•‡Pð@ŠGÞÏ+q¥|:«§¨¦¾7}Ѫ8K#`FØHšq)<£÷–‹œîÅ]/ý ew)†Wôø»¡½õÞ‡:Øof`ã2[ý&op£š-ÖïÈ Î’ îˆL³ ’’;ímƒ<…$"x®&ÑëW×ÍBB¨“Š,Ê*!¿D…E}ˆXi:$~ùºÖˆ~tõ¸# ç|ò¬»†¬~\e$4Ó\ÿ¼·«^ƒ*ÄJ¶ÅÑFK‰‚hߎú\ùy¹ˆWÊÜg%&å§³[ðåO¶çú[0€göNÞ1fØœÛzŠRƒ¶ì¾!ímÞlNœãçë7G¤€›Ô²öþ~H¾…BÉŠ;~kòµ|+\ù™—§£3!Kiî¨&VbfNYø¡®‡`Qr¤öm‚%wg`¨©imzÉA3£üÏl…®Ÿ~Tëæì½Æ§d»áË*kc\û‰Š·H¿7¢@_:âsËuÚ£rÉò!먮êžRal-nÆ}ô;¼ìNJ!fçÄߤv¯Õ¾eõ$_Ê-Ò‹.ÐS÷,ä -‰PÞÏØ¹mdâ9û6½‹ñ‹DäE|"¡°} ˆë€mH   ±|ûê²ÞÏêáøh„9ÏŒ¤‘+‰¯IÖOÑÈ4ˆßUWÇqf¸šýÉZïX'ãS(•óæ@3â…ñÁ€WÂ’p-¡¶{\wßVÖ -7¯æf±?uVkq,Žø³™YêÙÀí>T$Ï!‡â¦MãFìQw-Ñ“Þì9 ±ÐiÖæP¤äNŒt<”ÖWnÿh*ên“üy·rg)51”Mo.ÞJŠéh¹ /©>­@ ôõN†ð%V$ý ñàù»î~]ތӽSûN~Z>³T…·F6Pÿ¸¹3´œ¹FŸ?k(‘lÅ +rÁy´€¤¨f÷Êßs忈•"ê”KEìAM:@£ªÒ•ä”C¦e·f§¯ýÀ**‡C§okK #D7Ì÷têZÕöEfÐ/n¢{>Œ¶äM±¯X5Œî ¥L2h8µ³àê3LÎt å:Ï]Z§dI…›îròh>éqQTÄ'泚ãjhï…xÃ`snþPœ;2U€4ID_“¨ùà_Dq:®XÀÜŸpÅ.‰^ ÐNô6ó:{|C ‘ì¯óZã+ËßZÔH}»/#M -%üIì@¹ŠñOŽ¿Í®9jV̽ÞQHGß±j.ðË‚ªÔ!7ÃØ.¬¹ •üÂhcç^±J×È~¸Yð^§_@ž”Ï’½ª£ñÛ J–Î;!f=η„±¾2šŸ¸íøþÆ/£ù„ÇAxk,ËNã‘«X·•ó0º@Íáct™ežU§îjþÞi¡© -’ݦGÚ-+¹lðÖB6š¾ƒo¶©™lÿhê­eƒÅV+¾™¡#ãõïkåR0É™ÃÌp^©ÄêÉ’TÎ[^5GD†Ð~ú½#F䞥gŠ>ŒZP þw ڠЗfTo®oµà¹ŽÉˆxâõӘر¯d¨”gÍ«9GÜ+…ìd=°øáX†6oµ`ˆ0Á ÓHø°€[·™’¢mД -°žtÂü‰,>oц*šÍÑq…¤dƒ…½ ¤ÕÁXç’¹î=šc0·±ÍcÓÑN»j(ÔþÇ#Æ0±‹Cêö`B)‹êÝ8§íά2U•PÐÓ™¶tÁÝççÕm9ÁüED8Ëñ‹^ÚRoÈÁ.¼‹»²¤ÌîWÔýCm -zEqVÑ“ƒµ&-^ï7=%”Ã×<=y  &Ðnz#¤ò¼ÑX€TXbèVO!ª”¥TóDó#Ý6Ã*B¬þÏf©‡¹DÈ­òÇ}¯íd‚Æ;ZM£\óýð÷ -óm’ŠRXÓ5vÙ¶}Úe¥Te®­‡i;ò¢eûŸqis©ÜYe\à>åŒ1Tè²Â«1 ÒÏA›¹C©kkmðm©yk¸y1Ž~‰4rñlù¦"ÙPk|·:­¤Ÿ°º´$·X硬âüð$=~Ú¥`¥ Ø$"c_é–6éÄ3dO1Òf­œT1æ9û™ûÉaƒ‡þ´†ÕBVQ±@õ~<޵³L¦§Ùcb€¢ËL,Л}“wQI‚ ½C,‚g±ú}eß!,¹Y¥*3¿ƒÁö¾m‹:~üCƒ_Ó àA®ÛRßm™¬‰9R–žà#¬ÅñãÆ(¶œp¦Ê{].|6ŠÏ\øÍ̇7’ÕU«uã+ãQK_ˆ*wªad¥Áì)­Çf6ºæ¸¬òû/'8Àdß -HõøÐ¾iãí©e*)=jõ—ëöyTU ÁÙî”#p…s¯wãbsãBFð®v÷¶G‰Ñ&¨’‹Kþ¶Op\¹I¡~š`—/ïÉ %¬ù=¾&ì…Î!V{Ox¶T)gàëéú±e8üTæñKB‰öWÑýæi‹)ð#l¤'ÓJu§p¹ý}ý³,ð˜6%úVTxYëERòl -ë;ýýÃÌøÍCšØÓ‰Ûþ85½?™£ò vÞs·(ŠÊYxˆžMÅTeW”"ÎÀjh\"„¯7óO‡¶Pa?iÆ»vì_•øõûJï¡\A l"1ë`Ùõz>}>|.Ûöƒè¯hIÙÑtÎ+×¢ § ú*˜ŠÑÅ>X¶ ¯&^HÓ>êzöjÖP4’%û­o'H¤¾[lª~åœ}Oì(£_çe^ -´îÓ®çà/Æ`<§V/uKÈé †ê]å×ûðD|îýsÕû1IäŠf¬ºþptãA‹©Úªû0빉PÓÂôýî"ô!Ý™ß,ÏÆJ8`@¬Ñ¬ÈêÍìæ=À½ ³£‚zžý‚'‰Q’ö:Üù»Cæ@M†”ÈËöYô–Ç— wWÕæ Ú«ið‘g‡!Þ3h¤§6C\{¢CÃJ"ÏO@XW? ×ÇLXFãWä𫳓{˜Á²×îQbZw£°?Öç9d(Q–ê¦Oàf¬¯“ 8›ž¾ô~'ŠÅ:Ž9pV^p(èèX dPàÊóÀÎ/6~¡y:*™×ýzƒ!øvâk”Œ¢ÍÄ|eü5PþS@~‚t)ö¹Ö¬pMv¨¤îû**Zn-ŽŒV/Sm”¸žÍþ.ü€ÔIRMGo¡»^¤‹bÈ(hÌÆ tg?ÍP…´øoöD.%Ž–ÕuTl¶_/ý¬%Õ“*)º²Ër!z¤mÎ`Øx¯ˆ‹ ‰3‹V‘NèB’tŸ?£UŒ+\}6þ²7ýS;//Ó*°råþÇÐÝ{u¶Í«ôWët-½;Øi*¦Ë@å³Tö¼¡/ìóBª:žõ‡*É‘Ý6¹žâ ú‹6¹¥EÌÁ\`fhÛå4j$à'Œµ8£[Spz^iv©ã ÀRæÒÕ5©ù ÚçôdG¸Þ;Ÿˆ²8K/ô$jQx×a¥ÑÑ—?£Ýe¨ô»@ –yˆ>R]¯u^t[ÿF uí¸‰š¬ÑÔO\!KCªóù¹åå-‡sh©´%ÍKÖÿÛŸÿÌÀ7Bîž¹ ¹V;˜²¡&suj'{Ê1Ù}dQõalŠ ©+ä(FÂî ùï«æ³1ÊØ«×vczr´,‰S}‚l—ïÄRò&òù-9ùíèß«ËÊ_¥ou)otZÏK¯½\ó|Åõ]‹1ë;›5øÂ%¨'Š>‹ð§÷}B‹<ÄòÜgÁ ªa E¤Â/»ÇXÁüz?¤4—5m …9šæÌÈlžŽëÝÆGe˜ Ú«/Ê!‘r“Ïoc '‘ð„+S†H¶yS…´£vwµˆ˜•Dé"ƒ÷oÒluЉ !Z‚ƒS’æë¡Qß̘U¸Ý šky›‚±Z‰—4ä’-¨*žQMqa ô^U²YÃm^/Ì)-¡MNÞWC~ ;³ÄÇ)‚‚ÇÒôù>*æ„/I’•ôôÕV;Ú’Û±ßL¿)µ8þ€ô÷gÆÙä´˜†ºvª~’EbÞ"W LuûI&ÊœðBî\¬zv¾æÚ˜ë¬°8÷}ÁRB{#êéÓüÌ!~öFéj¯¿…òYú·©>CLŸmØnÕÏí‡ml}[³¿-¼°ˆ|<¾Á…"b~ØZ`'hhŒô3)̘èj&Ÿ¹ „çlÀ‘Ì£"øD¦XäÖ`wÓÉ«ÙÅðpƒ^VÄPr_q2Ó“óaÁ|ú±ò<«b$1\¦Ûq€ª1bC!Ë>4šß$$ÑÔžèrZªOKkœö›ütËÿ|Î9bHÛ{t‹€uf’,d{iÄù1|z3NM¼¥§"—ê¨2סӥ7/ƒÜ…,Cî°Êá銓àdÅ0÷#!ôn°zÀN6FÓQx¿ߺKO†ÏóÓ.^¾ûxòUoB«fŠPóQyßÞó s™fj‚¤ï=²>+õì*7¸‰É¤çý¾]L–iå|õXZç²Óîß4í56⇂¶‰%*J'åD:µ09Nä‘¡´Ûo»m'ñ± ¦0^“!ip2h(ÍÞÙ Ö_ðÛ|ÅÃE£Í/Yž%¢ÁøЏÎ5ðº#!¹ílôœy£èÞ -÷“¦ŽÐ­âìÉÁHÅ3)ü/aD2ý6ÚM`‰uÏ1mm×N#Ä’lHFËcÄó[ç>>“«;‡‡Jà§Ö’111;ÓìçÑN¾ÕuÛĤ|ãs`q³žØõÄ5Ø™73L,þUqÅè^"Ø_\¿²–Cç”}ªy8±¹Ð7´S—Ñíúa ½ö@m-™âØöÕo-¥9%í'uVÈÚ Œd½<Æ¡èSQä3KMªZz/mNêSþ@æa lŠ™Û›JÊ@FÆÏTyƒY[ðMV«¶×¤Ê#ö@Üz‰N¹XO¢8}Çá1‘F¤h‘Êœ19®Öd·oŸ,(»ßæµxÕ¡0LÏ6 s?D„ÑçH]›˜lKüÚÞc³4·5ÒNhÇ®hn?«–qêÍ׬=xlN¤ûÃ&ko:Cñ>Á–Ynþ6á1¹Ë¸\ê[”X¶û4øRŒpsxê¾ÐLpèžG券×뚉ǃ/øq?í£ âª®`Sõýê9@ ºÚ¼4s—”³`Û”~ù= Ô¾wmò9;ÙU°Ðõ§šl[49›êëâtÕ£3AÏáS¾²p$‹üTSwiÐ9kt9ÙÎÐx¹ƒ5l Þ¦‚³ár9Ó¢nW¡ ÎËf  òv²ciéQ…¥Þ××óô)¾'Õ®·¬Ï(î’µíáâ6²¦:Èmç%æèûy3åÐ?÷o‘’kyÅÙGÅ=úVоsÈIÔîIÆmU"6F3’èd.G7ó2„‰f¥¬Ÿ&ìïª|”±ô<ãk²h/.™¦uµ¸À¬³Þ²Ÿê(šÛ¸5¨°Õ7x¡:?Ÿˆ¼ƒÏÅjÐgÒwË,ãž‹8Y·zrÔ''QNô\~tCMÉRfü…ÈkäÛsÊ]«Ê¬Ÿ+¯l¶6iðŠî®â_M€¸A¯ŸdŸFB_¸EÜ8 ÒùÍFÔè'Ãw…“Ù[…²à©;Þfá„ÚçèAE¶ûæ¼÷.âÕŠ"~…LCô"/þ ;Ë´¤[ZâÊÞɾzÔ³,ØýPKëÒ¾ð-5æù €ˆ%¢ùi«çà÷$ˆLÀS¢ËJê‚w#ÆÑ·f)uFD/g{'Hì4WæÚÍ@¡w­Ü¯ çqµs…½ÐZ×:þÄV'œB‚‚ªæÕÀBÜÒl£Ê’ââ‘à -Jd˪-ÜQ\ð…†¨"e³GR£†……-K'W•M˜­Ë‰†¹Ø¡lº0ón ÛxO·Ô_ò¡’®7EgôÒß³èî-²[¨0=ÊQÂùá¯n„JÚ…X%1§ëtɧ”ëõ0mû­’ KµYCaJpÍu%ë -$’‰Ws w­Èã½ýòyÆDZw¥R¤ó=‚¯]M’yng# ¡ˆR­Ùl½óJ½ -{ùýbûèÀP-t -/ñHÑJ3ì"ö çS*a šêá×]uÞ²"ëŒ È„ß‰ò‰‹™ˆËó<+°ÎÈdºµ)žkÏ]œÝôJÙ‰H±CÑ*:ÁƒoꊼüÎLG϶ÃðŸŸÊ¨†G/ÈcŨ{\~®Â’¹ -¦z×»ºg¦ø€ÁLÓ ãq^–«lÀùŠL ÁƒKÚ+êŽÏ`=uXü%J™`Ò¯~‘/lÞö­¶¸…mlHçõÆ Vg}0I´ÊUÛºácäÒÆËHû ¤5¨è|ñ™®lœ{ÜËÌܧj7½$AŸ&¥Š) -›G€Ô/lަÊÉ]þÖK9Γlqq+I^‚‰ž¬tr2€‡¬5£EKö2¦FaÌFEo5: ¹z1S¾Á:òL8žl'FÖF)qˆËrG‘`S8;ÑfôÒ¨\¹³á“6©[h¡;÷wq*š…=yŸ80fM†)±`Éû=¯Š#r¦Yko€£Hg@àÙ—èsš‰¶×íüŽâø1 àГ‡%·§Žç»BÁ•8|æÍVÍÎ ŸÚV4ß–•þ»p;jì@å 8Kñzò~°ñ öcŠ‘ãË Z1Êà«vü·Àž,£µ–qµ*R悞ý‚¤ -ÃO.~Ÿˆ†w£Ó}<6$r Oé» L¢k¬H_s¸è¼Æ°;»*Û4Áù„ž|£uqb/ÒÇÆXæš4¥›Ë +0›ÓM‰æÛ^\é;QHhÅÏ”(’Ý•ø2T¤Wå¦8æKŠ[H8äwTŠëÌš÷‘úh[ÒÇkã¹8eQúÊ:‘ÒG‘,ª‚Õ%²Ö1ÇQ„™dµ/n< ©îl/a âõ2-ä„.’êCîqä° ý-·ZGófëÛ¨»".A/W®î›ívhþ!Ÿ+ç¹Â’\]VáËŸå‡NÚm5³ò´”Ä)Š:ò¡­¶l”4flÎðŸÅnåà´ ›ÒíæŒ³Ä^Ô²5’H¢%Ð}¯Ä„8 ’ÝK8k¤Š»=þZ8B`_>öpÎ -kª¾ú?|ÃÞ§|*m3_¶'¡dßOÍ¥EÍêÔQ’ÝzˆHÚÊM¬hÁ„žŽ×K"ÿ=0¯VÙ_+¡ÛŒ–é1éׄ3[¯±(Ž/%…rż¨¯øû×€•l&ÿrIÁöü ^úœéG·áΘh1²ØG4¾]·…2ÿ¨|§Ã»´ð$Çß/¯>ž#þ©‡1U›Ì¶â%Ày\}[¬®Šš•¶4Çã;yî ˆÄÇ=dX«•å:»5€¡¦b ý™y'1MŸJuI|=o# v›9\ï¸Ý"DÈ'BÜ_œ-ú9¬Ùµã 0Õ!Šóý†aV˜-@·.2'°Ui6ɰ='QDu=®7žn`¤¾ßÏná%7ÿ‰…ÏÙ °¹¥u¡ÛcW«dŸ–ŸL‰I(ÜÄÓ­ ÈÞÙ@ö\v,Jõçeù›)ë¡9Ïâ̲h~g0º¯ncÁú™÷ø¯øó·ýþ¼—0 ïâ’KE‹BZÃ[Ùn[òŽSwçtdy ”ß -m»È›ÙßÁ—ìà*§-]ŽÒ_\“~Éi¤Ù9¶úOŸžÎ£Ñ´dFÑÕ¶Ï9®°È…"\‹éždð¢c_æÜVõãàÃnÏ ÌÓÉÇ[kÖ×O/ÐÞpzS¦åÈóÄûÑüB¿@,`jÌåEÚsa»·1nºYèS‰Ó0à·ÁB«´Ÿ¿`os˜F䆠–ŒäÏdÓ§šˆoN>46:ãg¦T¶“AådvðHUAãuÛjéÁ˜Œ(àõ°è´ )CòÚ$[AiÒ .™]3[UZ¨ n1‰¶Þ½pŸªµö¹¼Ÿš´Å7ê^•³•½qHúÅ_î“’eñè¥B£¹÷Ž~ Ëv$O„yZÂèÕ ç͸îÿ -AF­·°FÞçð©­¼s—Ãì9-7vOœFßû¨!Š6¯SÞµKÒ¸˜ñÇÄÛ%;ŠÚÛ× º×O¬(è™ÃÒB4(iX™=±WµˆQö¥.‡ƒ‹¡Y‰áWsi›bôM(bËl–¡ µð•ý!ö´ûý²`ìÑJ6ˆìß§ÞªÏ,tÝ’Ù X ’ñ2´—qQj¿MLì¯ÚqGqŒmå} £¯cjІk?D)´zçê!Låµ °ž*6¹jêF aÙ§Û’ú¹ÁÙ):>«ÒÖ„*ÑÞŒæAf]?UgÙ:U7$€ä×0bl;C}Æg¾ßAî~ XâJfu}¡Þ32DÀ·Þ70¹×²šÚs˜‚ð›¬ÏÙV©/Žõn@ƒFS¨°ÿʶHGEa½±[÷¡È´æªˆ‰Áp”•d3 vÄ6Ò$–è#­DLΚhcÄ þIÜà ™.9 e <Ú3ÜyWÉmº'I5–cjuQó[7"Õ—ëü~Ö/´ÜÔø$’Ÿyzše9f9û7Û˜ìèÔ0½ßßž™©ÛYßyeVÜh´Âû½¡éaÁ÷Í|Ó—[ÒábblœÈä5Kß7òuƒ¥jlëàÆ)ú¨?EJWï£yÛ(Õ~'|Û•EιÁÎèt”ôÙ¥û$š,[lÕ¤V§ôK¡itÄÜ™Ÿ-¶Zýw²õŽù:™\^PFô›Ì ¹DyÍVÆÝ§~²Ï¹!<S·ã…sbÎùã  LÔ ­\¦}›Ñ´†·0ÒÕ’U ¹ð9·§~“ü`qÃK_Ýöv‚aæ“òV>3Î&JSiŒX.+ÒIõõrm{sJè~eÒxœ Dq ßY‹¶`ќȆ9=¯ÕH þø!,j.ÅE-¥JCŸ®ÛF ÿnpð/•Ôîó;×3™¸úDI·n"qî‘»Ï|ƒïŸGÕÖÅSÈÕÓw‚ôd³€÷L¸b@6^Xì¥\ܬ ¢‡Œ¿†=<†É9Ë<˜K8ðúz¹Šï-_Öþ¨æÕzþÙ”¹ÀáÇè ‰œžœÙ¶À’£Á uº‹Q”ÜG¢´IÿõzÎež »áê~wÍßà’¸˜‚V9tãa ÀPó±7—¸U|Kq<¶9x§“Bv 8J%Ãm77†È@ÇÿµÖ*q` @ã‡Ð°×É*t+¡‡ôÕë#õªªÊòþA_u0^¯8¥6\Άc^&¿¸Œ—µX]\ùJó´zNùiž(ß•ƒ6Ë;[’d5Bfa¤+¾ÇÙƒ×íú[n¯‘žx© î矷°KÓˆk—2@ÑgÚzXGZô†yÇd¶ÃâÃK'/ açYLðG„R>ì¼’hß{öçóÁØé“ŽX¸NÄ}¾Éá{Gí@©Iâg¤Ý uÂ)X ô¸ /‹+txû¾ÞmÓïV©Ž‹ß§è­zm&‰Âw;™öñ[ÛŠ¿8JǼ Y%VÏæ)ØÄe-fÌ§Ú %~ -=¯‘1>4kÉæÀâñ†ª]Ho·`q9’­–Wµ{*êZPíõ7uK;á >»gjº“„èÎÁ˜û±òÇe’•*úئ¼"»>óˆ”e"1õÈZ[b³KLÈ»Z1ŸzÒª_6*r¡+/Xazo,y2aSO¡> K&ôÛ!’?;y>«#æz? -£a‡ùòŽ»ð§8Zâ]%AD·á2<_ÙÅ8XI•T,Â2èWÞmgÙ~îKÏB¸ZÀ½öØcóCí˸ýa©n“>š‹LÎ3<}Û¯-„¤ß†{3b\‰à²ñû‚²ŠÜy‰°6£°Ü#üõ[v˜O®`âq,&Õ¾\Ö@²×Ü#Ðs<êåûæãÆÚšÒûy"=UùÙSÎUw fú•‘BºŸ‹[YÆ ‰Øtö‹ZšáŠåP;Œøð,UÝžŠ ^‘ýÛ3µoD´Än‹ÝÝ_ÔØÅaÅ>¨Á‡¿ø”È ÿ þ-Ú«¶š/1&Äñé­8–é“t³"ú›Zzé$Ö5}Ä"Èh I±æöë­fo„Éz$ióü-}þ¡™skzÑ'˜»ëÔq Lè[Õk1ÄŽ åβxkeþ(IÓØ¡ïv06j…ß½ #ÁCn¨ØžJ{ÿ<Á"ú8²]V®ÄiwC›µõ -É·"±‰ .¥–ˆõ0ôCºä£§5Sboá7Òè"}_ú%%{…¹a+­MóÖKy¬F=ó€`y¬þÈbó.ñº½I€og!§•¨Yla <¶~d0àÊ7«PwZ@h4f#-‘EÃÌt08‰°kWyð÷«Þ`]àî.Lq»2Ÿ?Ø!fþ}–'ÓÙi žVo’ÇוGÎèÚ|%~ R}¯±":&֣ψ˜lã3à›3½©œô_Ù÷Χ–:JÇl®”åõõFh´÷Lé™3®Yäp;b)K(Ì¥*¿ÈS+ýG„Ó_Z,Ææ Ÿ¾üü¤[†|¾A91÷#¢«Œ[ -gÏuÝLácA'w¨JÜ|û–£Ìß$—ÙÊÛݸzAX™V´ÞI51Ÿ²àpJ <Á‡QÉýEòq±$N. j–Zhî“ëòjph* 9÷dû®xñ—ËÙôÛ©âùЯb0÷ -‡\KžzpÖÏÇ—žîˆñYGuèµLûå»ÙN3…«4?v<‘®™º7¼Fþ=ÿ÷æ÷Á•ÄI8Ö]®Hîcï -?ޝÄdŸ»6¦÷Åyd³í3Õ JÏL–]Å1\/ÏÄSÒ€ÚÁU—l?y|(U—ª‰eŒE²—£«œ‹€ó"Å nSnõ/ÙÔ¦ÂUÔÆÚ†~´t•:à}—ë -èyêàTk9eå.ˆÁMqðóXÍK¯ƒôèµ-¥ i1»Úm–\ïÀ¯LŽÌÄ‹µ`É83ÜJ­Ú]®ÊÆ?h]‚ÏÀubIäø®x£ãǧJð‡³ï‡¬31Þ¹÷äl ÄæÄ*ìy|v |´ -š¨ôžJ±ÛÏêjôAy•2å&Lè´9?9î" -éðÇêOãhÂÅËRÕ–ÕPʈ¯¤2¡3уy“4œZÚþÎw¹s©b7Tý뛉i7Õk $E±igáeäwH#›éz††¨s° MRû2Ï6ìãvñÁÓ¶2bÙì NÇzr¨;+±sª)N˜ˆ¡Þ<%R¶wÄ‘g"¿d‡o¢=?4§Yä˜|9- O”'Ö·~úûÀ°Níۖř۲Üäóܖд›c~~™lòóàÁMUÜ¡^EÛÖšA[ûzÑæy‰^ ~Œ¡Œ‡x‰1ÌAÙÍÚ87¤s¹¿ÆÈÕ òè'B$;aÐЦkÀ2¾“ÞQ>ˆðc!S¨AF@¯^b‹£÷cˆUˆx½wPËÄ/Öy ‰”ª%òϦ†—vv]¸a?\¤Sy¢™™:*è²ó{^)æ}¥#B[þùîJƒC||š¤\b3ªi!1YgWðÓHÞƒê2¿ÙÑø ËÉ]í¨BlQNÁ›žˆ©‹Š‘Ü8d»“.úÊrjŸàüYç›SÍ -É”pÄ.íÊ?Á˜aøk›Í/ #ÏŠqÔxäÜþ¨UÒ˜§Ò—wÿ©Q¬‚mJêènÔAèbÛ`,h¢Ú"+ÏoÊ¥cúÏþ5§Ÿ ǤLK`sÇ 4Ј/І?ø¯¤„H§^Y«6?Ž F'؉MïôR¬‰YgwÇùQaÄ»'éÙ2MaTõMobÑ#ÊÔØñÛV3€Kìï¤=©…ŒDóæ$ìç`à¥&T¹r¤$‚Èó·ÒQšŠ'sš‘É PÓš¬aFà”®²‚]<äÚŠ¿ðD¥D,Ž ]ý¯ý‘æŸñ»ÚDO~í>"m½þb‡ ö²+dnƒ›GP æÂ¸Ê$˜½¡UvDe¸Ð¬þ° ᫇{~ºø]£Õœ+{o°èKhö©FmùØî”¨* -*£°WH¢Á¸Õ6øôÆ¢icE[ÛËÛsÈ‘ôéÀ›Uç¹ÎUé WäÂÖÑ<î0®ýÒo¼dì´_+ÀÆôtô^!‰ƒÃŠºÎ+ø=v0ß\mƒu~,•\ãåט’ïƒÅ¥ÇÆâtßO,B†¨e3 ¸çh/* ýøž…T¥|QP †= -[þéô$ RõãBþŠ¡N0ˆŒþ”KÙÆ2ŸDYÛÔq÷YãkÒ©<¼Šò¾dçìÓ³‡¬ß^òQPÙÇ*\±üü½„tkèÜW'.mª^¶M˜Ý»SÎEßÙ`-E.ß©¸ÿ +KT×{ê/³£ ™…Ýá80IŒLŒ^ö>_apqá™Ƙ¨~$:êÏFÂ}BY²Ó-7¬˜1~ÄÛ,ûwE×1!6öÙZ:ѱI¤(ççMþâG8t9Bi‚&A.¤ZVü:±«ªU0{*˜ „§Ý}ßfIŸ•Òvu BÅñ-ƒ®CŠ>.°s’‰96€ÑáÕ¯û7T  1kÅóL£¢¿áO;M5šK¾QSvÅ0®ïÆmkèEë(:AúÖs­su sÄxºÆö {úýÆ(à©p©º‚õt…­:ÿÙ 4—.ÅöRrÕ*ænš» ö•Pªÿ8›zÖÚ™C‰ÅÞ7ÃËÐîÔX\gs·»§‚&QkföA™ì“¯#°Ö -†[¢ÐîÞø;UØ -Rl£1&ËvÆ:]ˆ|,‘ùus¥èð¹0Þ‘S;°¤¥Ä¸Èðý…ØZVýÁ…ÜUد>¬0¿X~ _8'»VY°S×ô·KitW¬4`—ÖH¯a‘j>Â?é‰Ð¢ÚìGw®\ ߈„Á\k_µßib^7¸Kæ‚¥ìX»ž©ëAÛçØBVp庅Úöúm~´º2ô`É NÎEÏÇU[ÆXžgFn‚ïÙ5#Ò¼¶cFy(˜•B®hm¸ñG¬UÜÅæ©c޵|ÀÔ…ªxðñïàIn–¢8ËÁ«ÿ±iÈI%”hÕüÐðCÌäHqýƒÅÄ'–÷’b¾jT°¦­ïgh0qÌ&â’ߥ޴…‹[¶S'ÈeÙ±0¯Åñ=B9òƒzˆ¥Ø™õª-n~›_ì^™IØ )-1?Ú*†'©¿Õ¼¯îm¢¼„‰`ò`˵£UP-¯­QzÈÙPˆùB„+î‘ݶšbüXäiﯥú¿ç2!n¦ˆ·VYBšÔN&f¸[¿R¤Ï†Ô´¯ãL*k!þÜËì/oL\,b°9ç™v?—ŸLâÁj³«D„PÈ¢çߥî5 -^Ýócs¼zäeè·ö‡ùÑÜz-½KÞ9 U^¢bÓýXQ÷éøx“‰ÑÔ\ãƒB ™¹ñ+´8Ç që ORåÛ¥"×NÌÇMŠ^ý|ô -–H…äKeìõ©EãédXk§©%(ÓU_‚Þûž:Ôø£³$X{QF -˜ê†…¾ëS†¤²ÐY\)A¥lKdÕ‡è>Žë¿VŽ[‹þÌ!_ÛÜ c¡,ç•S˜?ô?Ü»ý¢ÍÈŸöê±9)ö‚¬ wi®Êzb‚„5´eynÅ®nµ_`þ‹ð»+ êÚX™JϽåÍ•W?AnÄ -òYZïƳÔûwsC-o³Uy)³¸%#§S/LÂä{j±gàe™Köc«0vu¬4 -‰¾^ÁŠ8îþ ñt–¾Ü7‘áBµýæãMÚÈ版þrˆog´Ž†çD …~.ÕQ_$4QK«v³ö hVÍ&º•Ñ‘¿ÐlüòîØ'åUÉinZ@?{¬È¯Ê¦©‰|kÓbn}“š˜n”.? t¦Ÿ(ôƘB”NeoRâÛ à¶ëCM„ôaø™!ò±ôÚƒ/›)ê=±¯J`ùˆÿCCOñî>vw-A2Êaˆ{ÂV¡y¡³²÷.œê«e'Ž•6´ â­áÙÔ´0w—R•3Šlž v7˜&ìã…Ù²?å×}­í—̇‰Œ‰›A»l:±0‘’°Ä…/éKƒ°M -Í ŸX,_¯8i`ü^¾£Ü5‘ØY¦’…ÒE½4Fáš™˜ÝÐýlÿN§GxèMôèI)OLßÒ Ìì"–“ÀM’t𘛟†(gT?`–8Þ3ú*W‰niÖè?zï´í{ɪ‚ðóûèzˆÅäc³mcd‡zTtl7:àµ%3qÖ¢sÎ~¶[;)2­ÃG¬”ÂØ Óa}é®ñ†èXöùð“1ˆeüRûÝÚG±”Çf­¿vL³ÔÓ>”drfN蔟 $y*öËÔðödóš0ä y9÷”íAë¥>aÞÉ—Õ×|\p7L˜½ê®ÿ%q?°#p >åê< ¥2j£§H\a0£c#¼ø»>JKóTÒ!ÚiÂ(Oi–f -Ä.ì’ïÍr7)…ʙȒ¯HOúÄ®þ5{êøsö¬;˜âÏg%`R¬_ºÁJKDñÃÇ®AãµX7eŽ…D–D·ÀT8}Y‘Áþ¶Ä°m_zÁãõóÞz5fóùLøîa6= ÍxÑŒªOÓœåø^os˜€½»¯ê|ÊkLp´IjcüAJßsöàìRœ´óìCfFýxN|‰ë c ð~\н ûFÁ´^ì*öàR…&¬WG+œ#([/¡2I%UNçýzjËÐVþÿúû©Ud) MræL}ÉI¢š7™µo2ÁV¢é È—ÔÙâqb~g[¹Mð|zÈÿ^¬+È4†ÀQŒdNÛýU²?›WÆ<ûÝäÔw©ÒGO—Ô1»›l‡*P¶¢.kÀ–.ôÛb På©Hí6¤b¡Ð?cåWÄo¾³q¬=een®jß@A _ÃBJxÑ…6$ -EKb×ÊL0`›zBfÖD2'·ú}'ìb2†oh<ìVµc;^™qC>®íI¢cóø<`ë·ïï•=ò¿vˆ®ÞÍ^fí“uÎB 8G¹éŽæ¢rTÅq…wO -!ÀÂ1¦$rÃøÛ¢@ïa'±-WÞ£• Ñm)%–º•‹æ¿ Dß‹RCÓ\¯{øXjòÑF2F‡ØeÓ¬R÷~«ÚŸ³p³ÊÜÝÌYE+‰ËfÇNÁ&Ï–({—»YÖ…Í7,”‡(V2ԥɸ¢¸wV;Z¸·³Ó -Ú&|ðíqMXt–Ųó4 õLjTBPçá( r6CA-qg\ÁŒ¹–ªq…)¾L"¨DÜ'+æ[š/sPÛ–z8èÞÅnÊÏG2põ\pgjõAäåè¿:Wª´ü)©Š7íÓ -¼bà°dìDÚl]m)Ú‘)ÓªSC¼ûØZKó*NâÑ”ËÎÎ~Š:ö‹4ijú¤àa¶-‰òSJ¤7(¶p]¨s'«›ü‡¿ ©lï[FÄwIfÜpC9ƒÚ”šVu_»”¶ËFÿÚÞ ÃùàÔçÑ?£+mwß꡺ìÊR;ÑŒÖ{ A8ð£HÃõ5ÔU¾»¸—PtÛ‡’g0F‰˜¨Özeî2'Ë£²–°«†"ìjYßÏ8ÅËÒæùŸE·y!ë3™ÁÐ9“8NkD³Žu¶—kÕ)ÎHË“BÉV•´K+«u1&PKX/æ(Z/6·ñ›ŒþÅà1,ß»ÛÊUXÕ9ËšÞ[ +ü†4¶mDwuÀù;$òúíj¸(䎮ÚzyXÊ8òÙ=¿®kWÀˆƒ(?2fÐ’Ó>âÝÜ:<=›-:™6ÅÕ“-BÈ“¬<ÙšõVQNÕºý‡ -0Í%…‹6Uv]ô¦vÜ5>û€Öñi6ôRC2ªžIïÌÁQ¬ü«ø4+šÜ†¦,/¬] -endstream -endobj -1827 0 obj << -/Type /FontDescriptor -/FontName /XXGKWP+CMR10 -/Flags 4 -/FontBBox [-251 -250 1009 969] -/Ascent 694 -/CapHeight 683 -/Descent -194 -/ItalicAngle 0 -/StemV 69 -/XHeight 431 -/CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/ampersand/asterisk/at/b/bracketleft/bracketright/c/circumflex/colon/comma/d/dollar/e/eight/endash/equal/exclam/f/ff/ffi/fi/five/fl/four/g/h/hyphen/i/j/k/l/m/n/nine/numbersign/o/one/p/parenleft/parenright/period/plus/q/question/quotedblleft/quotedblright/quoteleft/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/v/w/x/y/z/zero) -/FontFile 1826 0 R ->> endobj -1828 0 obj << -/Length1 1367 -/Length2 7534 -/Length3 0 -/Length 8340 -/Filter /FlateDecode ->> -stream -xÚ­”e\Ôë¶ÇIé’fhP¤»»c€†bˆ¡é–’¤¤[º I¥E:%Å;ûì{¶žsßÞϼ™ïÊßZÏóüÙ˜tôyeía¶%˜;œÄ’Èkê >\66y/…¹+€áIHBõq -@¢’Bâ’"¸ly˜ êèå9ÿ -ȺA¼ v`w€&îqCÖ°»ôavPÁuuèý•á ЃxC¼|!ö|¸ ÀjØB¡î¸ü Ruw€Äþ6ÛûxüÛå ñòFŠ‘"9H‰ö0wWÀâ€Ë¯Cö‚ •üˆúïâJ>®®Z`·¿Êÿµ¤ÿã»A]ÿsóðC¼š0{ˆ—û‡CþÖ¦ ±‡ú¸ý·Wv…Úɺ;ºB› ÞJPˆ½nçp»zCþe‡¸Ûÿ·äÞþ%_IÝÔØT‡ûïóü—O u‡ <þ©úWð¿ô›‘Ûñ‚úÌø@È@äïßÿ,ÿ«—¢»Ìꎼ"¢°—‹¼H‚Pw{ˆ?âÌÏçƒ#SÈ`^¸§¨(€_î/Óß$à—ÿMâ~…HL9Îoø•“ €_åGFêü&dMãyøÁ¿ ÙÁö7Iøíþ!¤Ï押cÿ¶ ÿeqsû@¶²ÿ‘ª ¿+ gûûŒÿ @Vpp€þ‘ àwü‘~§?PÀÿg0R‘눔ëöAH)¿µŠ çt‡ºCþð#µÁ~Ï‚L†ý‡¹Bßnd1°ÄÝâð[¾0è­^ÿ1•0rN仂ý±‰¿&õú‘“xÿ÷A|!ÈE†{#oÜïdÍßDáN^?v‹÷ƒý‘€\ŽïˆœÏï7 -" ~ FÆ@¼þÎþ¿OGNæÈ+$ àD6–ˆ‰ÿGœr ð}•ïïßìE¾VÄb‡»0³{áœÙU¢XÿÕµtDÝ“ëKÉMe6)á6æ6£ß­w\{î¸ÒQ˜grÖìý¶¯Ívv@ ­Éi¶&b˃ù2|¨­qæ|_UûÓ—Ñò4Ó×ýyÇ{…:@ƒoXËL(=æ¾ =9¢b&JÙ®†Ñ‘uìBLzÄYžå1ÂÑ+~Äi)+ÃCœ£±›¹—N`í>oб Rï-ο’1§ÈµtŸ˜ýì4çæêŽOPáfL(NÌii½»©Êå—žjdOÎrŸ‘ÊM‹*6³¤ÌެÑ5ä…ð=[ž‰-Ððä«Û.Ëó^¦Ö2í-¶å\òñœ­¸¿×Úo5 C­\z´S\0åÔý¬ªíãvñhÙ¡í*ã}ô× yP°5;)Kõ!ŒeeUà²Îoå%¦EÞÝ›Þsc -èb „¾ -Iiö?È› À$&»(6ÞynüÈ-[Ó®(XåêIöqJ[MA -DfÞ>z†ê šÙ§ra¿ìhÝOL;@Îr¿zÂùºÕþµzGÝ#³HÖ⯱ ¼æ©Í!§Šû¢ª¾?(k¾ï1Ô_?À‰Ý¹xÒ!´è‘=ºY@©òXÄ´”޹¦ëž{üéÔj€YàjŽÕY’•NÞ˜ïL–iu;ÉÔît¿¢}T¡=ušµ¬î®ê#H$þñ²g×™/‘õàQÏÊèöý 1œÌÈaAÖfÃ7<h‰óæ¾<ιJ5•¢ç©u²r§¹ë§” ©PöÅÓ—¿ƒñȼºd¼õý‡ýŠxR(SÉ9éÇI<ÔØóv¸îËá]<âÎÚØ&2Ú!v%ŽÊØÏÐ>ìJab~ :œ$²ç~ƒÆ„]«7'³X;f™™ ŸŸNáÝÄ]‚ðxà«@:aþÚ$åÍV2 O‡·^†œâ¢²ü9´½»ÇƒD$GYZßstü±ß§Ð¶óW£·I}ü›­Æ<`ªø¹ÎX—:œÞñ®>²¶¾¶¹˜é¼ÖÜi3ù6G6¥ >/PZ>8”øæŸý¸avC¶‚±1ê%¿ic¾QÆáçׄAò$!¸|ÚC’ø:¹“>ÜuI€Ü|wZ6Qÿ™‹<ý’G­§fw_€…ÒðÞ¹÷á`úí㣄†« Ðgð3G~“ˆ§_Ó@%þÊÙFΩR|Ï•Dz[„®Þ½†Xì’”EͧÒ}$}<ö@ýÒ/5püúÅÛ{Ô8ç&`£‘’¯ÙÊ‚D¼}Y&©\ý‚"ð¶Úoÿ0ä¹Ä~aé—CéHRÍ5´ÉZÔ¯A¾«²64be(ŽhÕ/ámëÕ‘~./ÜÝpRAþn"ue@cØè¥ Å.ºÊJÁVǸuz¯X2a?ŒE$eJ–2ÞnÒ£ ìÎ{£Êë˜#xË3Z (u"²áʰ÷5«†C¿ihVe¥J]~DòtS"D[LÄFÈöåa|yá`òeî<\N³EßÜÕ(Û§.öz\-‹Ë |7ôšeM9 úÔ̾½Ç©ôÀ;È9I4CkúŽ÷)ÝÁˆH©ø3¦ëÀá-‚e™d™û¿y›¹òQè“tüŸ5]Ê[\.ËX×Ó¾§åÍ÷Gp`xÜ[5kÝGΧÛ'[깃±æ+z¹ŠÉolO-É7»ÎñD;ÉíWX -q„"ç£Ö¾æPf·Ûº4{›`âËm~,MŒ¨L…CìšùšJØOÁÛº]ì Q'ý¹½,ÓÃ(8ƒ½ýIF4S9êX¾5ø¿è²N¢ÝžEˆ9Öµì{jâš*ŒáQííeÇx²Î/Smx³ª<®³"uêðÁaæýÅýp1 Šˆæ£‹{"ïB½e?åÏ?âtæ:Ò;I)ƒAÑÀö”©"vœQ)g¥âп°"ª«sT[lçve´§<ò˜-Ò-Ð褫-ëÀÛüv/ƒ·c¶ÿdìÔ,Et¿á]L¸*W±i)l–œY;DAÆ»ï\Ö´[Êõ"°“o²Ë»#‰jM¼ÚÜòÛÊ–/›ðÛÐBIÖ!Á¡N(®Þ0/k-iÌ ×Lõã‹îK0‘ÖÉ9犬×OJß ö¥ÏœÊ­$ñqË1U=©SOY« üHc´Þ6Ö¿©¿%±$/<Ìhðùÿ†èA\„ Ù+[ò#§ŽÇíŽBNù]lãÇ϶Ç.‡L¶m¹A_üœ&ólÕ‚dº7gC M’ÆÝŠg¯h sûž-ÕkÛô´_\ëý‚Æ,Û?èO¶|Âr€Ú¬pVóG1šÜ°Îi³S‹Ñ—Èõ+¸[³ K.”ý}Fõ‹vÍŸ™ªÔ]œÌãÖo5†ˆ -YÔ,ºÀvt¢}ÇVvF™á°cÿ¸|7¼2uU[+’<Ëç³Âã˜ðúÔ_õ¦1>0þP¥]i(ðÝEåa¿©«ÄÝ-E@÷^ðØ >6^æ õóW|‰dgRj*•7¿zŠZ}:K¤ÛydN‡í1`&ò˜Ëºûôg@Æ7 øÜAM­·$ŒÆ»(§2‹ûǵǢª¥øÔ|9"5îiXê»~áLZ®•ñ¥ó5$ÂΪm.UÅl 1»CØoÉw¤LûÈ€u?dÂÎúútEXΛvX__nÇíÚÛ{Çq$wÚû’¡«å&PH’iH¿§³É† @¯XžT&ÅDÍì8O†z­²j]*^©°c‘ÛŽÐú€´oøü™áÝSÔ  qïC^óG%~à oQÊG£Á´æ`ÁoÕæZ™Å@»~0-¬ -£rÉMÓ&èû nÁp-%x~âÑPv¡è¦Œ÷ÆUÚLº¾1Û¬Á…Î’”µJN"Ù¶"ý#|K°¶>øÛÏAÑ[ƒg…µT³¢Ç[ƒE$TOæ拦Е³F4ŸØÍüÒ˜ o Ű©c–³Ç=¢¢©ØÄúˆŠïNƬiÊ‹æ+ÓRy<ê˜6 meÓY`Õ§‘ìÝ«>qʼn4»°¬.6;5•û×{J N¿”tBѰÀøArNÃ2ç<=¡ð¯:ý2•ðÛ»+FE™©)ÿðÀÈb«'O”}Óí´?‡v“dgí@²Ÿ­øl¤-?°õ´­üD¾K½Q¦î!Á6b²S°å¿òjw*Ñ«ñ£2¶°@•j¨ñ£‹P{Ww&·' øÖ{1®”VtvÜ)ßÖ:ÎçäF—Äë¶=¢•r#ý·rûcNmº•üÀF{Þ;%ÝÙ¡È@è¾®¢F ÑBȾ&0=Ê3ÈßäÔØbM&êá—}’¥öâ. ×üúªžD½Ñ`MB£„xÇv-7% í‹?qåÞ ÖPêε¢°Í’-i¡*ع-6K‹›‡.Y(“l¶Õóø–òÅöîV„)&ÏÊ«ù‰Ö^ÙK+¶*›S‰U7«¢Ê¨ä!ËÖÕ ÎTFå³Ñ°ÇØS )5U˜Ù,,ukÖ¯D¶…En5W1¾&åäÛUhŒÇMw™>„uŒì¹7d¿«ëš«ÛÛ¥Ið#ÎITo}àé^Û]­ÕÎû˜åG#ÌXХääþŠ›Õ WU#LI¸ÀÑKÐñUˆóp÷[?ô^C×) v» -È[)ãîÐ1plt¤§d,†=A-$áy|CìH½Æ22¶Ht¢ï¬¨3µŠMB€Ñü¢˜ã23zÄÿeוÅôj5ü§»0#§WMÅÔ€ëÓ~êý¦Ö´G¡Ïê¯,Tt-;Ê ›ë­—X(ŸáPÑN~¶I$äõ·%¸EÅòFIÜ‚ìÁݘ[Yaº…º_AÐïÓ‰WN‡x¥Mˆ-xµ’Ö %c4ã77®Â|îö© :û'§,TF¡ñEUV"-hÅyi:(…oqmuN™()YÀØôÓ1”ED’6™vœ,ðÓj¤?ä= È·Í[è"¡#òÆýu«Ç³J¢ˆù£ŸÐ궤pU7TA ©‰âûà˜WzI½uF²¤#FgzBÎÅj9ÝêçJ%E¤«Ôé¢ tãO÷´« ³Vkèçx@_\}âå³¾ì³žÍ VfÍmÕaýÞ<¿ØE=êQí ä3ôl‹e/ð¡­Á³H´ò©ö7ˆ‚­ìÑÀ¨¹w¥AR†åæ+Þ{Nÿáá‡áä¦ôi­¯Ÿ¢G¡6JwÀ={åʼnúR™–;l•wºçŠG‰+Ž$ŽÆSȇ²‰ïѯ˜a?‹ŽÏ>˜Søìœlêٺط@W xNÛÙ…×üS™J}´¨3^ïö¿»IÞÏ/i¼Á^ Ò¥.Ôºì9ÇÞø‹Ið· ÂiE»Ô_6Ebq‹ÞdÓª ªñvîößž’ …za…?}]þ”ÍV¾“õ;Â’"G±?§éM„ÊšL -QHÊÝJ$)½oÔĠ8/°®ësDÆN†u8YNˆäª?a ¼Ûí¥#@·ËŒ=ÈåLùP­.|3ä]°š"dP¼Ç÷ô Š{ƒ¸vO -“niº)6£–eD~br±ˆXëÜé››¥ÞB ÒâKFUºDŒ&ýë>š‰)Ε%½Ë²wií¢>IÌV1+†°A6j, ¯»e …WJÀº«\ôˆDmÇW§_¬ûû®ÑEŸ+û&Œ‹cû S?n³f8ŸÁ%¥ 7ÖCm,êS™¯£/Úœgcê*3t“aòy»gP¬ý¾p>ÓqQïN%ŠÈ5æeËôØÎJ¿ëødA-åbN§2ZH™æcCfNÕºƒ¸_e®ÝŒ%ØJÛpóÁk -iÞÀ‚©¼ÞçŠÕ”'JDTpË\&ªÞù8Ö¬Ó :üü.)£¾ÆÚ­éʪû’Ì!9ø7F«žö>³÷v¤8MXÌØOÙ^æjê¾Õ$ï¦äh!3EwÔWÈ\Q=Ï*@<Õy0Ðí?t+æGéiäBWà]øPjšnχÂZô9ž-áÇâTI…6æ€éÈ>T3fÓ‰/X>_ÛÒÇ| ¬WX¸ZGÈÞD—mè:®£Êç¨ Æ;êC*ïüÀĘV$è{ôƒê»/|ûU>òg{Ÿ~Øß}ߨö•6ªŠŠGøÙ¶š ZÝç^ÑÉÅä¸Õì'—Ë»{ËŸ-l.]é`k•×]î΋Մ'šPq”€4•XtÃÁÁ­@|"yÛÓ5Ò…'Wàú Bô€“Õ½´ÍG)ŸÔÂ<Ùù×?¸?Õ#³U©%µ&¾:j­éÑ,~i;;^y©÷9"®Ê뤑 ³ö³Ð‚Çj³ P41-°{L²P2\û§Äm…)ª #`ŒcŸ=75/Òû}¥5Âì-{'`/{²j¼•Ì'ø³›Ø$Å©sÁ¥i½W ÑÇh® zŸˆ¨oÙßæ9Zcsi„‚±û…«£øõ¹J.r€„M/×S¹¨•5âÇþÔ:Ç´¦ E°ˆÐ¾yX>O2¶,êœzáit$!d—rÞ=çísxªHmëDrnûd¿„…×ß²ø´'ÎÆ_¥=¾­`¦tÞº›@ŸiѹKSB¦ ï¯Å|+¬8“Y(ªçõªý,÷] Hûa©Ù¼lP_ßWƘÏád9Aû#|´çœ5Â.ê­Ý4ÆD=Á‡KcïDïÉø§A/…ŽÞ.«\c“.¬8´3NÂ~ÊDŸùÄ×´«Ò‡"Y6+ -P—#…æÄK[FoyGÑO—ïÜ•~n’ƒ%óT ƒÝß´ÐUp¶\ÙÔM¤ç5œì-Ò žGaÝkÄŒðk !{"bFSZh©›†ÄœšCïç“ÎøŽ11Ž%YÈ@×ݵÓôÝ„è(±rE•XÛD¨m@òü2߉÷¹mõǪƒZä¯Ì¥^=„MUzÈŠ»òøëTa.ÿÑ.®é‡qˆN<ïGOߨ_xÓÒ½ˆbÕ’ny"D+ ÷Ÿ›o×”ûÛý…âù™ž±/«µl´í £6-qÖêö¨…vŠ>‘ [¡¼zÑ@ìø|Ì/¥b½øeUäЦÞ"– Ò0“%\вsõx -E ÁÃFu'P3/„Es”: 66‹Þ¨˜PÍ!½;Ÿf•b´Ïž·7CZÝ -~ø›åõœ(}Zá+M…RØàmäwº+ª6·RtêxŽùt‡ì˾…ð]uZ²oð©cý•ÁMU¶QÀC!qæh÷7–¶áý¾›¼Š†Ÿg8ÏTkª÷ŠÐ®ª³6 ŽÐÑó„÷¥²®«¼’´CX/”¦nææ}_ìÂΓÑH¤Àt`“#ªY X`ÜñßÉëL¢3~Ðk•=Wb&³õùVΟjceoe•0舫)=æ^„:±Ýtý~+ÂÔvRæ¶Zš¡Éeqür×;Ÿ33ìýìòý .ó¸çðÕºŽÍ3€| ÈGÇ(ù5“.+ 0ì¦UK–ŠÆ› ÷%zYü‚³{R}^Xbj/Û–ÔJ'V¸tÝÑì±ÿë鞉DÎPZ–ÌŒ:‰ÏWýߺk9)„ÛTíöÚÐl Ûbâåu²‡Æ­–˜1¢9|9nàu^êÌïwëoXšø”®«žŽyÁ$…ÈOûÐT±F¦e¯õqí†Ê~àøÿåÀˆÔŸº Q˜ô”Ø õOÍ+4B™£|òZ2sÿ mbW¦’”¨ãœžîp{¼Z¦#ÎŽÎd©\Òíå'x¼«¿06 lÃMGæ¦îܧ"zeT)Hý—^×A§Ðín·ÜMŒ#ÿUÜTà -endstream -endobj -1829 0 obj << -/Type /FontDescriptor -/FontName /FKYWYP+CMR12 -/Flags 4 -/FontBBox [-34 -251 988 750] -/Ascent 694 -/CapHeight 683 -/Descent -194 -/ItalicAngle 0 -/StemV 65 -/XHeight 431 -/CharSet (/B/C/D/F/G/H/P/W/a/b/c/colon/comma/d/e/eight/ffi/g/h/i/l/m/n/nine/o/one/p/parenleft/parenright/period/r/s/seven/six/t/three/two/v/w/y/zero) -/FontFile 1828 0 R ->> endobj -1830 0 obj << -/Length1 805 -/Length2 2064 -/Length3 0 -/Length 2626 -/Filter /FlateDecode ->> -stream -xÚ­’y<”kdz˖8e;éaLÉ2c ÆØ—,c™* 2Í<Æ cl‘ìBdçèPYÒ±•„BÔ©¤"Ê’5¤p„N$Ë;ê=§ÏÛù÷ý<ÿ<¿ëúÝ×ýýüî *gç jL¢ÍiT†*†ÐLmq€€© @¡¦tÀ Ó¨G P@ ÑÀ8È PWZ:Hmu (`J󣓽¼€¢é‘ -0öéd" -ØÞ {‘@hD2ÈƒÆ -€Û9àÀ@ ’`@"ÀiЋL€ïa¨ž4õ½L -òÿ» ÒÙP€"òÀF$Ѩ”0€z -À±4ö] ›äÿõópó -KðÛ¿Ò¿Ú?2%쿚Ÿ¤¶4H§þl= ~g³Iä ¿Ÿ»B&S½(  ö½D4'‡‚$;2ƒè x(à·:H%ý ÁÎíÜg‹q:¦üý=¿õìd*Ã1ÌÿŸ©;æoñC³Ó¡“C¼LM Á6²¿¿ÿÜ~ºËŒJ¤‘ÈTöBhj:&ÀÞ ¶Ò™JC0” ‡Qi ö€ÉYÀ“FØyN-Mn¼Sú¦PnñC!8æ‡ÒàØ”¶:ÇýP(~ò›úw&&´ÐpU$PU×TКJ}ö|Ä :¤2¾í;Í¿µ'™=†‚DÁW4¢nœO^C3Ò¬äE‡‰×ítl}ÛË»‚±”kO¬”FëœÖ+ ÄEfxf†lÈ&·DØw›/F¤ç÷oÍ{Ìœ¹#ã´\`6í/¿;·§¹¡ïÓ¼&DZÞÑ.f¶séƒÂç®Ú)u|Ç÷FnW;>øfû¥8-”“yåxb|Ý!¤N4?€y^#q$D4;“{äyl¤O"£òð­%Hl½„ÿJÖÖ)>÷+WöÕ,ðôs–ʨ×RsJžåAKÔã«ÂÈbêi:Š_hO†€²üI‹ ÷ÈskwkD.]â÷žYx'mPýð/Åc zD£ø&ìø†'57·ÿx¥Ì®ð/z¥¸?  +êGG”.æ>ˆaá§ßdÉÏØv‡ -ÏiSÅJ/?þúåæ}WõØ•gåÖ1¡Wk -Ëß³Ž5UCþ*?‹ÖvÃí³è¨¨L»Íƒ ¢6¥}2«¶ÂD0n<Õï7£¥©Djeûà—°°œüœÕÇÇ0âô÷Ì­ qý‡3!–äת>MhßΦ÷2(Ì"HöS [Û8PÍ\<»‡‚n7I[ð1€ÅÝ.­©r¾»%©ø²q%>Žàtÿ÷‚ åYµ‡SŠëëƒväœèô7{@£~tÓ– ›vü’x†|õ>Lwž ›.Þ)âÍçžØÂæ×ÉF„=*ÂðñËëùòÛǹ\ú¡æy{bÿì})RY»Âµ[¶eoê’X³¡‘;jŸT™ó±-žv$Î0çڬÑ3Ñb9‰GPÕ†¯¿T’¬­»O¤(ø5"ó•µ»ßJie4Ô´GeLÔ®UE³}éYV -Ñbz¬*µ ÔÙË©­Þíýõôù²¼ÓÏ+ËBûO>w›EYjÞ½«º •þÈJ¶9 [6UD¤ÚsʽSosÿ¶ÂÖâèÓ[!çF±×ˆübùæä¡bÉó“x?_ܾÞTçÃr= ¿­A_BF½Öcø -1]ËÚùæb$‰ Y”ÏFàߟ"Í Dë1|±ygtæQz VÌÔØ³ès<ž,;ë¡«¨s½rV²ÞÊ‚Øß˜¾*aظ¦°§Æ|_$˜™Š!~‚çÜ™¡•ÚÎÃ2Xi‰ ¿éfUf`t:‚ûIå€GÌ4°ð%«Á±oò-üüuå“÷bí¢"XòREe•æ›–]ŸÓE§b¢Ïë |@m}-²·º¸ÎduÄÄ|ô·é¯ïœmú-°ú Þ¤oû•œoÜäu’XŸ.³ä³QÊzØ5‹S·dïc„ìU–¼ÃMwsµ+Cyªi'Ö†^צY;+²Öâ‘áUQ:ËJï”G>2¶5sL_&Š5-`ìzYÔu~éÖV=Žú¬Ã‹_œ-.””ÅYe™ÄùÖ·yýñLiV(¢Ø-‰çq›±4J®îùhÓUW{YxKËÏ=æs'.P 5.„euM+÷WwÙ[ÑÉ͵aÅÉà½fiôÀ·¦JœÿÂÅ~!#¬ô,”Ò{xPv3ÑÈŠÜ…µyÑk?ée$M^OèIm³Mtœ…¾ - ÕÉ'Ýe•ª( ^W]Ïõô$)X÷ð‹ãËa+¯'öu ãœîÔé»)óôº ¹;¿p"~gb5<Ô çmqH^ÉÉÏÑ£ý -MAÓ®Kó®Þu'¢<ŸwZ>VxlÝvkðLRîzù3”’‚ã–CÓW± ©Ø†GZ®öº]b$ßb»Å‘ó­Á§Cw‰†[ Y³k—)“¿ß.‡Ô•—ÇÕ6oÑ-pJxé^FuÐJâŠZÅ£î5s¤ðt» ÔaHb˜.y¡Ì¼ë¾aÎîJpÓhÒþ Þ2º:ñN¦Kxõ>ÿJAûŒk ÆámwŸÜW¯®Î͈/—ßžÚ}-Adj¨ýéÄcÝJ¬ ‡Jêó_Ÿa+úÍä[ND´ŠàXŽd Ùð_­KUë,[ÏÒ˜±*v—§ 7 W.4Ë}F+ÇËUúnü¦+ÙÊA̘1y`QŒê@oƒËWÁ>ËŸÙŠ÷ð(Ul5ãE¥{¾×µ~W²¶]¬sÅ3jþÒˆºÐt[Á?.\,Ôz_¹Ÿwé…©EkëÑtóÕÄ–vÍ­fhéý RÐôÖŠ¤6¤fÏuÞM‘”ªÁ­¤»nööÝûCòðjJǯì˜0·õ¹½ÕÒŸŠºbÊ båüõO6ô=ªŸ y‚¿PâÏñö^/ñÒ º`\¬«°S¤_z9•B"áu6Xµo×2‘s³ždÜïáhò  °Ù!7‹®ÑXVjê÷Ótùxði³îë2nYlN²­­QUa‘až›¾ð±5neCO^¶Ñ5ÁsÒ"©_ª«×÷"*x¸’ôdwg3žz­ï>Ík…-½aïp»w*UdXjÀÕŽ( yÖþëï›ÉB€Ù.Œ+®‰÷gڦĪC°•—C»«d.HÃù> endobj -1832 0 obj << -/Length1 747 -/Length2 1286 -/Length3 0 -/Length 1814 -/Filter /FlateDecode ->> -stream -xÚ­RiXSg•çÑ£†M[•í,bHB lŠ“ˆ6)»Ê%¹À… É $@0,:T¤*--2 kË2E„Êbq‰-B± Y)€ãÌ3ôï<÷Ï=ï9ßûžï|/ÎÀãôa'6Ñ.z˜ˆ'ÚÎL/ -@Ä08œ3QáQÈ ÚÚ'A@"Dk;K[;ƒœ‘h GgÓupŠ‚x0 äL ‡¢”=X 8°`á'ðZ?Á¼ >Ä‹…Øx ‘°a -„@a0c±îÇ…Š”÷e¶ ú ñøJS€‰Ò¤) ´ÈF¸À†B1nˆr¤tòÿ0µ¹9]Àá¸Qëí•ý‰£`Žèß<-@!ÀDØ»Yê ½·Æ„ذ j3ë‚‚˜åÄ ã@á} æÓa!Äö€QV8 -røÐFâ²7›PƶaÁâ”k€“qhã57(æ¢Þ¢èÿ4]×n`â±2, x¨*¿g6¢qYæ*×ÁÊy÷0z•Ð6/vº  1Ležµ‹ºU‰™)6Ô”ÕÇêf¿N¯½`3|#–÷éËS>*íú‘à³Ö¤Ï™ÌU¥½ÞwdLãÚ1ã™KY˲·Œ1yT‡¦«wnÙí8r¦å°Ä¹º§±‹þ©2•Vf¸ºå,š–¤B ÏÉ= ~´€9Gúläw¿YýŽìKd:‘u5û)ëAšŽoçzë»drˆK1{jEUÖ»Ýú·Äª K/§y1ýþãéeÚЉ·MÛOcC"ÜSÛ &ìN¢e'´¶ d_øA¢Øå2BéyP¡Ú0z)åeD<ó‹½ù¹sÆM2Yò·¥O'çõ=œ%5ªš2¾‚I |«Ô±¶éh²¤ Ý”œQB;[{KÔ_×D¿r¨ú›¯2 »ý÷p¡&ÿÛhõ¡©–÷·» vq÷¯ù¹jïiÆ¢ÁŸwW'…§I8Zè¹mz …Ï÷¥Ý¢w|jÄÈŽ ' tŸpïÛ4UúÙ{-Õ* -~¦E<"ª¤PÉ5!»Êåö!“OmEUœµ¯}ì<ÊFfs33lç‚ÓK“õ‚¤'“vλÅù|N¨\RÛ©¨°glˆðçaåè%ë>5Q¹<†CVËó<üåIyÒð¤%=ëÜkáO1eqæ³o†æ‘³×³gúêKöG˜£–X-—íå”s@_OhüwW^vtˆÚL,MŒY½’ëm5{ØPè_»bJj™Ž½Ã– \\CÃìÔPYŒ×ÝJxCŸ¾ØmzS|>cqdËb½î考{Ñî"ãì›þæ1]K§ð¢Ø­ñ‰ÆKÝOíimš£ó™°-º×çØƒÏ:Ž­L)–Á©tpÑ-|,Ǭp®šH SqD47¶ž¿ØÅ€æê:©Ce™ùZÔì}g>Ëp²kÆ.Ý 0>)ª_Yvª/oÁfQ[Wûöw÷¼kÖ¸½ðþ÷©œHFuOrôšCPñ• %ÄùÊ™ÇmŽ˜ M„1Wá "‰Ÿ¹DÜ·ÐRæÿ lŸ -“ éÄç¯[ÜOt5þ¯>×\¤yÿ¸¸_PzMÿÅ«¥µn‡ñ5JIcñÏu”c=eYZòß$ÚW{ß„¿•ê²:n÷štç^²Q\”¹ñbµ5%3y%5÷õ¢z~ö רÌ{ìï̺òk‚­Æ‚iîòXB¼ôd%x*±­Ñ5²òî‘!O™=(€†N¯†xO¤-?ÿÆd?×ôÄùw^]2•XW¢–¦³m…v¿˜ø4œ‰46\gžñiɯl‹­Íñêí­U6¼»P–ŽXT©ðÎWw´ÓŸ™å§3Ñ)‘{à è\˜‹Táx&ô‹9¯qøc7õç‚Ó÷÷e0ÿ·àw -endstream -endobj -1833 0 obj << -/Type /FontDescriptor -/FontName /LKZNMG+CMR7 -/Flags 4 -/FontBBox [-27 -250 1122 750] -/Ascent 694 -/CapHeight 683 -/Descent -194 -/ItalicAngle 0 -/StemV 79 -/XHeight 431 -/CharSet (/M/T) -/FontFile 1832 0 R ->> endobj -1834 0 obj << -/Length1 815 -/Length2 904 -/Length3 0 -/Length 1456 -/Filter /FlateDecode ->> -stream -xÚ­R{8Tyî&j»¬†P¿j=’ÌÌ¡1ª]&¢—II«§cΙq4sŽŽƒ÷J%Â>±É¥eyÚD¹+Ô°vcõ(]´¹´ÔØM¹dsÙƒzÚÕ¿ûœÎ÷¾ï÷ýÞçý>õ®BS„ðAí œ2…Xà; ÷A±8 CC>‰ÂFàÛa -µ¥%l%âÏÊŒcÅå1 ŸðW˜Ä—øÆS"°‘¡$&‚qà S¾¨Œž!‚¥@Hˆ0”R°€T -ܧ:€;€’A(Âb@@0|P †3ØSŽq1x30èÿ -BÉÚØ@›4´E„À¥ -€ b[@Ðo¡´“ÿÃÔìáöR©–MŸNé–aRÅ{!ó¤P8Jâ³¥{ÑsÎ(‚Êf³Ž,ÅD6¸DŠSh3‹cÎ!°{LŽ"®%òbX€Nã(ŽÌ¶BÇ7m„íi·ÇKèiò~¯Ó¤+ŒáÔn…? -8ÕÓ5ô±¦S"19ØÏaq8-¤¿Þ³³ÃE‚á`Ƶ0I -}AtÅ¡Àp•TN;f³p‚¢[M8$cj­ææ€MwÁ3 £¹i˜¾2¶8ú/ˆVŠ0R$EESûýHp[†áÓÀ§IØÚòPS3K`jiA;ƒ ÀãqÃÿ#’$ŠSÓÇFçù¡côPTŽŠím„È:Úï̵ùvÙÍjlQeQ_»úOžeé.äfº­•P9/²:Kj™‡ZtvЬSV%ºñ‚Ó/®(,½çùM·šõ@ÈT‹M]œµëÚÙ}åTÖj¶UjC+¾¼×ÎOýNCд0ÖÌ9°t8µÌ7á%›ÙÓ¿¹©­yGNW”lŽ–nF˜›÷uF¼ l?±0¾¦§#®ÞŸSØ€Òû‹Ý.¨Šä†VWYi÷×D,EV¸d…ç—jª§Lï×Y_(ç;4é $·{·Îçd–ûç²^»A©Èt(Ëd"E{G%Ú_ÜÖÚy=R¿w84ó¬H+ê®Ò-hÕ‘xiú¡Î…OºDûTØiUd|»Xe¶¬â–J-M™ ÞŸˆ–“1w¹)¹üñìæ,íÏ:nŽe^òSï;•ÝÏzöÕÄdr³ª†ßûpuoXžUCͤX“[Ž£ñÅoLÞBÉG‚5æk¾vJ[>huº> endobj -1836 0 obj << -/Length1 2243 -/Length2 14662 -/Length3 0 -/Length 15873 -/Filter /FlateDecode ->> -stream -xÚ­µeXœKÚ5ŠCÐà »Ó¸»»»5»'@p'¸»»'x hp·à§÷̼;{æû{.úkÝR«Ö]U™Š:“¨Ø $vtcbcfãˆ+jh°±ؘYYÅ©¨Ä]@¦n6`G S7€—— êä`ç°±òq²C~ÈTq°“·‹•µ€Vœî¯$n€¨ÈÅÆÜÔ hêf r€ô07µ¨ƒÍm@nÞÌQ{{€Ú_®5+ÈÅdÁŒÌư°1w˜¬l‘YþÒ$ëh pÿ›¶pwú¿ÈÅ" -@û/™tˆH °£½7Àd‰Ì¢†¬‚hùÿCÖÿ6—r··W2uø«ý¿œúâ¦6öÞÿÉ;8¹»\Š` ‹ãÿ¦jƒþ-Ndaãîð¿QY7S{sQG+{€õß”«”ÈBÅÆÍÜàæâú r´ø_ çþ¥€EFAYIUá?CýWPÅÔÆÑMÃÛéï®eÿ ³ýÁ{\l¼ú¬Ù ‰¿ÿûÏð“t4[Ø8ZØ\SSodÈñ À— `ãhò€¼ ‚Y˜ÁnÄ€%Øù¯‰r,¢QÿF\±?ˆÀ"þñX$þ ^‹ä߈›À"õ±X¤ÿ vˆ€Eöâ°ÈýA-òD‹ÂÑ¢øA´(ýA-Ê#ˆ•?¢Eõ‚hQûƒ ZÔÿ ˆ?¢Eó‚hÑúƒ Z´ÿ ˆ?¢E÷oÄ Ñ¢÷AêLÿF:S'ÈU2…œ ¿s *L]ÍmlÌm\ÌÝþæ9Ùÿâ!‡ÙÆÕîÏþJvûS éhöA*ÌLÍí\íM]­ÿfÙØ9ÿ¢]þA@\0s15Ùƒ,ÝþAÿCÿû -ÿÝ•íß´Èí¿òy9þæÿ§bˆùß‘h¶‡¼oŒó/ÆÁá1l¬×þ8ÂñÞloÿOÍ«ÀúÓ’ú¯E¹þŠ;»CÞ–¿»@ôA®½©Ã?º@²üÓ’aiãñ¶…Áîÿ\’bõgHÜê¯÷ôÏÈvþ¸Í 1ÑÚÛÉäø góoû9#vÿ€¿þl‚ bŒ=ÈÕõqˆ»ÿØä‘aù³ÒËÑÆô8Äðubð…!;rú†4s2u9þ× 9ÙþÃþ÷˜9!Û€œeðŸÁqBÜr²wÿ‡Z6ãüg7!wë_ß·?sâü‹»,Ìþì›—ë?ä)áàýûßJØØ -þ16ˆß4!E® ›ÿ>„À¿r@ÿÒÄòÿ½ˆ—ÿs“Ø ªþ, „øâfíúÇùøçæ þG¤‡ûŸMAÖt‡<Ï.®æ`—2r@ˆ`Ï\KHS¯@ȪÞÿ€úüÑ éärù·‚ÿ÷%&öòeâ0±s!ï2äådõÿ¯4swÈ Ýþõù‡|æþ[Ú@¾‰ ÈyylÎj›Ö^ Y0]O-fÕ¯Tß3׉²”m_4&ïL¿^§óPžþ þ©çÓ{×è?Õ ©³`çøÏó/¿t”§B+¡±‡øƒ ªWߣ¡73”‹[G*Ã^3"¬ŽšƒLíígçÒHΈ5ϷɉpkS!¶H- «àw¬‡¤Ü¤c¨{s„ØÅ²—š§l#2˜xÖ $¬î×b PõEÝ,Tf™U½éU¿·9.·ß­tOoª·ÕözC}ÚzcF?A°7¬@‹8Íëª}‚X.…¦wÄ'Ù\¡øÖζ2D&Œ•½Xò?Y8SùÄ¢W˜FSÒ€éóJ,?BÒø¶) ?uºËæC³%à›ÀFcÅšdÒ¥D¯Ò1ºžŸÜEâo"è1í¬jŽëîäWÌ©4Å…c§üÞ+Ú¼#ª Õ# ^Oí80ë–TÌÎ_ôÐ5tÍœF=å+lÙÒæOÎ =Ù¾Mºwv ei²4sz•ç«7]h˜e³r¬Ëޏ_‰]ùßÎnTÄöæä÷]Œ ·KÁé^ÜNœË‚H¨â »ÞýÊ÷OÞß0sHô»J ·08,]$ ÓævpOã(§h}ó–çu”<’´äßÏ…Kx?Ñ8ö,Ó¶zõzÁ¯²Èù?~/T‡;q)C¯{¬ù[÷ç²a%hsM–—}üÚSAEbc(ÛEZ~¶o“¼}Öýœ<׌#}Tpoè*·²âƒcÖ‹ù]n^¨@_{wºñ Eæ`‡|5îi~÷¾U¹Ä›—y££g³ˆÄ­>ï‰OæÝ"¥dÐpÚ!é×pL· ò8¤|7RÚ˜|ü—¯–.)j'òFÞ›á&ʸFáçÙ9a—70#zžjõè›u%Em¬½iBõ|'†b Fg2WØxÖ)Ú¥Ö!~ÍÔÒ޽eòd9gŽ9‹h¹ “‚š‘+îÌBn†­½CÙ²6÷ªÓÁµÍ¥nkA2¬ òVbñàÔ vær—M*d”‘ ø³€¹¾~ ŠŒ;#’Pbç†ô=£ZL´ Íd×ù¨ZçÊroN}zgÕ@]—Ä£ãçóÞÅŸ„œ‰)úªHZ` g¡cU!æ(&sfpBÆVe%eØß,‡Bsû’xVcËj@Ì%¥jtîÂç`’KUíà͈Çí²ã¤4ŒlVxªEÞfe¶²+h7UiºüÌÞµieQÅtÛ-p—kóëLü4í%6ò-ÒÍÚýÚOÏ¡ÜÇõÇIõ@øŸÒ‘Š«3?ìºD>ÿ„Ëϸ}àÛ–0AC.W¯ÿ€¶xÜUÐE¤ZÍX\±)£‡8ãÎtûI³‘A±Xƒ¾xש~Þ^©’Ë7Óõ±§h¦NÁŠ€ÿ1î7>¸·ñsôø×óO/"&BÁͪ½L2±ß™ô‰‘†iÃë6(›ªôî¼[±I¾¯Þ¿èŽïÅK~´tþ>ÌöA÷[@écI­ßN›~¥}•‘†¶ÌÝuy~Ù‘þvtA&$EÔu™s4ÐÄcÞ²›ä –©eR0ž™zùž><öNHûXkêq›ŽXüŽÞ}¨ŸÂ|ñ¡rº g`É2¿'Çœ¡:/åUñ¯gö1²çn<nâÂ)¯9¹Bß;許hª¹×?Û„†™ïâskVåZ‰.4·‡d¯‡ -”)ÁJqÿŒ‚0Œ[½¦9ò3<óÙ+Dö-kmñ>£Q’ž -³³ÃÒå™™û)’ÎT¹æÓVûñâþò(Æ0;1ËYÔ–¢S7ä]ÃkDMÊ‘ùݹZ}q 6xÁ±ná»ýâ*kBas´‰3V-£"þ{z¨æèD5˨€eJ±à,ÁÞ[á„ƒíØ½#fK2mÓ®…O§£¯åq -ãn¼CôrØgï#ÓÊ»Éî¡-F àŸ¸ž\(“X<]úŽuÕnU÷m?sä?¿"9æ,¦îQR¥V…µx’Ù-=¨¶gqàПæ8|“~"Ø7½`§"ù5¼9 2@ª˜í1‡=ù²­Q(ð^ìcHuè¥9„³…(ôdÉÜþÍ]³ YÇ“ùÃËBòÇñœc#¥oÙ˜?ø:<0·‘âwÌ} ó1CEî¥|>·Ó¿‡mg1Œlž™1x›fyÜlvîK„£pÃÇÒiÒ“wÝCcˆˆ')I…>yS«—¿T!±¶ÿn`·dyUëéJ`™5îö øûY½²"Wx)mB€•oÛ]œÀAÝæ¢×ÎvÚ^IvrÁè“Ú¢âãReNr®Øþ€6Ld„ë›s„}®’fA¦&Õ Ñˆ:)Ñ©Q'ÐÕ$Ýw f‚Ÿ-{Ô<áè“vÇ9%O9àYà»wMèªyÕ˜øñê"Q¨íÒNG³ì褞˜‹8‘ñ®(¬LÊaL`OVŽwSPèrš8sû¿œf.2ËÜ,0¿g<ÅŠÒ~ÁÄa½™|jSRô»zAÅ›îB´6—+&ÔtÙö¯õ½’fÔŸ¿ñn™1RÖòøŒ¨¤ÊG;kîÜ9>2‹.DÃM‰Moöê7­ŒÜ{Ž90•8Ó´;ó¾ö5’L²Û8J?Š–&—‹}ŽŠ‹σÓI)ÜÜ>fmÚ׿­ŠdL¿¹ ýH¶î¸4OZ„VÑé·¾¡?ëƒ ŠšËÌÝÔgýJµ‚æè¾ç›CŽžíLTQnšùÌÇÜlºÇgk"Ó)í™ìmÙÄg„–ìMWÎü%XÉAAbFÝ\”…AаCƸis -÷a 2Ð*T°b¸9HÕ®Kø‘ºKø&Èîè¶JÃüi±-‹óÞȰ¼Fçgö¤Ÿˆ˜Ï™MÞàY²Èj˜‹åÛáñ(uUù ž«Î’ùÝðÀ“½â0˜0Ó^˜ƒà_G°XãpæcX~4“>û«æ*ܲ)5Q:ò>ë›ãÎQw² -eÞúýéLq -špxAŒ,Ý[]l+lži“ÂÛ¯è7Vv÷Ÿ÷‰HA‹:þlx3)lŒ§L3U3F\ô½ûÑÂ]p·• ¡i´“²žïÚÍЬ~h4{rõq­qòTÊwÕt w†ß¾âSóÔ2±!#n•‚i6Eìî}™÷¬SçŬ~Äݬk“iñM´ ‹¤Fu`νºÆT€ | »%óÇ[ß”<»f0R!éøÝsH‘Ýe¯àLÙcd5,ß4˜+¬Åýë”I ñoš±»»lé}…¬’n.X ©÷Ùòém¶)ïaJ%/©ƒç6»a¹d÷'YIÆÕ¾Nç6œ1§7¾¥M^LÈ µërÜÃ_0C@å.îÒÑ,Z÷?y½²ß¹]ôá~Tµâø‰&Ý™»1ƒ²¨@Êà“|·¤iÇË}s–A0þ\R>å‰^ú­½#”Kî§ïýÈDß7Yyœt3«IK3\`ÍóÌp+‚WÁµHÞàðúñuŽ__Õ¨yk°-þË6œi³µZ3;ìÇ·ߎo|IV¼³}?ûsc'JEÚÑÅÇ ûeøÖPvKD_ìaöR®õ/l­w¿[p~YºÄÅ) -ÏœO-a¡},‡™gÙ‰XËÝÚùºDÕø4'@à£þ/ùÔŸOîîœRìZ´oßó¥ÑÝcm°„#M´vÎuò›Ó¾²©‰ÌNm2”ß~œˆOðt¬“Û4Ð*û˜áÔÑÍö…y7‰¤²#óîSØÆ©?væ»PE b³œõÈ—Ë[3‡"'³*•Uo¾×-Ç[‡€Ë2K¤8 ¶tÿ"ÝÕGn&—´ƒ)Ó‹Å÷æÆßœðé†ÌÏ3Œ¤ "غjƒŠPÅ4`L©5YP´ºgÁ%xW”ôÓïRÇË(…›×V•Ò×o«ÐøGϹêHÖF÷³ï“®!…¹E&Mv¡˜rmÐEÅîqQáÈ?ôœs1Ñ€_ )J4]ð>hM!%Yëe”LaQïÖqp”×`{2æ©k¬éËM o’¤<)ùÀ@¬Ñ–Ù{Çn'fŠ:÷ÏÓoˆ¹äMÌ·½_8ÊiÝ07ší—­RËã6áÎâÑã1ÙðÑGû£ Õ„êö`vNIáÍëÕ“ì‘=‰îX¨ýÔ¥¢?~a£çg‰äv-s{öën<¦!<|ì²Ì (ö*V¡äñ–wîAÏö °q,Ûcò\¦HþI×ÔÚKuíE!.¸kê4mƒ:pÇØÕ”Ž•È:a¿ªL{Eš;¤ò¢bGÃ9½ëÆ ®4ÌÙz:7:s“ÐiøT =¼éòN;½d -æOù¨}Ÿª“Fºcƒø ‰áYYåfÚOÏzO+±}GVäÌ€™¹î -3Ú›– Mí‚{ßmÑñéù¼÷4m±{òd ÉfØKhI?—Æ]:Ų3QÉZš/í#}ì«óñ"¥ÁMÛU@“Ê6">÷WMÌšô?ñ>|ßkÔd{m¢ÉËÊ€-1~¤@ÎDRˆÜò[ýF/5_((~ÄîÄ~…4vÁÎòì+ùôûÌäòøzGð$—“R£Å“Ì?t¦~š& u%ßÈôCV$ -X§5Bè­ßX$ŸÃÄͨMoyλøâÃDÁL³­!‚Üo ™Q»g»: -=5ìg7ãà€H$ÎsĉEû9qä,9=lÅûÊáNU6{4µêí”ñ¯™¹>éO¼ºË75ýE‘´Ú_ã¥õ­½´Gä"]­Ygùç|>’¿Ì¢[¢æò«3©¾­ÆÀ@êìݳâ}GB³*‹ºäîy9ú¨?%!gÑ +šÍó’éA†.Œ`§¨%€Å?·žV•€{ƒ Ùñ©÷÷[X÷ÙV -rY&3äµ&‚S&5X©¹[¿7 vÆs¶ìÏ&}EÜËßÜ“½Ä¥&“;vë…:g¬‰Ú™ ÷ŠƒDÖ½‰NtN‚5éLŸçI'+Î(ÁRcz× -Šì™ô_Ä)°lU£æI8n $ád,U®ÝiÎŽéÞ©j´Ùï0E³¶¹þŠÖP¡,Û/Ç ‰Rûfи7dÏu$ç`œ¢Ñ¸žvážÏ$Aäb6J>g;¸×›»®´½´(ü„NækWÎ xî›}Þ©CÛ€YðQ2ÃNÍløQ¯Qþ#¶dŠvŸŠBãÚ S&°u¿«ï¼rR:2)³]ù9tÑià*i$}·á×ÌýÅN—Ý#~>¾#.Â%t¥qŠvT¹›ƒ¥¸·ç‰ñ®I°«äý¢Ò -õݕڒË`“ ™È¡ÞF¶ýP4úƒxh‡èL?å&”OͯwbeêSq‡VÄÊ™žÍçæ—zWf Q´K‹âaœƒ{½Ñhf)w"Zι-Ëß»¿»ƒú4]Þ#ç¾&‡€åM¥ýæö™•SAÌφÁ9¢¹.éAðP¼s» -À`Í^`Àmµ9©¯i@Š %}Сî¨í®k&úžYrÈ"ø&‡Ýhz+ȶc1¿ƒ@*‰¼æŒO.?еÜᨈʀ4É‘^ï­U}0ðêïœëÿzKÓðÃ#ªÿV%À?kó0‚Ûè÷¤DÝnì&Ksž”—ƒzã‚Rê9&±…ý¤ô¶òg_SÖK÷ñ‚RZ¶e -tƒ¨ËÑ:BužXýÏçS±½}Ö˜GnŽç©R{Jú¬ÆeW[á¢×*ÀÊ*9QEägæúÊ-lòO½,GF¯{RoUnkißåÛç‘`˜SËÚ¢¢Ë3Â_nß}f¡r Ì„h z5æp­ÀZàtòöZd2R}ô0Òá^qc AL5cFt¹QE×Oše+Ýa¡\We§ÙR÷H;œtÊ¿b `"=¶oL -aL+¨vÄÿQAàЩNÒéø«w„|ñæü¹ÃI½µþs'‡S"9A1»”Y+Éù› ˜$žš>;ïóS…9)+îL$LèÃRl±@ öýÒ ó»ëŽQèp-b|«;BÿeTØ*!þºÆ»Á¤d<ž³*s»—mC®÷K;Íc:?Ì»ïâmêRzK¡LöZ(Ê‹|V)|gÀù½DnÁ¢¬eòsÖßóßÇR#Fä Ôþ¶‚Œöö×ïÁs©ëe±ç\¡TÓp%œŽÞ|˜)–¤&v|ŒY©1ÕDöã{^ÍwØÕîþ9¾çh+Gå( l0EYPøðäûS¥Cb­Ú8—òmŸMóuL{JÀŸbñ× fhNâd'C¼öµå¨e¥È˜%m›äe´‡?±Ü•>R¼ñ°ÿu4þھ݂ -—\>Äë´×eS*'>1^p¼‚ñîúK¢Æ£b+Ýc˜¤ ¯yµ¿`|$¸ü &ôiºeb7ùe®=T¡•&bß³$®  l­2¯äéôREsúå {¾{è÷: Ô2‡ë -FcË'Á˜v N··“ÎK¦çyå8¢Ý?ŒLì îÅ\/¾*ðlðvžb§ :Äú#uÒ.‚ñ÷lŒcºå¢¶†ÅBCN† {ÔK£%V # R¹ÝÅ„ö­ø=åFv9EÎÇ÷nY'¸z>ßnŽnÁ£+a– ôpG¿›ÓÂ'^çM¦%ׇ}Ä2C›2b-Äó‡]¸€/_ôÍæ˜f*ÉO·\1¯²ÿ¨•ÿŠ}‡ÍÕÜ þ©Ù3.´›*×îøª†°arI(Úª¹ÂWÔ…u“ž„ςވÔM_kc¦Vd™)}/òn$AX"l ®‚{+°‹¼Ùǯ³ã&¼œi}“¯úFö¡PF9mIq*ªQ/ jU×ün%}Íãs鮤6Žá[‡ÛWƒ·ïç‹ †%–³’è/ËV¾ñ)L³“z’¸ïKbfâM>]&EcÏ¢ô¶°œ?7T”Õ„çpµÔ*4kB³[=æ \'¡èœG'eS°Ê£L(e¹¬òÁ”¥hZ›¨D…Eš¾€~7Ù[´5>þ¦Í¯„(&þPu•íÊý¤³4¹‘`–FX´ÓaÍH+B!\-¦•Îz[5 ˜Ë¦›F\y…ÂvæÃ1ft׺Àá9  üc3'ß²¨ÌY‘JPJcÒ‚2ÖRø=!‹ÚÂÝçA1…Ý«‡†Á°U…Ðã:z©Ðü&0Â(ðd”Ìâ ”@$§îËv›|’Veç‡$‰ûÀœ4¼ï– )4Z¯l]Z¹©žÈÚðÓˆCßäcãD³ð‡—ŒýÃÇÝùÞ[¦õ‰*=•ýéïü_îï‚®^kÛÚsws†õ¿+b1àäßòêàŽÑ8eò¶#åÕ™D"é õ騩sÞ3xv‹£òK:J¶ ×ÃçÿžvÍÓÉãâÂ.BpóIú~3?›ø‘jë¬Fhr§@츬‘²QeÊá¾+Ïš5@á¸T%:^þ›§ú,Z†>ë–&°{äz9QðÇ~µŸ\Ýu#¡sr6?ŒÔÐc/ÁR´_ãž~yˆ£Þ¡¼+ ׸¹êéÃÀ '`Ãã,´¾'‡K ßôÇ;GG!¹ÉE’n,Çà¤EÀyÎÙÑ7ÿ6æ$D?{1“„iáêBzÎÃø<ø»nŒÍþšdóPœ½Êæ$¤ŽŸ§iŠœ ¤EŸæ¸lYvõLI¥Ÿ-O™õó‚^Ú"<É“ND[2‘ý_“±ÓJ㊿€I‡€C UpjÄŽ¡Ëøe‘-of¤Ê+Õ ‚Å&« S^+X³î1u÷1^çeC mbO‹¢¾“¡Œ/bHüÂAJðÜÁâ·¡WD•÷Æ‘ª½"Yuä'0ߦ9Ųí0 £¯ZØæ»›Hųþ‘*îr!Þh“ípsÜÿ ß’}ú,H:H|VÈ´û|(ƒ Ÿu#zÏ겘õó“ÊÂ\ëm3Á| -—Z 1qÉ}ü¯jsœ(,*“UèÙ…?»›Fbe?hæû:b½ûJ²«w:+ò¼QVvñ—䯕Þ+$¥£L   Œ+ïzõÙïmX*üœÆJ­g¦MùKo¸;Hæ\„Ì“õÅÄêer3Õl?›Ýdp}hôOŒ÷ŽAÉ/!±®þ¹fç¹Ð|K¨õˆEz >4¯×ôÙBƒË:žÅIÔ4´ÚÜDßü Àõ ºC¿ê'\ëBpk⪎‰n\Ûð*aÙ§ïþTM¯h9rü•4U¯¤žeÖ\­?õŸtÄäÄ“ì1c´Œ8Ö817U6Hü¿¦!/Šo€‘â3Šª¹ÏQ®Nd\Ò?MÊéy:Wf Ó¹k«Ó£’s]åhv›ø“Jõñ‚Gk˜9ž"Qdcgâ -UfhŽLóL֑Ʃ׼Té¢+¤Q%eW×h’øïkôöaJ[ÂÀ{x= ƒ2¾7ÎðÅŒi\èVÖÉ×(÷l,ÝÓzÑiÇW¸¸îxÕ´ôm™œ¡:]m¦–o²—¢HA„`Ê âðÁ #ä÷SöÇFÁ>ÆÍº‹?ÇxIãCÑHm¢:^Ž&xn[¶³Ž¬BÍwe£•sÚ@™ þœ&’Ýþ&á¸Ïo`MÕÅ6;eìóOÕ¿öÁ®Òvoj÷û¥ú¢á ŠáñðÄ[”ãH‚sx=Âg*΂;î -³%®ÊJþøo¾²±3FÖÝOa,²g£@m½ÇŸ( Qê\¯2 -SáÊÔ z§ÁШÞ,”ºÐŠÍH}™e‘<È’³ä'þL¶ô~mèã}/qhY8i?pø]zÅä{Á Kþþ½-.³‘;OövD­@ì×%Á\ªr™ íNmèù‘¦§Q¶Qïб6÷R%É24<ãš‹<[¦¬ªz.ÆŒžÂ˜•ö{¹9ßÊÞ6Ö¹>Üü‚·7Ð9YJ¤;>Ö• -ÿ=Û›-þʵ{ŒÓ—tÞ½Bc"w¥>x–E–î’wcð¢¼èÖÓ¬zr8w)6™éI´¢R!ZS£i4x>#™zÍxxäÕÖò‹|Wß7žÙ¦j¯áEŒøGŽRQàjìy¡hÊÚhß~;Ó0 ÈIo÷E89õLÓÔ†ùãÅ%'³±IS*Ö^¨<¨¬²ÒÒm¬îz~9xvM­¡+‰›UEûí¨DÉ:ʱ€ÚäþáL”½üܲ=•äçn×n¥saS‚°ÍH) ’ï¸ ¿n$/ð3¶æ¨¼+]weIÎÝüó|¿€Õf%æ¼X¤<¥Á܋ѓ+À–J4>]¹& Ã…:Vù®@ Ó†äl-ÜÞí6OˆújÛîÏä—ßß©.-mjkXÜ?Ðh»Û¡J!«r8œpo†áéÂ46œ!mU.UÈ‹-LzQ(W‡è·¢XÚeÌ ‡¬H"õÊË56D -Yq¡öQ¾RuÈz™XW•«y]>´kZÜßçÐj½â¡M>ñù„lá‰qÂ(þ€š>äb©f*ÝA2ÒÚ‘Ì DBŽ&©ï™òò5r¶úHãJüè¼÷Ë žüV_ì™±)u½Opóµ)õ÷(ÈRß@ÇHÄœ'*uÔû ¤6é °Ó¥2ÌŽq©M¡°0˜Ðc‰sŸÃ`E¼)4ðpo“;áUÓ|¾S¨Á«@øÇ¶RhÚ­}(Ɉ=tÅ´Þé{˱º¶®hÚëÝдÊÅÐÖ`‰8Ný›Ë³±L²ÜfÅÌäxo+Ø2Û‘õÈÎ?bW”ð) 3ÀšÈ/¼„!S²—Tµ±„”~ÊR žÆê{äÛë,è](‡¦ñ Ý`±½çþXYѦ)¥ßü¶WJ§¾ÑÊF²Qa¯5 ‰ÿtglª¾Ï¯ÍOeÔŸC$Ey;C¸ŠPÖ·ZÑrž<Š®CESñלõëZZV_Ü=ú ¾Áªˆ‰²6ƒüFòÖóT'1¥àp ÞÖ‹»†û7 ïfÁ·ÃgH¬Õ¼7è-ý¶YpÐ0&™à*ÓÐ0þ e:6½eœlñ-² ”V$ÐÂëûß0íæ(¡¸Ï#lXwÈüÒJq½†ØÈPbÑí¢?#IëL“·ÂÇ@Û¨#níÿ"ƒ¦D¤yF?{ÕPù”ø™ò0>úJ¥v¬›'¾þ•dròªnýeÿ;g7v„KYï+—ü1p/»Ì¡a¯Pz륈!’ å^„Í7ªG—ëå1xíÞŸ&²jÆwuK†$ŒÏè{Ù_Òap:éË~Yle•z)÷Íïl0}HEl¯æ[.—‹Ò-óo‡Jó‰èˆƒýÖs·ûrQáG·“2ZS_=#íøu•úÁ¼Í6ê<`÷ÎgÚäs:9ÖšL«ÉôôÑÁêîÐ.k -v­—ï´¤½%—ÞAœa+4¹š ˆR–ÌqYy€FÝPË÷àtÒNPûëtØàÒNfva1š"ÝÔÌ=Tf^{©¼SrœuÃÅ‚˜ýI¹öŠcKèûù˜¶Ô=Î~\ÛèXyDì¹Ϊ²9lE÷TDS1ç±F´F”ÏËUFäÄÏ[1rÖwïŠ.±<³1k†|ǸB#ò™ºótÇ~ÆçGŽì”²èÏÕ¯ ÷L zŒuº²|G}iqÄJ0Åzw¬TGÏöhžZ›ÀT -{Ñþë]8‡€«ûÞ÷ú¹‘»‡N+ JñtŸ„Ûãøv]2Ãþ2¡Þ¶E¬øg¿I:ºVñµ¹é´{ü2Û‡¢˜».MQâ6:´gÞX’Au¯kÊr”4ÎÈŠWìg£p?—ÚéU‘Öj5ReëE _ˆÈ7vû}s€ªÁ÷r€­3¿ós°½š$ µŽ—Ä5ÆÆêW¢.gy>»M´8”kj3‘¤ìÊó¯ÝJñ:&ŠÝuÍîe§­æ¡4³oVPl·f¨õ—ÉŒ‘µWzK…ZÜ©NbEIý,¬^ê -u¡K)* 'ýWJüèJž]Yù?Ù‹R~âQHŠgF`¶à -“b°?B÷_Íè˼™Üªï›ï6*n8·%9º(§ +M÷Áe„p`|_;dAÉã~Ë‘Õ~!cÀ`ò1⢹p2¶“É`x‘Nxs˜ÒYq)1_¡p¤¸uÏ6¦±âl9“!69û¬‰3ö¼®œZ»»ºN½Ê/†^·X›+H(¼?Þ=Ê Bh =ƒé¤j=Y¬bä\º¢øy ŽEgçz[´Ï¥"Þ¯óÛXÿó¾6\”a±hOáGê*M%Ô€'.éC×4wŒr›1yô¿7­Ùp¯zÏÂßnãÒ€)__÷Ød#pâ('úœ“ÂÎJô¦¢)Þ(aß –ºJ‘ º8*mˆžDPçôöÇrá÷X‡Àv‚rõPïíâòÍÔ9>}ÁßyÿËÂ)g®F"&i¯nõAî§_7?¼+J^uœKéÇÕ5Þ“!ÂDˆ -PxZ^æÖm»½1ìÐŽ?' {tÐÔ¢»h<ô4$’?¹Þ5‡KúþÈÈÍrÄåžËßgBMjaáŠþiZýlQ? § -ÈèÏÑ3œ)w' ÂIðmSíAp -þUÑ%i~ßáh®¼}Ò ôâ[OWc2snq[䩌hA_Új—3E¼Ö†¯—<—gêr:ÖK–JØU+™_±òì(èKò§˜Bà=}H¡}y‰/½§.wËxoé¾ȢNOŠÛY¡ÚrFË4OBH(•'‹þ/Žæ½mñðù¾è4êçyÿîWé Ž ÖäϦW“»¿âÉJ?mðP,MI3¶I€~“E¹õ¸_!_ÑÖ[jP–²Ê«ÝC <”ê4  #å®Ýôn©Ó̇åPZ¼»1Êjóž–øÝ‘x7O-b•5Õ³0§–7ý1\«šxße‚Ц"É+Ýs D¶@ÜÙ¡º |³5r·3ÕÐëÑ£0<îßr…‰Q{qÍZ£¼ÍæÜCµ™õäsY$,,!ÿs¹T.–Ìé§i×Û&›24jCÑ£ïi”ö;ëoµ ~ëÞÑdÅt>Á4á(ä2Àoq`Ý -Yd©ÊgrlV|LEÜËâ|YÏO_f¶1× Z|õúþUêÀÌŠÚ²õâÈñÐöV¯'ÞvÍ’ ¯‹¬Tîµ”äÌ´7¥å×DgªÛ'¿±Ovd~”awÅÎê¯>ò¡ßv¯ßi9¿€³fXˆ‹~MÌwS8·ÉHªlÅ\}|§?¿6‰›&ˆìgSïOüvÃý$•}G¹Or)‡ö#RS¶¦i•›IFu|Çw#èÏ dª”ÞB¤çï|8„KT ­K¸XHTœü>÷ãV—°½ƒ=4– :`è]i…Nþø> ’­â¸T˧™ä·å‚:ÞËþšo®ç3µ¿h_/7f´W4.Úéi’¾Œú{£¦Š3ò2û$üúáVü{ª6·ÛǤfj"k9,vIØ CÓ* ÄvºØ…é(¤r¹ú^½¢"j|½Ûí¬A Ê6ð®?æÌâƒMz¶3ï°` 4÷¹ÄEÊí &÷ìg£Ó#Tº÷©a¹ù¼S£ä}†0êL¤è$D^õËc@‘>?Ëí)ÞÏÄà‹HöÏ|)´#éfÑ«\l»¼ÓH9•1+Ý&³ÆyÖ6G×{»DÓe®y¥Tœ¨{‹#W(¦å1öa h ¹Àƒ`[ÕZlWa{V†É߸½MÈÖ¡‹EȬԧM -¨Fc<óì±%çÜàT(«ÈzMŠÅD£„F]YdÏÄÍàY˜’œo˜¾¹ºtˉo*Âq_ O7,žBØ}ª°CrL?¯ÍQ /Ï—¡ò…G‘ ß„Òé~7—<è”{‡¯ì½r·3)¬†*m¿, rÌ&f¸*f*99©Ëú˜—hÈ¥å”; º¶Áú†Ð³ápçyrs`ÖûJfN÷ëh‡Õ¦tVéJ&ˆ£¥!ÜÿDzhbD#UIΠ¥NÎe‚´€´sÐHO”u%Ix`WÑSá­¹Ò×Ô©Ký§—ЮxFãÉòb•<ìH÷”Ípü7éãõÖV¸Íþ2ì¥+÷õjþ(kÄÔòӯݳG‹Ý"ù–éžâfjÝ -6ËjgΡ0·#â[Ž9¨z ÌS‰!ìÝ~ÍN—B— CC´=b¹?`³È¯½;°Hçs§¢eÿŽýÕ'{'Žák|•9Ú}ËT!…jû­GÄâäá:…–{REé(œ0:ÈTÅ$þƒc¼æ}9)ÉÞÉAÄ›¾ð³Úpêo#‘xQ“^#’·’ØiÒ·gM®X„OØ8Ô Ñfì4åUytŸ‘<=ÃùÐÝK nÈ|7Ö—5^5™ûš˜Mg4$†ÍÈ -â‘%WÒª¾Ä§œu«˜&¹ÞÝë(Ñc.zª7† z„þͦˆnMa&?Sc€*ÚÞ ¬·Hú€¿Õ]ð•iu‚)6ˆ§}£)ºÖ3%D2½Æ7—Ÿ`¶éÍÝ·/¤qÏ{4É–âk sé}ãÄ2­%’µ’!ñêqœn•¦Z í©gÇüst‚áŠÏa+™“°î ظh†Œ!Ì6…ªç. –;ÝÏ1xƒÏSD@ÞM<‹ðu"b>”Œ·rä]•6ÓˆW8Ä6„Ž{ìý>èËbgE ÒZ< Ã÷U^úx©†k¸©>(Úðynñ‘…Ôô±?J z]üœkQû~\Ë PÏÚÝÔ×Äžž5u+΃m@«È˜Ø¼8©‰‚øã¼’Fݬ~ã|÷Ô­¦í´c ýBÒþxZ¤ŠÛ 8Î,õFZÚðl΄ÒH"*XÂá¦Éú§<ÿBò·‚•nnˆA™8™!… 0T“Éh·neZìr*vl_u)„–DÈøŽþKœB ~Íì«ãq "ïg^ÿs¢e^ÉíÑH7Ì›—£U€K¹`â:Ö 8è‰hLö14-ågÖÆªõ2L!F»ΛÙJžânÆæÎïXª_ž(±Ü\ŽÅí“H…L& ñLÒz©]ÓÐû3Õ´V -Ý‹¬ÚCB•ÆâzKld迲(Z8äTêi…æE^àh¦¨ñ’'à÷¬*Äî°¶by(±E@4¬zÚõWŽ‹t\c´§X]¸¼h,)(“yÒôóë­¡Vb¤Ÿ‚Zo»Üò³õ“#ÓëŒø5Ó,{`q2Å&OÍŽ¹}¶µòœU©$=‹¯¬~—Ëçe±2aáÔ¨i1êX„y‚3yš÷È›?8–åbUìðÆ—CµÅ¹Tæ-òr7ò ÷‡¤zOÊ~ÒÑwÞ¸ kÆ­ý>; ­†=•6\a'Õ TTÁÕìôRD;ÛiÇFzñâ¨U¡ÌþØcŽ»!wôV× ×:7:¤t-„ «³•±JÀ‚Ö7½:aÛKµ;³÷×:¹æêkWÎCnO“'ç,¯ÓÔ¤Îm¡Ia ;ÈÃÕÜR•m”¢–-œ?T†)DÙ¦ªyåkYÇ‘ZO Ë=Q`¡>+šÖ&8G£¾=ÉÔÄΫñ ŒsᵂÐ!ò\噟œ§>Ñn—D}a¼y‰²ÄR׃ ­JCf¨ÍV«*¯qø*PÎ9ÜùÑNõÌ.T»R‚ùŽÛD’#?ö -[>óµCPûÅ+Õ1Ä®1j~Öú‰7+Jh&Ú‘’ûíõU‚d>eµlš±“ÁâäÛ“ÙS=Ò* `pz90xXlø¤&” ¨îˆeÒ ÞsÜ$,põl‹·V7ãÝ~b8d¤_ý°üø¦‡@”ù-‘$ROÀ>4ÙCÎÔÎH - -ynÉRZ…MJ©AZŽ4žØzœ¬•-9ò—BI›&ÖÛZƒÙoYB­šó2R':ôWÞh\[r×ü|vr·šMœT}6^šCª¼‚Ñü~œ–J¿ÔúõSÚÜÆ!¦®ÔǤ­Ü`Â׃ú "{ê¹OW޹ |Ç2ï’\žj„{31…où»SÓvL)¼±Ôvü.³rÌ~Ïð£X¼©¤P.±¢ëÝ36Ö„¢)þ¬QÎhëx¾ñ‚C¦¶°N§ÿZÞF1žÁ¿H"âÎôúdmœš›@>ù†ö¶5\47Þà]¯³ÿ OQ9ÊNåð"Sw,‹ádqÈ…AŽ¡Æ(›_oAéÞš³BKãà¼zDîµI`Á¤…^ЧkØÉhXœ´gÆK C·˜Cd5÷^¯ÜIÙ$鬷 ¿üþö¬"s¨ äj•éø¸ Û5y‚·-h†[« | A]_¸vL®ÁNá¾1ŶzõþBLvúÈØ"²jlmí;/7Û/¿îÄ-¼“ç31§ ô­Øû ¥žÚ‡~¼5)ÉÏr¬/lKŠÀ³œ’-ßQ4!åÛë2Zßfµ'?÷þ<ƒ)ŠÏtòžôµÂÂǪIòÛ³ÃNLx£i(wáÝÉO«ßÊ”»÷Ù$–Ù‘"ΔU.~ŸÉK ¦÷ *kå+•S˜Ôý Y]%ôhÊ n‰H6ï@ʽ¶Žè¥ns²ó=©W_…+¡‡ª„‚Š—_®N¥n}±½ -9ø+^‰¶«B;Ûpí‰l¾ÊlX‘EgÞ•Ïà±&Þö/xGÓmËœ}[9¿„ûÿ3ÕV -endstream -endobj -1837 0 obj << -/Type /FontDescriptor -/FontName /HLONQR+CMTT10 -/Flags 4 -/FontBBox [-4 -235 731 800] -/Ascent 611 -/CapHeight 611 -/Descent -222 -/ItalicAngle 0 -/StemV 69 -/XHeight 431 -/CharSet (/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/ampersand/asciicircum/asterisk/at/b/backslash/bar/braceleft/braceright/bracketleft/bracketright/c/colon/comma/d/dollar/e/eight/equal/exclam/f/five/four/g/greater/h/hyphen/i/j/k/l/less/m/n/nine/o/one/p/parenleft/parenright/period/plus/q/question/quotedbl/quoteleft/quoteright/r/s/semicolon/seven/six/slash/t/three/two/u/underscore/v/w/x/y/z/zero) -/FontFile 1836 0 R ->> endobj -879 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /IDSUQC+CMBX10 -/FontDescriptor 1821 0 R -/FirstChar 11 -/LastChar 122 -/Widths 1814 0 R ->> endobj -823 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /EQHLLW+CMBX12 -/FontDescriptor 1823 0 R -/FirstChar 11 -/LastChar 123 -/Widths 1819 0 R ->> endobj -833 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /SYFPBV+CMMI10 -/FontDescriptor 1825 0 R -/FirstChar 60 -/LastChar 62 -/Widths 1815 0 R ->> endobj -826 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /XXGKWP+CMR10 -/FontDescriptor 1827 0 R -/FirstChar 11 -/LastChar 123 -/Widths 1816 0 R ->> endobj -824 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /FKYWYP+CMR12 -/FontDescriptor 1829 0 R -/FirstChar 14 -/LastChar 121 -/Widths 1818 0 R ->> endobj -1136 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /PRMIXO+CMR17 -/FontDescriptor 1831 0 R -/FirstChar 65 -/LastChar 87 -/Widths 1811 0 R ->> endobj -1089 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /LKZNMG+CMR7 -/FontDescriptor 1833 0 R -/FirstChar 77 -/LastChar 84 -/Widths 1813 0 R ->> endobj -825 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /XEVZSX+CMSY10 -/FontDescriptor 1835 0 R -/FirstChar 0 -/LastChar 33 -/Widths 1817 0 R ->> endobj -1094 0 obj << -/Type /Font -/Subtype /Type1 -/BaseFont /HLONQR+CMTT10 -/FontDescriptor 1837 0 R -/FirstChar 33 -/LastChar 125 -/Widths 1812 0 R ->> endobj -827 0 obj << -/Type /Pages -/Count 6 -/Parent 1838 0 R -/Kids [818 0 R 830 0 R 835 0 R 839 0 R 875 0 R 914 0 R] ->> endobj -953 0 obj << -/Type /Pages -/Count 6 -/Parent 1838 0 R -/Kids [950 0 R 988 0 R 1025 0 R 1060 0 R 1073 0 R 1077 0 R] ->> endobj -1084 0 obj << -/Type /Pages -/Count 6 -/Parent 1838 0 R -/Kids [1081 0 R 1086 0 R 1091 0 R 1096 0 R 1101 0 R 1105 0 R] ->> endobj -1115 0 obj << -/Type /Pages -/Count 6 -/Parent 1838 0 R -/Kids [1112 0 R 1118 0 R 1133 0 R 1140 0 R 1144 0 R 1149 0 R] ->> endobj -1161 0 obj << -/Type /Pages -/Count 6 -/Parent 1838 0 R -/Kids [1158 0 R 1165 0 R 1169 0 R 1186 0 R 1190 0 R 1195 0 R] ->> endobj -1203 0 obj << -/Type /Pages -/Count 6 -/Parent 1838 0 R -/Kids [1200 0 R 1206 0 R 1212 0 R 1218 0 R 1223 0 R 1232 0 R] ->> endobj -1241 0 obj << -/Type /Pages -/Count 6 -/Parent 1839 0 R -/Kids [1238 0 R 1247 0 R 1253 0 R 1257 0 R 1262 0 R 1266 0 R] ->> endobj -1273 0 obj << -/Type /Pages -/Count 6 -/Parent 1839 0 R -/Kids [1270 0 R 1277 0 R 1284 0 R 1292 0 R 1300 0 R 1308 0 R] ->> endobj -1318 0 obj << -/Type /Pages -/Count 6 -/Parent 1839 0 R -/Kids [1315 0 R 1321 0 R 1326 0 R 1333 0 R 1337 0 R 1343 0 R] ->> endobj -1353 0 obj << -/Type /Pages -/Count 6 -/Parent 1839 0 R -/Kids [1347 0 R 1355 0 R 1367 0 R 1371 0 R 1375 0 R 1380 0 R] ->> endobj -1387 0 obj << -/Type /Pages -/Count 6 -/Parent 1839 0 R -/Kids [1384 0 R 1389 0 R 1393 0 R 1399 0 R 1403 0 R 1407 0 R] ->> endobj -1416 0 obj << -/Type /Pages -/Count 6 -/Parent 1839 0 R -/Kids [1413 0 R 1420 0 R 1424 0 R 1428 0 R 1434 0 R 1438 0 R] ->> endobj -1445 0 obj << -/Type /Pages -/Count 6 -/Parent 1840 0 R -/Kids [1442 0 R 1447 0 R 1451 0 R 1455 0 R 1459 0 R 1463 0 R] ->> endobj -1473 0 obj << -/Type /Pages -/Count 6 -/Parent 1840 0 R -/Kids [1467 0 R 1477 0 R 1481 0 R 1485 0 R 1490 0 R 1494 0 R] ->> endobj -1503 0 obj << -/Type /Pages -/Count 6 -/Parent 1840 0 R -/Kids [1500 0 R 1505 0 R 1509 0 R 1516 0 R 1521 0 R 1525 0 R] ->> endobj -1534 0 obj << -/Type /Pages -/Count 6 -/Parent 1840 0 R -/Kids [1531 0 R 1536 0 R 1542 0 R 1547 0 R 1552 0 R 1557 0 R] ->> endobj -1564 0 obj << -/Type /Pages -/Count 6 -/Parent 1840 0 R -/Kids [1561 0 R 1566 0 R 1570 0 R 1577 0 R 1581 0 R 1585 0 R] ->> endobj -1592 0 obj << -/Type /Pages -/Count 6 -/Parent 1840 0 R -/Kids [1589 0 R 1594 0 R 1598 0 R 1602 0 R 1606 0 R 1610 0 R] ->> endobj -1617 0 obj << -/Type /Pages -/Count 6 -/Parent 1841 0 R -/Kids [1614 0 R 1619 0 R 1623 0 R 1627 0 R 1631 0 R 1635 0 R] ->> endobj -1654 0 obj << -/Type /Pages -/Count 5 -/Parent 1841 0 R -/Kids [1639 0 R 1656 0 R 1672 0 R 1690 0 R 1800 0 R] ->> endobj -1838 0 obj << -/Type /Pages -/Count 36 -/Parent 1842 0 R -/Kids [827 0 R 953 0 R 1084 0 R 1115 0 R 1161 0 R 1203 0 R] ->> endobj -1839 0 obj << -/Type /Pages -/Count 36 -/Parent 1842 0 R -/Kids [1241 0 R 1273 0 R 1318 0 R 1353 0 R 1387 0 R 1416 0 R] ->> endobj -1840 0 obj << -/Type /Pages -/Count 36 -/Parent 1842 0 R -/Kids [1445 0 R 1473 0 R 1503 0 R 1534 0 R 1564 0 R 1592 0 R] ->> endobj -1841 0 obj << -/Type /Pages -/Count 11 -/Parent 1842 0 R -/Kids [1617 0 R 1654 0 R] ->> endobj -1842 0 obj << -/Type /Pages -/Count 119 -/Kids [1838 0 R 1839 0 R 1840 0 R 1841 0 R] ->> endobj -1843 0 obj << -/Type /Outlines -/First 7 0 R -/Last 815 0 R -/Count 10 ->> endobj -815 0 obj << -/Title 816 0 R -/A 813 0 R -/Parent 1843 0 R -/Prev 779 0 R ->> endobj -811 0 obj << -/Title 812 0 R -/A 809 0 R -/Parent 787 0 R -/Prev 807 0 R ->> endobj -807 0 obj << -/Title 808 0 R -/A 805 0 R -/Parent 787 0 R -/Prev 803 0 R -/Next 811 0 R ->> endobj -803 0 obj << -/Title 804 0 R -/A 801 0 R -/Parent 787 0 R -/Prev 799 0 R -/Next 807 0 R ->> endobj -799 0 obj << -/Title 800 0 R -/A 797 0 R -/Parent 787 0 R -/Prev 795 0 R -/Next 803 0 R ->> endobj -795 0 obj << -/Title 796 0 R -/A 793 0 R -/Parent 787 0 R -/Prev 791 0 R -/Next 799 0 R ->> endobj -791 0 obj << -/Title 792 0 R -/A 789 0 R -/Parent 787 0 R -/Next 795 0 R ->> endobj -787 0 obj << -/Title 788 0 R -/A 785 0 R -/Parent 779 0 R -/Prev 783 0 R -/First 791 0 R -/Last 811 0 R -/Count -6 ->> endobj -783 0 obj << -/Title 784 0 R -/A 781 0 R -/Parent 779 0 R -/Next 787 0 R ->> endobj -779 0 obj << -/Title 780 0 R -/A 777 0 R -/Parent 1843 0 R -/Prev 775 0 R -/Next 815 0 R -/First 783 0 R -/Last 787 0 R -/Count -2 ->> endobj -775 0 obj << -/Title 776 0 R -/A 773 0 R -/Parent 1843 0 R -/Prev 771 0 R -/Next 779 0 R ->> endobj -771 0 obj << -/Title 772 0 R -/A 769 0 R -/Parent 1843 0 R -/Prev 767 0 R -/Next 775 0 R ->> endobj -767 0 obj << -/Title 768 0 R -/A 765 0 R -/Parent 1843 0 R -/Prev 759 0 R -/Next 771 0 R ->> endobj -763 0 obj << -/Title 764 0 R -/A 761 0 R -/Parent 759 0 R ->> endobj -759 0 obj << -/Title 760 0 R -/A 757 0 R -/Parent 1843 0 R -/Prev 275 0 R -/Next 767 0 R -/First 763 0 R -/Last 763 0 R -/Count -1 ->> endobj -755 0 obj << -/Title 756 0 R -/A 753 0 R -/Parent 719 0 R -/Prev 751 0 R ->> endobj -751 0 obj << -/Title 752 0 R -/A 749 0 R -/Parent 719 0 R -/Prev 747 0 R -/Next 755 0 R ->> endobj -747 0 obj << -/Title 748 0 R -/A 745 0 R -/Parent 719 0 R -/Prev 743 0 R -/Next 751 0 R ->> endobj -743 0 obj << -/Title 744 0 R -/A 741 0 R -/Parent 719 0 R -/Prev 739 0 R -/Next 747 0 R ->> endobj -739 0 obj << -/Title 740 0 R -/A 737 0 R -/Parent 719 0 R -/Prev 735 0 R -/Next 743 0 R ->> endobj -735 0 obj << -/Title 736 0 R -/A 733 0 R -/Parent 719 0 R -/Prev 731 0 R -/Next 739 0 R ->> endobj -731 0 obj << -/Title 732 0 R -/A 729 0 R -/Parent 719 0 R -/Prev 727 0 R -/Next 735 0 R ->> endobj -727 0 obj << -/Title 728 0 R -/A 725 0 R -/Parent 719 0 R -/Prev 723 0 R -/Next 731 0 R ->> endobj -723 0 obj << -/Title 724 0 R -/A 721 0 R -/Parent 719 0 R -/Next 727 0 R ->> endobj -719 0 obj << -/Title 720 0 R -/A 717 0 R -/Parent 711 0 R -/Prev 715 0 R -/First 723 0 R -/Last 755 0 R -/Count -9 ->> endobj -715 0 obj << -/Title 716 0 R -/A 713 0 R -/Parent 711 0 R -/Next 719 0 R ->> endobj -711 0 obj << -/Title 712 0 R -/A 709 0 R -/Parent 275 0 R -/Prev 635 0 R -/First 715 0 R -/Last 719 0 R -/Count -2 ->> endobj -707 0 obj << -/Title 708 0 R -/A 705 0 R -/Parent 635 0 R -/Prev 647 0 R ->> endobj -703 0 obj << -/Title 704 0 R -/A 701 0 R -/Parent 647 0 R -/Prev 699 0 R ->> endobj -699 0 obj << -/Title 700 0 R -/A 697 0 R -/Parent 647 0 R -/Prev 695 0 R -/Next 703 0 R ->> endobj -695 0 obj << -/Title 696 0 R -/A 693 0 R -/Parent 647 0 R -/Prev 691 0 R -/Next 699 0 R ->> endobj -691 0 obj << -/Title 692 0 R -/A 689 0 R -/Parent 647 0 R -/Prev 687 0 R -/Next 695 0 R ->> endobj -687 0 obj << -/Title 688 0 R -/A 685 0 R -/Parent 647 0 R -/Prev 683 0 R -/Next 691 0 R ->> endobj -683 0 obj << -/Title 684 0 R -/A 681 0 R -/Parent 647 0 R -/Prev 679 0 R -/Next 687 0 R ->> endobj -679 0 obj << -/Title 680 0 R -/A 677 0 R -/Parent 647 0 R -/Prev 675 0 R -/Next 683 0 R ->> endobj -675 0 obj << -/Title 676 0 R -/A 673 0 R -/Parent 647 0 R -/Prev 671 0 R -/Next 679 0 R ->> endobj -671 0 obj << -/Title 672 0 R -/A 669 0 R -/Parent 647 0 R -/Prev 667 0 R -/Next 675 0 R ->> endobj -667 0 obj << -/Title 668 0 R -/A 665 0 R -/Parent 647 0 R -/Prev 663 0 R -/Next 671 0 R ->> endobj -663 0 obj << -/Title 664 0 R -/A 661 0 R -/Parent 647 0 R -/Prev 659 0 R -/Next 667 0 R ->> endobj -659 0 obj << -/Title 660 0 R -/A 657 0 R -/Parent 647 0 R -/Prev 655 0 R -/Next 663 0 R ->> endobj -655 0 obj << -/Title 656 0 R -/A 653 0 R -/Parent 647 0 R -/Prev 651 0 R -/Next 659 0 R ->> endobj -651 0 obj << -/Title 652 0 R -/A 649 0 R -/Parent 647 0 R -/Next 655 0 R ->> endobj -647 0 obj << -/Title 648 0 R -/A 645 0 R -/Parent 635 0 R -/Prev 643 0 R -/Next 707 0 R -/First 651 0 R -/Last 703 0 R -/Count -14 ->> endobj -643 0 obj << -/Title 644 0 R -/A 641 0 R -/Parent 635 0 R -/Prev 639 0 R -/Next 647 0 R ->> endobj -639 0 obj << -/Title 640 0 R -/A 637 0 R -/Parent 635 0 R -/Next 643 0 R ->> endobj -635 0 obj << -/Title 636 0 R -/A 633 0 R -/Parent 275 0 R -/Prev 615 0 R -/Next 711 0 R -/First 639 0 R -/Last 707 0 R -/Count -4 ->> endobj -631 0 obj << -/Title 632 0 R -/A 629 0 R -/Parent 615 0 R -/Prev 619 0 R ->> endobj -627 0 obj << -/Title 628 0 R -/A 625 0 R -/Parent 619 0 R -/Prev 623 0 R ->> endobj -623 0 obj << -/Title 624 0 R -/A 621 0 R -/Parent 619 0 R -/Next 627 0 R ->> endobj -619 0 obj << -/Title 620 0 R -/A 617 0 R -/Parent 615 0 R -/Next 631 0 R -/First 623 0 R -/Last 627 0 R -/Count -2 ->> endobj -615 0 obj << -/Title 616 0 R -/A 613 0 R -/Parent 275 0 R -/Prev 595 0 R -/Next 635 0 R -/First 619 0 R -/Last 631 0 R -/Count -2 ->> endobj -611 0 obj << -/Title 612 0 R -/A 609 0 R -/Parent 599 0 R -/Prev 607 0 R ->> endobj -607 0 obj << -/Title 608 0 R -/A 605 0 R -/Parent 599 0 R -/Prev 603 0 R -/Next 611 0 R ->> endobj -603 0 obj << -/Title 604 0 R -/A 601 0 R -/Parent 599 0 R -/Next 607 0 R ->> endobj -599 0 obj << -/Title 600 0 R -/A 597 0 R -/Parent 595 0 R -/First 603 0 R -/Last 611 0 R -/Count -3 ->> endobj -595 0 obj << -/Title 596 0 R -/A 593 0 R -/Parent 275 0 R -/Prev 575 0 R -/Next 615 0 R -/First 599 0 R -/Last 599 0 R -/Count -1 ->> endobj -591 0 obj << -/Title 592 0 R -/A 589 0 R -/Parent 575 0 R -/Prev 579 0 R ->> endobj -587 0 obj << -/Title 588 0 R -/A 585 0 R -/Parent 579 0 R -/Prev 583 0 R ->> endobj -583 0 obj << -/Title 584 0 R -/A 581 0 R -/Parent 579 0 R -/Next 587 0 R ->> endobj -579 0 obj << -/Title 580 0 R -/A 577 0 R -/Parent 575 0 R -/Next 591 0 R -/First 583 0 R -/Last 587 0 R -/Count -2 ->> endobj -575 0 obj << -/Title 576 0 R -/A 573 0 R -/Parent 275 0 R -/Prev 563 0 R -/Next 595 0 R -/First 579 0 R -/Last 591 0 R -/Count -2 ->> endobj -571 0 obj << -/Title 572 0 R -/A 569 0 R -/Parent 563 0 R -/Prev 567 0 R ->> endobj -567 0 obj << -/Title 568 0 R -/A 565 0 R -/Parent 563 0 R -/Next 571 0 R ->> endobj -563 0 obj << -/Title 564 0 R -/A 561 0 R -/Parent 275 0 R -/Prev 559 0 R -/Next 575 0 R -/First 567 0 R -/Last 571 0 R -/Count -2 ->> endobj -559 0 obj << -/Title 560 0 R -/A 557 0 R -/Parent 275 0 R -/Prev 467 0 R -/Next 563 0 R ->> endobj -555 0 obj << -/Title 556 0 R -/A 553 0 R -/Parent 467 0 R -/Prev 531 0 R ->> endobj -551 0 obj << -/Title 552 0 R -/A 549 0 R -/Parent 531 0 R -/Prev 547 0 R ->> endobj -547 0 obj << -/Title 548 0 R -/A 545 0 R -/Parent 531 0 R -/Prev 543 0 R -/Next 551 0 R ->> endobj -543 0 obj << -/Title 544 0 R -/A 541 0 R -/Parent 531 0 R -/Prev 539 0 R -/Next 547 0 R ->> endobj -539 0 obj << -/Title 540 0 R -/A 537 0 R -/Parent 531 0 R -/Prev 535 0 R -/Next 543 0 R ->> endobj -535 0 obj << -/Title 536 0 R -/A 533 0 R -/Parent 531 0 R -/Next 539 0 R ->> endobj -531 0 obj << -/Title 532 0 R -/A 529 0 R -/Parent 467 0 R -/Prev 471 0 R -/Next 555 0 R -/First 535 0 R -/Last 551 0 R -/Count -5 ->> endobj -527 0 obj << -/Title 528 0 R -/A 525 0 R -/Parent 471 0 R -/Prev 511 0 R ->> endobj -523 0 obj << -/Title 524 0 R -/A 521 0 R -/Parent 511 0 R -/Prev 519 0 R ->> endobj -519 0 obj << -/Title 520 0 R -/A 517 0 R -/Parent 511 0 R -/Prev 515 0 R -/Next 523 0 R ->> endobj -515 0 obj << -/Title 516 0 R -/A 513 0 R -/Parent 511 0 R -/Next 519 0 R ->> endobj -511 0 obj << -/Title 512 0 R -/A 509 0 R -/Parent 471 0 R -/Prev 483 0 R -/Next 527 0 R -/First 515 0 R -/Last 523 0 R -/Count -3 ->> endobj -507 0 obj << -/Title 508 0 R -/A 505 0 R -/Parent 483 0 R -/Prev 503 0 R ->> endobj -503 0 obj << -/Title 504 0 R -/A 501 0 R -/Parent 483 0 R -/Prev 499 0 R -/Next 507 0 R ->> endobj -499 0 obj << -/Title 500 0 R -/A 497 0 R -/Parent 483 0 R -/Prev 495 0 R -/Next 503 0 R ->> endobj -495 0 obj << -/Title 496 0 R -/A 493 0 R -/Parent 483 0 R -/Prev 491 0 R -/Next 499 0 R ->> endobj -491 0 obj << -/Title 492 0 R -/A 489 0 R -/Parent 483 0 R -/Prev 487 0 R -/Next 495 0 R ->> endobj -487 0 obj << -/Title 488 0 R -/A 485 0 R -/Parent 483 0 R -/Next 491 0 R ->> endobj -483 0 obj << -/Title 484 0 R -/A 481 0 R -/Parent 471 0 R -/Prev 479 0 R -/Next 511 0 R -/First 487 0 R -/Last 507 0 R -/Count -6 ->> endobj -479 0 obj << -/Title 480 0 R -/A 477 0 R -/Parent 471 0 R -/Prev 475 0 R -/Next 483 0 R ->> endobj -475 0 obj << -/Title 476 0 R -/A 473 0 R -/Parent 471 0 R -/Next 479 0 R ->> endobj -471 0 obj << -/Title 472 0 R -/A 469 0 R -/Parent 467 0 R -/Next 531 0 R -/First 475 0 R -/Last 527 0 R -/Count -5 ->> endobj -467 0 obj << -/Title 468 0 R -/A 465 0 R -/Parent 275 0 R -/Prev 439 0 R -/Next 559 0 R -/First 471 0 R -/Last 555 0 R -/Count -3 ->> endobj -463 0 obj << -/Title 464 0 R -/A 461 0 R -/Parent 439 0 R -/Prev 443 0 R ->> endobj -459 0 obj << -/Title 460 0 R -/A 457 0 R -/Parent 443 0 R -/Prev 455 0 R ->> endobj -455 0 obj << -/Title 456 0 R -/A 453 0 R -/Parent 443 0 R -/Prev 451 0 R -/Next 459 0 R ->> endobj -451 0 obj << -/Title 452 0 R -/A 449 0 R -/Parent 443 0 R -/Prev 447 0 R -/Next 455 0 R ->> endobj -447 0 obj << -/Title 448 0 R -/A 445 0 R -/Parent 443 0 R -/Next 451 0 R ->> endobj -443 0 obj << -/Title 444 0 R -/A 441 0 R -/Parent 439 0 R -/Next 463 0 R -/First 447 0 R -/Last 459 0 R -/Count -4 ->> endobj -439 0 obj << -/Title 440 0 R -/A 437 0 R -/Parent 275 0 R -/Prev 327 0 R -/Next 467 0 R -/First 443 0 R -/Last 463 0 R -/Count -2 ->> endobj -435 0 obj << -/Title 436 0 R -/A 433 0 R -/Parent 423 0 R -/Prev 431 0 R ->> endobj -431 0 obj << -/Title 432 0 R -/A 429 0 R -/Parent 423 0 R -/Prev 427 0 R -/Next 435 0 R ->> endobj -427 0 obj << -/Title 428 0 R -/A 425 0 R -/Parent 423 0 R -/Next 431 0 R ->> endobj -423 0 obj << -/Title 424 0 R -/A 421 0 R -/Parent 327 0 R -/Prev 411 0 R -/First 427 0 R -/Last 435 0 R -/Count -3 ->> endobj -419 0 obj << -/Title 420 0 R -/A 417 0 R -/Parent 411 0 R -/Prev 415 0 R ->> endobj -415 0 obj << -/Title 416 0 R -/A 413 0 R -/Parent 411 0 R -/Next 419 0 R ->> endobj -411 0 obj << -/Title 412 0 R -/A 409 0 R -/Parent 327 0 R -/Prev 383 0 R -/Next 423 0 R -/First 415 0 R -/Last 419 0 R -/Count -2 ->> endobj -407 0 obj << -/Title 408 0 R -/A 405 0 R -/Parent 383 0 R -/Prev 403 0 R ->> endobj -403 0 obj << -/Title 404 0 R -/A 401 0 R -/Parent 383 0 R -/Prev 399 0 R -/Next 407 0 R ->> endobj -399 0 obj << -/Title 400 0 R -/A 397 0 R -/Parent 383 0 R -/Prev 395 0 R -/Next 403 0 R ->> endobj -395 0 obj << -/Title 396 0 R -/A 393 0 R -/Parent 383 0 R -/Prev 391 0 R -/Next 399 0 R ->> endobj -391 0 obj << -/Title 392 0 R -/A 389 0 R -/Parent 383 0 R -/Prev 387 0 R -/Next 395 0 R ->> endobj -387 0 obj << -/Title 388 0 R -/A 385 0 R -/Parent 383 0 R -/Next 391 0 R ->> endobj -383 0 obj << -/Title 384 0 R -/A 381 0 R -/Parent 327 0 R -/Prev 359 0 R -/Next 411 0 R -/First 387 0 R -/Last 407 0 R -/Count -6 ->> endobj -379 0 obj << -/Title 380 0 R -/A 377 0 R -/Parent 359 0 R -/Prev 375 0 R ->> endobj -375 0 obj << -/Title 376 0 R -/A 373 0 R -/Parent 359 0 R -/Prev 371 0 R -/Next 379 0 R ->> endobj -371 0 obj << -/Title 372 0 R -/A 369 0 R -/Parent 359 0 R -/Prev 367 0 R -/Next 375 0 R ->> endobj -367 0 obj << -/Title 368 0 R -/A 365 0 R -/Parent 359 0 R -/Prev 363 0 R -/Next 371 0 R ->> endobj -363 0 obj << -/Title 364 0 R -/A 361 0 R -/Parent 359 0 R -/Next 367 0 R ->> endobj -359 0 obj << -/Title 360 0 R -/A 357 0 R -/Parent 327 0 R -/Prev 351 0 R -/Next 383 0 R -/First 363 0 R -/Last 379 0 R -/Count -5 ->> endobj -355 0 obj << -/Title 356 0 R -/A 353 0 R -/Parent 351 0 R ->> endobj -351 0 obj << -/Title 352 0 R -/A 349 0 R -/Parent 327 0 R -/Prev 331 0 R -/Next 359 0 R -/First 355 0 R -/Last 355 0 R -/Count -1 ->> endobj -347 0 obj << -/Title 348 0 R -/A 345 0 R -/Parent 331 0 R -/Prev 343 0 R ->> endobj -343 0 obj << -/Title 344 0 R -/A 341 0 R -/Parent 331 0 R -/Prev 339 0 R -/Next 347 0 R ->> endobj -339 0 obj << -/Title 340 0 R -/A 337 0 R -/Parent 331 0 R -/Prev 335 0 R -/Next 343 0 R ->> endobj -335 0 obj << -/Title 336 0 R -/A 333 0 R -/Parent 331 0 R -/Next 339 0 R ->> endobj -331 0 obj << -/Title 332 0 R -/A 329 0 R -/Parent 327 0 R -/Next 351 0 R -/First 335 0 R -/Last 347 0 R -/Count -4 ->> endobj -327 0 obj << -/Title 328 0 R -/A 325 0 R -/Parent 275 0 R -/Prev 279 0 R -/Next 439 0 R -/First 331 0 R -/Last 423 0 R -/Count -6 ->> endobj -323 0 obj << -/Title 324 0 R -/A 321 0 R -/Parent 287 0 R -/Prev 319 0 R ->> endobj -319 0 obj << -/Title 320 0 R -/A 317 0 R -/Parent 287 0 R -/Prev 315 0 R -/Next 323 0 R ->> endobj -315 0 obj << -/Title 316 0 R -/A 313 0 R -/Parent 287 0 R -/Prev 311 0 R -/Next 319 0 R ->> endobj -311 0 obj << -/Title 312 0 R -/A 309 0 R -/Parent 287 0 R -/Prev 307 0 R -/Next 315 0 R ->> endobj -307 0 obj << -/Title 308 0 R -/A 305 0 R -/Parent 287 0 R -/Prev 303 0 R -/Next 311 0 R ->> endobj -303 0 obj << -/Title 304 0 R -/A 301 0 R -/Parent 287 0 R -/Prev 299 0 R -/Next 307 0 R ->> endobj -299 0 obj << -/Title 300 0 R -/A 297 0 R -/Parent 287 0 R -/Prev 295 0 R -/Next 303 0 R ->> endobj -295 0 obj << -/Title 296 0 R -/A 293 0 R -/Parent 287 0 R -/Prev 291 0 R -/Next 299 0 R ->> endobj -291 0 obj << -/Title 292 0 R -/A 289 0 R -/Parent 287 0 R -/Next 295 0 R ->> endobj -287 0 obj << -/Title 288 0 R -/A 285 0 R -/Parent 279 0 R -/Prev 283 0 R -/First 291 0 R -/Last 323 0 R -/Count -9 ->> endobj -283 0 obj << -/Title 284 0 R -/A 281 0 R -/Parent 279 0 R -/Next 287 0 R ->> endobj -279 0 obj << -/Title 280 0 R -/A 277 0 R -/Parent 275 0 R -/Next 327 0 R -/First 283 0 R -/Last 287 0 R -/Count -2 ->> endobj -275 0 obj << -/Title 276 0 R -/A 273 0 R -/Parent 1843 0 R -/Prev 131 0 R -/Next 759 0 R -/First 279 0 R -/Last 711 0 R -/Count -11 ->> endobj -271 0 obj << -/Title 272 0 R -/A 269 0 R -/Parent 263 0 R -/Prev 267 0 R ->> endobj -267 0 obj << -/Title 268 0 R -/A 265 0 R -/Parent 263 0 R -/Next 271 0 R ->> endobj -263 0 obj << -/Title 264 0 R -/A 261 0 R -/Parent 223 0 R -/Prev 243 0 R -/First 267 0 R -/Last 271 0 R -/Count -2 ->> endobj -259 0 obj << -/Title 260 0 R -/A 257 0 R -/Parent 243 0 R -/Prev 255 0 R ->> endobj -255 0 obj << -/Title 256 0 R -/A 253 0 R -/Parent 243 0 R -/Prev 251 0 R -/Next 259 0 R ->> endobj -251 0 obj << -/Title 252 0 R -/A 249 0 R -/Parent 243 0 R -/Prev 247 0 R -/Next 255 0 R ->> endobj -247 0 obj << -/Title 248 0 R -/A 245 0 R -/Parent 243 0 R -/Next 251 0 R ->> endobj -243 0 obj << -/Title 244 0 R -/A 241 0 R -/Parent 223 0 R -/Prev 239 0 R -/Next 263 0 R -/First 247 0 R -/Last 259 0 R -/Count -4 ->> endobj -239 0 obj << -/Title 240 0 R -/A 237 0 R -/Parent 223 0 R -/Prev 227 0 R -/Next 243 0 R ->> endobj -235 0 obj << -/Title 236 0 R -/A 233 0 R -/Parent 227 0 R -/Prev 231 0 R ->> endobj -231 0 obj << -/Title 232 0 R -/A 229 0 R -/Parent 227 0 R -/Next 235 0 R ->> endobj -227 0 obj << -/Title 228 0 R -/A 225 0 R -/Parent 223 0 R -/Next 239 0 R -/First 231 0 R -/Last 235 0 R -/Count -2 ->> endobj -223 0 obj << -/Title 224 0 R -/A 221 0 R -/Parent 131 0 R -/Prev 211 0 R -/First 227 0 R -/Last 263 0 R -/Count -4 ->> endobj -219 0 obj << -/Title 220 0 R -/A 217 0 R -/Parent 211 0 R -/Prev 215 0 R ->> endobj -215 0 obj << -/Title 216 0 R -/A 213 0 R -/Parent 211 0 R -/Next 219 0 R ->> endobj -211 0 obj << -/Title 212 0 R -/A 209 0 R -/Parent 131 0 R -/Prev 167 0 R -/Next 223 0 R -/First 215 0 R -/Last 219 0 R -/Count -2 ->> endobj -207 0 obj << -/Title 208 0 R -/A 205 0 R -/Parent 195 0 R -/Prev 203 0 R ->> endobj -203 0 obj << -/Title 204 0 R -/A 201 0 R -/Parent 195 0 R -/Prev 199 0 R -/Next 207 0 R ->> endobj -199 0 obj << -/Title 200 0 R -/A 197 0 R -/Parent 195 0 R -/Next 203 0 R ->> endobj -195 0 obj << -/Title 196 0 R -/A 193 0 R -/Parent 167 0 R -/Prev 183 0 R -/First 199 0 R -/Last 207 0 R -/Count -3 ->> endobj -191 0 obj << -/Title 192 0 R -/A 189 0 R -/Parent 183 0 R -/Prev 187 0 R ->> endobj -187 0 obj << -/Title 188 0 R -/A 185 0 R -/Parent 183 0 R -/Next 191 0 R ->> endobj -183 0 obj << -/Title 184 0 R -/A 181 0 R -/Parent 167 0 R -/Prev 179 0 R -/Next 195 0 R -/First 187 0 R -/Last 191 0 R -/Count -2 ->> endobj -179 0 obj << -/Title 180 0 R -/A 177 0 R -/Parent 167 0 R -/Prev 175 0 R -/Next 183 0 R ->> endobj -175 0 obj << -/Title 176 0 R -/A 173 0 R -/Parent 167 0 R -/Prev 171 0 R -/Next 179 0 R ->> endobj -171 0 obj << -/Title 172 0 R -/A 169 0 R -/Parent 167 0 R -/Next 175 0 R ->> endobj -167 0 obj << -/Title 168 0 R -/A 165 0 R -/Parent 131 0 R -/Prev 135 0 R -/Next 211 0 R -/First 171 0 R -/Last 195 0 R -/Count -5 ->> endobj -163 0 obj << -/Title 164 0 R -/A 161 0 R -/Parent 135 0 R -/Prev 159 0 R ->> endobj -159 0 obj << -/Title 160 0 R -/A 157 0 R -/Parent 135 0 R -/Prev 155 0 R -/Next 163 0 R ->> endobj -155 0 obj << -/Title 156 0 R -/A 153 0 R -/Parent 135 0 R -/Prev 139 0 R -/Next 159 0 R ->> endobj -151 0 obj << -/Title 152 0 R -/A 149 0 R -/Parent 139 0 R -/Prev 147 0 R ->> endobj -147 0 obj << -/Title 148 0 R -/A 145 0 R -/Parent 139 0 R -/Prev 143 0 R -/Next 151 0 R ->> endobj -143 0 obj << -/Title 144 0 R -/A 141 0 R -/Parent 139 0 R -/Next 147 0 R ->> endobj -139 0 obj << -/Title 140 0 R -/A 137 0 R -/Parent 135 0 R -/Next 155 0 R -/First 143 0 R -/Last 151 0 R -/Count -3 ->> endobj -135 0 obj << -/Title 136 0 R -/A 133 0 R -/Parent 131 0 R -/Next 167 0 R -/First 139 0 R -/Last 163 0 R -/Count -4 ->> endobj -131 0 obj << -/Title 132 0 R -/A 129 0 R -/Parent 1843 0 R -/Prev 47 0 R -/Next 275 0 R -/First 135 0 R -/Last 223 0 R -/Count -4 ->> endobj -127 0 obj << -/Title 128 0 R -/A 125 0 R -/Parent 47 0 R -/Prev 123 0 R ->> endobj -123 0 obj << -/Title 124 0 R -/A 121 0 R -/Parent 47 0 R -/Prev 119 0 R -/Next 127 0 R ->> endobj -119 0 obj << -/Title 120 0 R -/A 117 0 R -/Parent 47 0 R -/Prev 115 0 R -/Next 123 0 R ->> endobj -115 0 obj << -/Title 116 0 R -/A 113 0 R -/Parent 47 0 R -/Prev 111 0 R -/Next 119 0 R ->> endobj -111 0 obj << -/Title 112 0 R -/A 109 0 R -/Parent 47 0 R -/Prev 107 0 R -/Next 115 0 R ->> endobj -107 0 obj << -/Title 108 0 R -/A 105 0 R -/Parent 47 0 R -/Prev 79 0 R -/Next 111 0 R ->> endobj -103 0 obj << -/Title 104 0 R -/A 101 0 R -/Parent 79 0 R -/Prev 99 0 R ->> endobj -99 0 obj << -/Title 100 0 R -/A 97 0 R -/Parent 79 0 R -/Prev 87 0 R -/Next 103 0 R ->> endobj -95 0 obj << -/Title 96 0 R -/A 93 0 R -/Parent 87 0 R -/Prev 91 0 R ->> endobj -91 0 obj << -/Title 92 0 R -/A 89 0 R -/Parent 87 0 R -/Next 95 0 R ->> endobj -87 0 obj << -/Title 88 0 R -/A 85 0 R -/Parent 79 0 R -/Prev 83 0 R -/Next 99 0 R -/First 91 0 R -/Last 95 0 R -/Count -2 ->> endobj -83 0 obj << -/Title 84 0 R -/A 81 0 R -/Parent 79 0 R -/Next 87 0 R ->> endobj -79 0 obj << -/Title 80 0 R -/A 77 0 R -/Parent 47 0 R -/Prev 75 0 R -/Next 107 0 R -/First 83 0 R -/Last 103 0 R -/Count -4 ->> endobj -75 0 obj << -/Title 76 0 R -/A 73 0 R -/Parent 47 0 R -/Prev 71 0 R -/Next 79 0 R ->> endobj -71 0 obj << -/Title 72 0 R -/A 69 0 R -/Parent 47 0 R -/Prev 67 0 R -/Next 75 0 R ->> endobj -67 0 obj << -/Title 68 0 R -/A 65 0 R -/Parent 47 0 R -/Prev 63 0 R -/Next 71 0 R ->> endobj -63 0 obj << -/Title 64 0 R -/A 61 0 R -/Parent 47 0 R -/Prev 59 0 R -/Next 67 0 R ->> endobj -59 0 obj << -/Title 60 0 R -/A 57 0 R -/Parent 47 0 R -/Prev 55 0 R -/Next 63 0 R ->> endobj -55 0 obj << -/Title 56 0 R -/A 53 0 R -/Parent 47 0 R -/Prev 51 0 R -/Next 59 0 R ->> endobj -51 0 obj << -/Title 52 0 R -/A 49 0 R -/Parent 47 0 R -/Next 55 0 R ->> endobj -47 0 obj << -/Title 48 0 R -/A 45 0 R -/Parent 1843 0 R -/Prev 7 0 R -/Next 131 0 R -/First 51 0 R -/Last 127 0 R -/Count -14 ->> endobj -43 0 obj << -/Title 44 0 R -/A 41 0 R -/Parent 31 0 R -/Prev 39 0 R ->> endobj -39 0 obj << -/Title 40 0 R -/A 37 0 R -/Parent 31 0 R -/Prev 35 0 R -/Next 43 0 R ->> endobj -35 0 obj << -/Title 36 0 R -/A 33 0 R -/Parent 31 0 R -/Next 39 0 R ->> endobj -31 0 obj << -/Title 32 0 R -/A 29 0 R -/Parent 7 0 R -/Prev 27 0 R -/First 35 0 R -/Last 43 0 R -/Count -3 ->> endobj -27 0 obj << -/Title 28 0 R -/A 25 0 R -/Parent 7 0 R -/Prev 23 0 R -/Next 31 0 R ->> endobj -23 0 obj << -/Title 24 0 R -/A 21 0 R -/Parent 7 0 R -/Prev 19 0 R -/Next 27 0 R ->> endobj -19 0 obj << -/Title 20 0 R -/A 17 0 R -/Parent 7 0 R -/Prev 15 0 R -/Next 23 0 R ->> endobj -15 0 obj << -/Title 16 0 R -/A 13 0 R -/Parent 7 0 R -/Prev 11 0 R -/Next 19 0 R ->> endobj -11 0 obj << -/Title 12 0 R -/A 9 0 R -/Parent 7 0 R -/Next 15 0 R ->> endobj -7 0 obj << -/Title 8 0 R -/A 5 0 R -/Parent 1843 0 R -/Next 47 0 R -/First 11 0 R -/Last 31 0 R -/Count -6 ->> endobj -1844 0 obj << -/Names [(Doc-Start) 822 0 R (Item.1) 1121 0 R (Item.10) 1227 0 R (Item.11) 1350 0 R (Item.12) 1351 0 R (Item.13) 1352 0 R] -/Limits [(Doc-Start) (Item.13)] ->> endobj -1845 0 obj << -/Names [(Item.14) 1358 0 R (Item.15) 1359 0 R (Item.16) 1360 0 R (Item.17) 1361 0 R (Item.18) 1362 0 R (Item.19) 1363 0 R] -/Limits [(Item.14) (Item.19)] ->> endobj -1846 0 obj << -/Names [(Item.2) 1122 0 R (Item.20) 1364 0 R (Item.21) 1365 0 R (Item.22) 1396 0 R (Item.23) 1397 0 R (Item.24) 1470 0 R] -/Limits [(Item.2) (Item.24)] ->> endobj -1847 0 obj << -/Names [(Item.25) 1471 0 R (Item.26) 1472 0 R (Item.27) 1642 0 R (Item.28) 1643 0 R (Item.29) 1644 0 R (Item.3) 1123 0 R] -/Limits [(Item.25) (Item.3)] ->> endobj -1848 0 obj << -/Names [(Item.30) 1645 0 R (Item.31) 1646 0 R (Item.32) 1647 0 R (Item.33) 1648 0 R (Item.34) 1649 0 R (Item.35) 1650 0 R] -/Limits [(Item.30) (Item.35)] ->> endobj -1849 0 obj << -/Names [(Item.36) 1651 0 R (Item.37) 1652 0 R (Item.38) 1653 0 R (Item.39) 1659 0 R (Item.4) 1124 0 R (Item.40) 1660 0 R] -/Limits [(Item.36) (Item.40)] ->> endobj -1850 0 obj << -/Names [(Item.41) 1661 0 R (Item.42) 1662 0 R (Item.43) 1663 0 R (Item.44) 1664 0 R (Item.45) 1665 0 R (Item.46) 1666 0 R] -/Limits [(Item.41) (Item.46)] ->> endobj -1851 0 obj << -/Names [(Item.47) 1667 0 R (Item.48) 1668 0 R (Item.49) 1669 0 R (Item.5) 1125 0 R (Item.50) 1670 0 R (Item.51) 1675 0 R] -/Limits [(Item.47) (Item.51)] ->> endobj -1852 0 obj << -/Names [(Item.52) 1676 0 R (Item.53) 1677 0 R (Item.54) 1678 0 R (Item.55) 1679 0 R (Item.56) 1680 0 R (Item.57) 1681 0 R] -/Limits [(Item.52) (Item.57)] ->> endobj -1853 0 obj << -/Names [(Item.58) 1682 0 R (Item.59) 1683 0 R (Item.6) 1152 0 R (Item.60) 1684 0 R (Item.61) 1685 0 R (Item.62) 1686 0 R] -/Limits [(Item.58) (Item.62)] ->> endobj -1854 0 obj << -/Names [(Item.63) 1687 0 R (Item.64) 1688 0 R (Item.65) 1693 0 R (Item.66) 1694 0 R (Item.67) 1695 0 R (Item.68) 1696 0 R] -/Limits [(Item.63) (Item.68)] ->> endobj -1855 0 obj << -/Names [(Item.69) 1697 0 R (Item.7) 1153 0 R (Item.70) 1698 0 R (Item.8) 1154 0 R (Item.9) 1226 0 R (appendix.A) 758 0 R] -/Limits [(Item.69) (appendix.A)] ->> endobj -1856 0 obj << -/Names [(appendix.B) 766 0 R (appendix.C) 770 0 R (appendix.D) 774 0 R (appendix.E) 778 0 R (appendix.F) 814 0 R (page.1) 821 0 R] -/Limits [(appendix.B) (page.1)] ->> endobj -1857 0 obj << -/Names [(page.10) 1062 0 R (page.100) 1579 0 R (page.101) 1583 0 R (page.102) 1587 0 R (page.103) 1591 0 R (page.104) 1596 0 R] -/Limits [(page.10) (page.104)] ->> endobj -1858 0 obj << -/Names [(page.105) 1600 0 R (page.106) 1604 0 R (page.107) 1608 0 R (page.108) 1612 0 R (page.109) 1616 0 R (page.11) 1075 0 R] -/Limits [(page.105) (page.11)] ->> endobj -1859 0 obj << -/Names [(page.110) 1621 0 R (page.111) 1625 0 R (page.112) 1629 0 R (page.113) 1633 0 R (page.114) 1637 0 R (page.115) 1641 0 R] -/Limits [(page.110) (page.115)] ->> endobj -1860 0 obj << -/Names [(page.116) 1658 0 R (page.117) 1674 0 R (page.118) 1692 0 R (page.119) 1802 0 R (page.12) 1079 0 R (page.120) 1807 0 R] -/Limits [(page.116) (page.120)] ->> endobj -1861 0 obj << -/Names [(page.123) 1810 0 R (page.13) 1083 0 R (page.132) 1809 0 R (page.134) 1808 0 R (page.135) 1805 0 R (page.136) 1806 0 R] -/Limits [(page.123) (page.136)] ->> endobj -1862 0 obj << -/Names [(page.138) 1804 0 R (page.14) 1088 0 R (page.15) 1093 0 R (page.16) 1098 0 R (page.17) 1103 0 R (page.18) 1107 0 R] -/Limits [(page.138) (page.18)] ->> endobj -1863 0 obj << -/Names [(page.19) 1114 0 R (page.2) 832 0 R (page.20) 1120 0 R (page.21) 1135 0 R (page.22) 1142 0 R (page.23) 1146 0 R] -/Limits [(page.19) (page.23)] ->> endobj -1864 0 obj << -/Names [(page.24) 1151 0 R (page.25) 1160 0 R (page.26) 1167 0 R (page.27) 1171 0 R (page.28) 1188 0 R (page.29) 1192 0 R] -/Limits [(page.24) (page.29)] ->> endobj -1865 0 obj << -/Names [(page.3) 837 0 R (page.30) 1197 0 R (page.31) 1202 0 R (page.32) 1208 0 R (page.33) 1214 0 R (page.34) 1220 0 R] -/Limits [(page.3) (page.34)] ->> endobj -1866 0 obj << -/Names [(page.35) 1225 0 R (page.36) 1234 0 R (page.37) 1240 0 R (page.38) 1249 0 R (page.39) 1255 0 R (page.4) 841 0 R] -/Limits [(page.35) (page.4)] ->> endobj -1867 0 obj << -/Names [(page.40) 1259 0 R (page.41) 1264 0 R (page.42) 1268 0 R (page.43) 1272 0 R (page.44) 1279 0 R (page.45) 1286 0 R] -/Limits [(page.40) (page.45)] ->> endobj -1868 0 obj << -/Names [(page.46) 1294 0 R (page.47) 1302 0 R (page.48) 1310 0 R (page.49) 1317 0 R (page.5) 877 0 R (page.50) 1323 0 R] -/Limits [(page.46) (page.50)] ->> endobj -1869 0 obj << -/Names [(page.51) 1328 0 R (page.52) 1335 0 R (page.53) 1339 0 R (page.54) 1345 0 R (page.55) 1349 0 R (page.56) 1357 0 R] -/Limits [(page.51) (page.56)] ->> endobj -1870 0 obj << -/Names [(page.57) 1369 0 R (page.58) 1373 0 R (page.59) 1377 0 R (page.6) 916 0 R (page.60) 1382 0 R (page.61) 1386 0 R] -/Limits [(page.57) (page.61)] ->> endobj -1871 0 obj << -/Names [(page.62) 1391 0 R (page.63) 1395 0 R (page.64) 1401 0 R (page.65) 1405 0 R (page.66) 1409 0 R (page.67) 1415 0 R] -/Limits [(page.62) (page.67)] ->> endobj -1872 0 obj << -/Names [(page.68) 1422 0 R (page.69) 1426 0 R (page.7) 952 0 R (page.70) 1430 0 R (page.71) 1436 0 R (page.72) 1440 0 R] -/Limits [(page.68) (page.72)] ->> endobj -1873 0 obj << -/Names [(page.73) 1444 0 R (page.74) 1449 0 R (page.75) 1453 0 R (page.76) 1457 0 R (page.77) 1461 0 R (page.78) 1465 0 R] -/Limits [(page.73) (page.78)] ->> endobj -1874 0 obj << -/Names [(page.79) 1469 0 R (page.8) 990 0 R (page.80) 1479 0 R (page.81) 1483 0 R (page.82) 1487 0 R (page.83) 1492 0 R] -/Limits [(page.79) (page.83)] ->> endobj -1875 0 obj << -/Names [(page.84) 1496 0 R (page.85) 1502 0 R (page.86) 1507 0 R (page.87) 1511 0 R (page.88) 1518 0 R (page.89) 1523 0 R] -/Limits [(page.84) (page.89)] ->> endobj -1876 0 obj << -/Names [(page.9) 1027 0 R (page.90) 1527 0 R (page.91) 1533 0 R (page.92) 1538 0 R (page.93) 1544 0 R (page.94) 1549 0 R] -/Limits [(page.9) (page.94)] ->> endobj -1877 0 obj << -/Names [(page.95) 1554 0 R (page.96) 1559 0 R (page.97) 1563 0 R (page.98) 1568 0 R (page.99) 1572 0 R (paragraph.2.8.2.1) 90 0 R] -/Limits [(page.95) (paragraph.2.8.2.1)] ->> endobj -1878 0 obj << -/Names [(paragraph.2.8.2.2) 94 0 R (paragraph.3.1.1.1) 142 0 R (paragraph.3.1.1.2) 146 0 R (paragraph.3.1.1.3) 150 0 R (paragraph.3.2.4.1) 186 0 R (paragraph.3.2.4.2) 190 0 R] -/Limits [(paragraph.2.8.2.2) (paragraph.3.2.4.2)] ->> endobj -1879 0 obj << -/Names [(paragraph.3.2.5.1) 198 0 R (paragraph.3.2.5.2) 202 0 R (paragraph.3.2.5.3) 206 0 R (paragraph.3.4.1.1) 230 0 R (paragraph.3.4.1.2) 234 0 R (paragraph.3.4.3.1) 246 0 R] -/Limits [(paragraph.3.2.5.1) (paragraph.3.4.3.1)] ->> endobj -1880 0 obj << -/Names [(paragraph.3.4.3.2) 250 0 R (paragraph.3.4.3.3) 254 0 R (paragraph.3.4.3.4) 258 0 R (paragraph.3.4.4.1) 266 0 R (paragraph.3.4.4.2) 270 0 R (paragraph.4.1.2.1) 290 0 R] -/Limits [(paragraph.3.4.3.2) (paragraph.4.1.2.1)] ->> endobj -1881 0 obj << -/Names [(paragraph.4.1.2.2) 294 0 R (paragraph.4.1.2.3) 298 0 R (paragraph.4.1.2.4) 302 0 R (paragraph.4.1.2.5) 306 0 R (paragraph.4.1.2.6) 310 0 R (paragraph.4.1.2.7) 314 0 R] -/Limits [(paragraph.4.1.2.2) (paragraph.4.1.2.7)] ->> endobj -1882 0 obj << -/Names [(paragraph.4.1.2.8) 318 0 R (paragraph.4.1.2.9) 322 0 R (paragraph.4.10.3.1) 650 0 R (paragraph.4.10.3.10) 686 0 R (paragraph.4.10.3.11) 690 0 R (paragraph.4.10.3.12) 694 0 R] -/Limits [(paragraph.4.1.2.8) (paragraph.4.10.3.12)] ->> endobj -1883 0 obj << -/Names [(paragraph.4.10.3.13) 698 0 R (paragraph.4.10.3.14) 702 0 R (paragraph.4.10.3.2) 654 0 R (paragraph.4.10.3.3) 658 0 R (paragraph.4.10.3.4) 662 0 R (paragraph.4.10.3.5) 666 0 R] -/Limits [(paragraph.4.10.3.13) (paragraph.4.10.3.5)] ->> endobj -1884 0 obj << -/Names [(paragraph.4.10.3.6) 670 0 R (paragraph.4.10.3.7) 674 0 R (paragraph.4.10.3.8) 678 0 R (paragraph.4.10.3.9) 682 0 R (paragraph.4.11.2.1) 722 0 R (paragraph.4.11.2.2) 726 0 R] -/Limits [(paragraph.4.10.3.6) (paragraph.4.11.2.2)] ->> endobj -1885 0 obj << -/Names [(paragraph.4.11.2.3) 730 0 R (paragraph.4.11.2.4) 734 0 R (paragraph.4.11.2.5) 738 0 R (paragraph.4.11.2.6) 742 0 R (paragraph.4.11.2.7) 746 0 R (paragraph.4.11.2.8) 750 0 R] -/Limits [(paragraph.4.11.2.3) (paragraph.4.11.2.8)] ->> endobj -1886 0 obj << -/Names [(paragraph.4.11.2.9) 754 0 R (paragraph.4.2.1.1) 334 0 R (paragraph.4.2.1.2) 338 0 R (paragraph.4.2.1.3) 342 0 R (paragraph.4.2.1.4) 346 0 R (paragraph.4.2.2.1) 354 0 R] -/Limits [(paragraph.4.11.2.9) (paragraph.4.2.2.1)] ->> endobj -1887 0 obj << -/Names [(paragraph.4.2.3.1) 362 0 R (paragraph.4.2.3.2) 366 0 R (paragraph.4.2.3.3) 370 0 R (paragraph.4.2.3.4) 374 0 R (paragraph.4.2.3.5) 378 0 R (paragraph.4.2.4.1) 386 0 R] -/Limits [(paragraph.4.2.3.1) (paragraph.4.2.4.1)] ->> endobj -1888 0 obj << -/Names [(paragraph.4.2.4.2) 390 0 R (paragraph.4.2.4.3) 394 0 R (paragraph.4.2.4.4) 398 0 R (paragraph.4.2.4.5) 402 0 R (paragraph.4.2.4.6) 406 0 R (paragraph.4.2.5.1) 414 0 R] -/Limits [(paragraph.4.2.4.2) (paragraph.4.2.5.1)] ->> endobj -1889 0 obj << -/Names [(paragraph.4.2.5.2) 418 0 R (paragraph.4.2.6.1) 426 0 R (paragraph.4.2.6.2) 430 0 R (paragraph.4.2.6.3) 434 0 R (paragraph.4.3.1.1) 446 0 R (paragraph.4.3.1.2) 450 0 R] -/Limits [(paragraph.4.2.5.2) (paragraph.4.3.1.2)] ->> endobj -1890 0 obj << -/Names [(paragraph.4.3.1.3) 454 0 R (paragraph.4.3.1.4) 458 0 R (paragraph.4.4.1.1) 474 0 R (paragraph.4.4.1.2) 478 0 R (paragraph.4.4.1.3) 482 0 R (paragraph.4.4.1.4) 510 0 R] -/Limits [(paragraph.4.3.1.3) (paragraph.4.4.1.4)] ->> endobj -1891 0 obj << -/Names [(paragraph.4.4.1.5) 526 0 R (paragraph.4.4.2.1) 534 0 R (paragraph.4.4.2.2) 538 0 R (paragraph.4.4.2.3) 542 0 R (paragraph.4.4.2.4) 546 0 R (paragraph.4.4.2.5) 550 0 R] -/Limits [(paragraph.4.4.1.5) (paragraph.4.4.2.5)] ->> endobj -1892 0 obj << -/Names [(paragraph.4.7.1.1) 582 0 R (paragraph.4.7.1.2) 586 0 R (paragraph.4.8.1.1) 602 0 R (paragraph.4.8.1.2) 606 0 R (paragraph.4.8.1.3) 610 0 R (paragraph.4.9.1.1) 622 0 R] -/Limits [(paragraph.4.7.1.1) (paragraph.4.9.1.1)] ->> endobj -1893 0 obj << -/Names [(paragraph.4.9.1.2) 626 0 R (section*.1) 878 0 R (section*.2) 1803 0 R (section.1) 6 0 R (section.2) 46 0 R (section.3) 130 0 R] -/Limits [(paragraph.4.9.1.2) (section.3)] ->> endobj -1894 0 obj << -/Names [(section.4) 274 0 R (subparagraph.4.4.1.3.1) 486 0 R (subparagraph.4.4.1.3.2) 490 0 R (subparagraph.4.4.1.3.3) 494 0 R (subparagraph.4.4.1.3.4) 498 0 R (subparagraph.4.4.1.3.5) 502 0 R] -/Limits [(section.4) (subparagraph.4.4.1.3.5)] ->> endobj -1895 0 obj << -/Names [(subparagraph.4.4.1.3.6) 506 0 R (subparagraph.4.4.1.4.1) 514 0 R (subparagraph.4.4.1.4.2) 518 0 R (subparagraph.4.4.1.4.3) 522 0 R (subsection.1.1) 10 0 R (subsection.1.2) 14 0 R] -/Limits [(subparagraph.4.4.1.3.6) (subsection.1.2)] ->> endobj -1896 0 obj << -/Names [(subsection.1.3) 18 0 R (subsection.1.4) 22 0 R (subsection.1.5) 26 0 R (subsection.1.6) 30 0 R (subsection.2.1) 50 0 R (subsection.2.10) 110 0 R] -/Limits [(subsection.1.3) (subsection.2.10)] ->> endobj -1897 0 obj << -/Names [(subsection.2.11) 114 0 R (subsection.2.12) 118 0 R (subsection.2.13) 122 0 R (subsection.2.14) 126 0 R (subsection.2.2) 54 0 R (subsection.2.3) 58 0 R] -/Limits [(subsection.2.11) (subsection.2.3)] ->> endobj -1898 0 obj << -/Names [(subsection.2.4) 62 0 R (subsection.2.5) 66 0 R (subsection.2.6) 70 0 R (subsection.2.7) 74 0 R (subsection.2.8) 78 0 R (subsection.2.9) 106 0 R] -/Limits [(subsection.2.4) (subsection.2.9)] ->> endobj -1899 0 obj << -/Names [(subsection.3.1) 134 0 R (subsection.3.2) 166 0 R (subsection.3.3) 210 0 R (subsection.3.4) 222 0 R (subsection.4.1) 278 0 R (subsection.4.10) 634 0 R] -/Limits [(subsection.3.1) (subsection.4.10)] ->> endobj -1900 0 obj << -/Names [(subsection.4.11) 710 0 R (subsection.4.2) 326 0 R (subsection.4.3) 438 0 R (subsection.4.4) 466 0 R (subsection.4.5) 558 0 R (subsection.4.6) 562 0 R] -/Limits [(subsection.4.11) (subsection.4.6)] ->> endobj -1901 0 obj << -/Names [(subsection.4.7) 574 0 R (subsection.4.8) 594 0 R (subsection.4.9) 614 0 R (subsection.A.1) 762 0 R (subsection.E.1) 782 0 R (subsection.E.2) 786 0 R] -/Limits [(subsection.4.7) (subsection.E.2)] ->> endobj -1902 0 obj << -/Names [(subsubsection.1.6.1) 34 0 R (subsubsection.1.6.2) 38 0 R (subsubsection.1.6.3) 42 0 R (subsubsection.2.8.1) 82 0 R (subsubsection.2.8.2) 86 0 R (subsubsection.2.8.3) 98 0 R] -/Limits [(subsubsection.1.6.1) (subsubsection.2.8.3)] ->> endobj -1903 0 obj << -/Names [(subsubsection.2.8.4) 102 0 R (subsubsection.3.1.1) 138 0 R (subsubsection.3.1.2) 154 0 R (subsubsection.3.1.3) 158 0 R (subsubsection.3.1.4) 162 0 R (subsubsection.3.2.1) 170 0 R] -/Limits [(subsubsection.2.8.4) (subsubsection.3.2.1)] ->> endobj -1904 0 obj << -/Names [(subsubsection.3.2.2) 174 0 R (subsubsection.3.2.3) 178 0 R (subsubsection.3.2.4) 182 0 R (subsubsection.3.2.5) 194 0 R (subsubsection.3.3.1) 214 0 R (subsubsection.3.3.2) 218 0 R] -/Limits [(subsubsection.3.2.2) (subsubsection.3.3.2)] ->> endobj -1905 0 obj << -/Names [(subsubsection.3.4.1) 226 0 R (subsubsection.3.4.2) 238 0 R (subsubsection.3.4.3) 242 0 R (subsubsection.3.4.4) 262 0 R (subsubsection.4.1.1) 282 0 R (subsubsection.4.1.2) 286 0 R] -/Limits [(subsubsection.3.4.1) (subsubsection.4.1.2)] ->> endobj -1906 0 obj << -/Names [(subsubsection.4.10.1) 638 0 R (subsubsection.4.10.2) 642 0 R (subsubsection.4.10.3) 646 0 R (subsubsection.4.10.4) 706 0 R (subsubsection.4.11.1) 714 0 R (subsubsection.4.11.2) 718 0 R] -/Limits [(subsubsection.4.10.1) (subsubsection.4.11.2)] ->> endobj -1907 0 obj << -/Names [(subsubsection.4.2.1) 330 0 R (subsubsection.4.2.2) 350 0 R (subsubsection.4.2.3) 358 0 R (subsubsection.4.2.4) 382 0 R (subsubsection.4.2.5) 410 0 R (subsubsection.4.2.6) 422 0 R] -/Limits [(subsubsection.4.2.1) (subsubsection.4.2.6)] ->> endobj -1908 0 obj << -/Names [(subsubsection.4.3.1) 442 0 R (subsubsection.4.3.2) 462 0 R (subsubsection.4.4.1) 470 0 R (subsubsection.4.4.2) 530 0 R (subsubsection.4.4.3) 554 0 R (subsubsection.4.6.1) 566 0 R] -/Limits [(subsubsection.4.3.1) (subsubsection.4.6.1)] ->> endobj -1909 0 obj << -/Names [(subsubsection.4.6.2) 570 0 R (subsubsection.4.7.1) 578 0 R (subsubsection.4.7.2) 590 0 R (subsubsection.4.8.1) 598 0 R (subsubsection.4.9.1) 618 0 R (subsubsection.4.9.2) 630 0 R] -/Limits [(subsubsection.4.6.2) (subsubsection.4.9.2)] ->> endobj -1910 0 obj << -/Names [(subsubsection.E.2.1) 790 0 R (subsubsection.E.2.2) 794 0 R (subsubsection.E.2.3) 798 0 R (subsubsection.E.2.4) 802 0 R (subsubsection.E.2.5) 806 0 R (subsubsection.E.2.6) 810 0 R] -/Limits [(subsubsection.E.2.1) (subsubsection.E.2.6)] ->> endobj -1911 0 obj << -/Kids [1844 0 R 1845 0 R 1846 0 R 1847 0 R 1848 0 R 1849 0 R] -/Limits [(Doc-Start) (Item.40)] ->> endobj -1912 0 obj << -/Kids [1850 0 R 1851 0 R 1852 0 R 1853 0 R 1854 0 R 1855 0 R] -/Limits [(Item.41) (appendix.A)] ->> endobj -1913 0 obj << -/Kids [1856 0 R 1857 0 R 1858 0 R 1859 0 R 1860 0 R 1861 0 R] -/Limits [(appendix.B) (page.136)] ->> endobj -1914 0 obj << -/Kids [1862 0 R 1863 0 R 1864 0 R 1865 0 R 1866 0 R 1867 0 R] -/Limits [(page.138) (page.45)] ->> endobj -1915 0 obj << -/Kids [1868 0 R 1869 0 R 1870 0 R 1871 0 R 1872 0 R 1873 0 R] -/Limits [(page.46) (page.78)] ->> endobj -1916 0 obj << -/Kids [1874 0 R 1875 0 R 1876 0 R 1877 0 R 1878 0 R 1879 0 R] -/Limits [(page.79) (paragraph.3.4.3.1)] ->> endobj -1917 0 obj << -/Kids [1880 0 R 1881 0 R 1882 0 R 1883 0 R 1884 0 R 1885 0 R] -/Limits [(paragraph.3.4.3.2) (paragraph.4.11.2.8)] ->> endobj -1918 0 obj << -/Kids [1886 0 R 1887 0 R 1888 0 R 1889 0 R 1890 0 R 1891 0 R] -/Limits [(paragraph.4.11.2.9) (paragraph.4.4.2.5)] ->> endobj -1919 0 obj << -/Kids [1892 0 R 1893 0 R 1894 0 R 1895 0 R 1896 0 R 1897 0 R] -/Limits [(paragraph.4.7.1.1) (subsection.2.3)] ->> endobj -1920 0 obj << -/Kids [1898 0 R 1899 0 R 1900 0 R 1901 0 R 1902 0 R 1903 0 R] -/Limits [(subsection.2.4) (subsubsection.3.2.1)] ->> endobj -1921 0 obj << -/Kids [1904 0 R 1905 0 R 1906 0 R 1907 0 R 1908 0 R 1909 0 R] -/Limits [(subsubsection.3.2.2) (subsubsection.4.9.2)] ->> endobj -1922 0 obj << -/Kids [1910 0 R] -/Limits [(subsubsection.E.2.1) (subsubsection.E.2.6)] ->> endobj -1923 0 obj << -/Kids [1911 0 R 1912 0 R 1913 0 R 1914 0 R 1915 0 R 1916 0 R] -/Limits [(Doc-Start) (paragraph.3.4.3.1)] ->> endobj -1924 0 obj << -/Kids [1917 0 R 1918 0 R 1919 0 R 1920 0 R 1921 0 R 1922 0 R] -/Limits [(paragraph.3.4.3.2) (subsubsection.E.2.6)] ->> endobj -1925 0 obj << -/Kids [1923 0 R 1924 0 R] -/Limits [(Doc-Start) (subsubsection.E.2.6)] ->> endobj -1926 0 obj << -/Dests 1925 0 R ->> endobj -1927 0 obj << -/Type /Catalog -/Pages 1842 0 R -/Outlines 1843 0 R -/Names 1926 0 R -/PageMode/UseOutlines -/OpenAction 817 0 R ->> endobj -1928 0 obj << -/Author()/Title(ZSDOS 1.0)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.3)/Keywords(cp/m, zsdos) -/CreationDate (D:20090422211120-07'00') -/ModDate (D:20090422211120-07'00') -/Trapped /False -/PTEX.Fullbanner (This is pdfTeX using libpoppler, Version 3.141592-1.40.3-2.2 (Web2C 7.5.6) kpathsea version 3.5.6) ->> endobj -xref -0 1929 -0000000001 65535 f -0000000002 00000 f -0000000003 00000 f -0000000004 00000 f -0000000000 00000 f -0000000015 00000 n -0000074103 00000 n -0000498884 00000 n -0000000060 00000 n -0000000092 00000 n -0000074155 00000 n -0000498812 00000 n -0000000142 00000 n -0000000182 00000 n -0000074212 00000 n -0000498726 00000 n -0000000233 00000 n -0000000270 00000 n -0000077926 00000 n -0000498640 00000 n -0000000321 00000 n -0000000364 00000 n -0000080718 00000 n -0000498554 00000 n -0000000415 00000 n -0000000473 00000 n -0000080771 00000 n -0000498468 00000 n -0000000524 00000 n -0000000592 00000 n -0000083521 00000 n -0000498358 00000 n -0000000643 00000 n -0000000693 00000 n -0000083577 00000 n -0000498284 00000 n -0000000749 00000 n -0000000801 00000 n -0000086673 00000 n -0000498197 00000 n -0000000857 00000 n -0000000895 00000 n -0000088001 00000 n -0000498123 00000 n -0000000951 00000 n -0000000996 00000 n -0000091114 00000 n -0000497995 00000 n -0000001042 00000 n -0000001071 00000 n -0000091167 00000 n -0000497921 00000 n -0000001122 00000 n -0000001165 00000 n -0000091224 00000 n -0000497834 00000 n -0000001216 00000 n -0000001262 00000 n -0000095142 00000 n -0000497747 00000 n -0000001313 00000 n -0000001361 00000 n -0000095199 00000 n -0000497660 00000 n -0000001412 00000 n -0000001461 00000 n -0000095256 00000 n -0000497573 00000 n -0000001512 00000 n -0000001556 00000 n -0000098354 00000 n -0000497486 00000 n -0000001607 00000 n -0000001653 00000 n -0000098411 00000 n -0000497399 00000 n -0000001704 00000 n -0000001743 00000 n -0000098468 00000 n -0000497273 00000 n -0000001794 00000 n -0000001834 00000 n -0000102833 00000 n -0000497199 00000 n -0000001890 00000 n -0000001928 00000 n -0000102890 00000 n -0000497075 00000 n -0000001984 00000 n -0000002035 00000 n -0000102947 00000 n -0000497001 00000 n -0000002089 00000 n -0000002152 00000 n -0000103004 00000 n -0000496927 00000 n -0000002206 00000 n -0000002264 00000 n -0000107146 00000 n -0000496838 00000 n -0000002320 00000 n -0000002359 00000 n -0000107203 00000 n -0000496761 00000 n -0000002416 00000 n -0000002472 00000 n -0000113714 00000 n -0000496670 00000 n -0000002524 00000 n -0000002573 00000 n -0000113772 00000 n -0000496578 00000 n -0000002626 00000 n -0000002676 00000 n -0000113830 00000 n -0000496486 00000 n -0000002729 00000 n -0000002777 00000 n -0000117805 00000 n -0000496394 00000 n -0000002830 00000 n -0000002880 00000 n -0000117862 00000 n -0000496302 00000 n -0000002933 00000 n -0000002980 00000 n -0000121403 00000 n -0000496224 00000 n -0000003033 00000 n -0000003088 00000 n -0000126942 00000 n -0000496092 00000 n -0000003135 00000 n -0000003173 00000 n -0000126996 00000 n -0000495974 00000 n -0000003225 00000 n -0000003280 00000 n -0000127054 00000 n -0000495856 00000 n -0000003337 00000 n -0000003393 00000 n -0000129293 00000 n -0000495777 00000 n -0000003448 00000 n -0000003490 00000 n -0000137014 00000 n -0000495684 00000 n -0000003545 00000 n -0000003593 00000 n -0000137071 00000 n -0000495605 00000 n -0000003648 00000 n -0000003699 00000 n -0000142645 00000 n -0000495512 00000 n -0000003756 00000 n -0000003809 00000 n -0000145771 00000 n -0000495419 00000 n -0000003866 00000 n -0000003920 00000 n -0000145829 00000 n -0000495340 00000 n -0000003977 00000 n -0000004024 00000 n -0000146005 00000 n -0000495208 00000 n -0000004076 00000 n -0000004133 00000 n -0000149716 00000 n -0000495129 00000 n -0000004190 00000 n -0000004240 00000 n -0000152366 00000 n -0000495036 00000 n -0000004297 00000 n -0000004359 00000 n -0000161708 00000 n -0000494943 00000 n -0000004416 00000 n -0000004459 00000 n -0000164946 00000 n -0000494811 00000 n -0000004516 00000 n -0000004583 00000 n -0000165000 00000 n -0000494732 00000 n -0000004638 00000 n -0000004688 00000 n -0000165058 00000 n -0000494653 00000 n -0000004743 00000 n -0000004788 00000 n -0000167340 00000 n -0000494535 00000 n -0000004845 00000 n -0000004915 00000 n -0000167394 00000 n -0000494456 00000 n -0000004970 00000 n -0000005022 00000 n -0000167452 00000 n -0000494363 00000 n -0000005077 00000 n -0000005124 00000 n -0000167510 00000 n -0000494284 00000 n -0000005179 00000 n -0000005229 00000 n -0000170214 00000 n -0000494152 00000 n -0000005281 00000 n -0000005341 00000 n -0000170272 00000 n -0000494073 00000 n -0000005398 00000 n -0000005465 00000 n -0000170330 00000 n -0000493994 00000 n -0000005522 00000 n -0000005574 00000 n -0000172611 00000 n -0000493876 00000 n -0000005626 00000 n -0000005682 00000 n -0000172669 00000 n -0000493758 00000 n -0000005739 00000 n -0000005801 00000 n -0000172727 00000 n -0000493679 00000 n -0000005856 00000 n -0000005901 00000 n -0000176860 00000 n -0000493600 00000 n -0000005956 00000 n -0000006002 00000 n -0000176914 00000 n -0000493507 00000 n -0000006059 00000 n -0000006113 00000 n -0000176971 00000 n -0000493375 00000 n -0000006170 00000 n -0000006240 00000 n -0000177029 00000 n -0000493296 00000 n -0000006295 00000 n -0000006350 00000 n -0000181240 00000 n -0000493203 00000 n -0000006405 00000 n -0000006473 00000 n -0000184906 00000 n -0000493110 00000 n -0000006528 00000 n -0000006599 00000 n -0000188815 00000 n -0000493031 00000 n -0000006654 00000 n -0000006720 00000 n -0000188873 00000 n -0000492913 00000 n -0000006777 00000 n -0000006844 00000 n -0000188931 00000 n -0000492834 00000 n -0000006899 00000 n -0000006956 00000 n -0000188989 00000 n -0000492755 00000 n -0000007011 00000 n -0000007048 00000 n -0000192596 00000 n -0000492621 00000 n -0000007095 00000 n -0000007132 00000 n -0000192650 00000 n -0000492503 00000 n -0000007184 00000 n -0000007226 00000 n -0000195963 00000 n -0000492424 00000 n -0000007283 00000 n -0000007319 00000 n -0000198868 00000 n -0000492306 00000 n -0000007376 00000 n -0000007414 00000 n -0000202582 00000 n -0000492227 00000 n -0000007469 00000 n -0000007511 00000 n -0000202640 00000 n -0000492134 00000 n -0000007566 00000 n -0000007615 00000 n -0000202697 00000 n -0000492041 00000 n -0000007670 00000 n -0000007718 00000 n -0000202755 00000 n -0000491948 00000 n -0000007773 00000 n -0000007821 00000 n -0000202813 00000 n -0000491855 00000 n -0000007876 00000 n -0000007925 00000 n -0000206070 00000 n -0000491762 00000 n -0000007980 00000 n -0000008020 00000 n -0000206124 00000 n -0000491669 00000 n -0000008075 00000 n -0000008122 00000 n -0000206182 00000 n -0000491576 00000 n -0000008177 00000 n -0000008218 00000 n -0000206240 00000 n -0000491497 00000 n -0000008273 00000 n -0000008338 00000 n -0000206298 00000 n -0000491365 00000 n -0000008390 00000 n -0000008440 00000 n -0000206356 00000 n -0000491247 00000 n -0000008497 00000 n -0000008531 00000 n -0000209155 00000 n -0000491168 00000 n -0000008586 00000 n -0000008629 00000 n -0000212335 00000 n -0000491075 00000 n -0000008684 00000 n -0000008745 00000 n -0000212393 00000 n -0000490982 00000 n -0000008800 00000 n -0000008851 00000 n -0000215901 00000 n -0000490903 00000 n -0000008906 00000 n -0000008954 00000 n -0000218546 00000 n -0000490771 00000 n -0000009011 00000 n -0000009051 00000 n -0000221203 00000 n -0000490706 00000 n -0000009106 00000 n -0000009150 00000 n -0000221261 00000 n -0000490574 00000 n -0000009207 00000 n -0000009257 00000 n -0000221319 00000 n -0000490495 00000 n -0000009312 00000 n -0000009363 00000 n -0000224504 00000 n -0000490402 00000 n -0000009418 00000 n -0000009462 00000 n -0000224562 00000 n -0000490309 00000 n -0000009517 00000 n -0000009567 00000 n -0000230208 00000 n -0000490216 00000 n -0000009622 00000 n -0000009664 00000 n -0000232944 00000 n -0000490137 00000 n -0000009719 00000 n -0000009769 00000 n -0000233002 00000 n -0000490005 00000 n -0000009826 00000 n -0000009872 00000 n -0000233060 00000 n -0000489926 00000 n -0000009927 00000 n -0000009973 00000 n -0000233118 00000 n -0000489833 00000 n -0000010028 00000 n -0000010070 00000 n -0000235983 00000 n -0000489740 00000 n -0000010125 00000 n -0000010174 00000 n -0000236037 00000 n -0000489647 00000 n -0000010229 00000 n -0000010275 00000 n -0000236095 00000 n -0000489554 00000 n -0000010330 00000 n -0000010374 00000 n -0000236151 00000 n -0000489475 00000 n -0000010429 00000 n -0000010495 00000 n -0000236327 00000 n -0000489343 00000 n -0000010552 00000 n -0000010608 00000 n -0000236385 00000 n -0000489264 00000 n -0000010663 00000 n -0000010703 00000 n -0000242918 00000 n -0000489185 00000 n -0000010758 00000 n -0000010799 00000 n -0000246402 00000 n -0000489067 00000 n -0000010856 00000 n -0000010903 00000 n -0000246456 00000 n -0000488988 00000 n -0000010958 00000 n -0000011010 00000 n -0000246514 00000 n -0000488895 00000 n -0000011065 00000 n -0000011109 00000 n -0000246572 00000 n -0000488816 00000 n -0000011164 00000 n -0000011214 00000 n -0000249667 00000 n -0000488684 00000 n -0000011266 00000 n -0000011327 00000 n -0000249721 00000 n -0000488566 00000 n -0000011384 00000 n -0000011424 00000 n -0000249779 00000 n -0000488487 00000 n -0000011479 00000 n -0000011532 00000 n -0000249837 00000 n -0000488394 00000 n -0000011587 00000 n -0000011636 00000 n -0000249895 00000 n -0000488301 00000 n -0000011691 00000 n -0000011735 00000 n -0000252986 00000 n -0000488222 00000 n -0000011790 00000 n -0000011833 00000 n -0000254783 00000 n -0000488143 00000 n -0000011890 00000 n -0000011939 00000 n -0000257972 00000 n -0000488011 00000 n -0000011991 00000 n -0000012045 00000 n -0000258026 00000 n -0000487893 00000 n -0000012102 00000 n -0000012143 00000 n -0000260345 00000 n -0000487814 00000 n -0000012198 00000 n -0000012249 00000 n -0000260399 00000 n -0000487721 00000 n -0000012304 00000 n -0000012360 00000 n -0000260457 00000 n -0000487589 00000 n -0000012415 00000 n -0000012459 00000 n -0000262842 00000 n -0000487510 00000 n -0000012519 00000 n -0000012564 00000 n -0000265838 00000 n -0000487417 00000 n -0000012624 00000 n -0000012684 00000 n -0000265892 00000 n -0000487324 00000 n -0000012744 00000 n -0000012795 00000 n -0000265950 00000 n -0000487231 00000 n -0000012855 00000 n -0000012893 00000 n -0000266008 00000 n -0000487138 00000 n -0000012953 00000 n -0000013003 00000 n -0000266066 00000 n -0000487059 00000 n -0000013063 00000 n -0000013115 00000 n -0000266124 00000 n -0000486927 00000 n -0000013170 00000 n -0000013226 00000 n -0000268391 00000 n -0000486848 00000 n -0000013286 00000 n -0000013331 00000 n -0000268445 00000 n -0000486755 00000 n -0000013391 00000 n -0000013426 00000 n -0000271270 00000 n -0000486676 00000 n -0000013486 00000 n -0000013535 00000 n -0000271328 00000 n -0000486597 00000 n -0000013590 00000 n -0000013646 00000 n -0000274005 00000 n -0000486465 00000 n -0000013703 00000 n -0000013744 00000 n -0000274059 00000 n -0000486386 00000 n -0000013799 00000 n -0000013842 00000 n -0000274117 00000 n -0000486293 00000 n -0000013897 00000 n -0000013954 00000 n -0000276688 00000 n -0000486200 00000 n -0000014009 00000 n -0000014068 00000 n -0000276746 00000 n -0000486107 00000 n -0000014123 00000 n -0000014173 00000 n -0000276804 00000 n -0000486028 00000 n -0000014228 00000 n -0000014279 00000 n -0000279365 00000 n -0000485949 00000 n -0000014336 00000 n -0000014385 00000 n -0000282342 00000 n -0000485856 00000 n -0000014437 00000 n -0000014487 00000 n -0000282400 00000 n -0000485724 00000 n -0000014539 00000 n -0000014587 00000 n -0000282458 00000 n -0000485645 00000 n -0000014644 00000 n -0000014678 00000 n -0000284807 00000 n -0000485566 00000 n -0000014735 00000 n -0000014778 00000 n -0000287024 00000 n -0000485434 00000 n -0000014830 00000 n -0000014875 00000 n -0000287082 00000 n -0000485316 00000 n -0000014932 00000 n -0000014968 00000 n -0000287140 00000 n -0000485237 00000 n -0000015023 00000 n -0000015075 00000 n -0000290302 00000 n -0000485158 00000 n -0000015130 00000 n -0000015169 00000 n -0000290356 00000 n -0000485079 00000 n -0000015226 00000 n -0000015271 00000 n -0000290414 00000 n -0000484947 00000 n -0000015323 00000 n -0000015376 00000 n -0000290472 00000 n -0000484843 00000 n -0000015433 00000 n -0000015470 00000 n -0000292614 00000 n -0000484764 00000 n -0000015525 00000 n -0000015574 00000 n -0000292672 00000 n -0000484671 00000 n -0000015629 00000 n -0000015677 00000 n -0000295792 00000 n -0000484592 00000 n -0000015732 00000 n -0000015772 00000 n -0000295849 00000 n -0000484460 00000 n -0000015824 00000 n -0000015870 00000 n -0000295906 00000 n -0000484342 00000 n -0000015927 00000 n -0000015963 00000 n -0000295964 00000 n -0000484263 00000 n -0000016018 00000 n -0000016069 00000 n -0000297925 00000 n -0000484184 00000 n -0000016124 00000 n -0000016166 00000 n -0000299373 00000 n -0000484105 00000 n -0000016223 00000 n -0000016281 00000 n -0000301853 00000 n -0000483973 00000 n -0000016334 00000 n -0000016403 00000 n -0000301911 00000 n -0000483894 00000 n -0000016461 00000 n -0000016513 00000 n -0000304476 00000 n -0000483801 00000 n -0000016571 00000 n -0000016618 00000 n -0000308881 00000 n -0000483668 00000 n -0000016676 00000 n -0000016719 00000 n -0000308939 00000 n -0000483589 00000 n -0000016775 00000 n -0000016836 00000 n -0000308997 00000 n -0000483496 00000 n -0000016892 00000 n -0000016965 00000 n -0000310717 00000 n -0000483403 00000 n -0000017021 00000 n -0000017094 00000 n -0000310775 00000 n -0000483310 00000 n -0000017150 00000 n -0000017220 00000 n -0000310833 00000 n -0000483217 00000 n -0000017276 00000 n -0000017344 00000 n -0000313309 00000 n -0000483124 00000 n -0000017400 00000 n -0000017473 00000 n -0000313367 00000 n -0000483031 00000 n -0000017529 00000 n -0000017588 00000 n -0000316594 00000 n -0000482938 00000 n -0000017644 00000 n -0000017717 00000 n -0000319519 00000 n -0000482845 00000 n -0000017773 00000 n -0000017851 00000 n -0000319577 00000 n -0000482752 00000 n -0000017908 00000 n -0000017982 00000 n -0000322263 00000 n -0000482659 00000 n -0000018039 00000 n -0000018101 00000 n -0000324597 00000 n -0000482566 00000 n -0000018158 00000 n -0000018225 00000 n -0000327117 00000 n -0000482473 00000 n -0000018282 00000 n -0000018346 00000 n -0000327175 00000 n -0000482394 00000 n -0000018403 00000 n -0000018467 00000 n -0000329609 00000 n -0000482315 00000 n -0000018525 00000 n -0000018575 00000 n -0000329667 00000 n -0000482197 00000 n -0000018628 00000 n -0000018685 00000 n -0000329725 00000 n -0000482118 00000 n -0000018743 00000 n -0000018779 00000 n -0000333356 00000 n -0000482000 00000 n -0000018837 00000 n -0000018875 00000 n -0000333414 00000 n -0000481921 00000 n -0000018931 00000 n -0000018985 00000 n -0000333472 00000 n -0000481828 00000 n -0000019041 00000 n -0000019089 00000 n -0000335934 00000 n -0000481735 00000 n -0000019145 00000 n -0000019205 00000 n -0000335992 00000 n -0000481642 00000 n -0000019261 00000 n -0000019311 00000 n -0000336046 00000 n -0000481549 00000 n -0000019367 00000 n -0000019413 00000 n -0000336104 00000 n -0000481456 00000 n -0000019469 00000 n -0000019518 00000 n -0000336162 00000 n -0000481363 00000 n -0000019574 00000 n -0000019620 00000 n -0000336220 00000 n -0000481270 00000 n -0000019676 00000 n -0000019719 00000 n -0000337382 00000 n -0000481191 00000 n -0000019775 00000 n -0000019816 00000 n -0000340269 00000 n -0000481058 00000 n -0000019864 00000 n -0000019917 00000 n -0000343822 00000 n -0000480993 00000 n -0000019969 00000 n -0000020021 00000 n -0000345666 00000 n -0000480899 00000 n -0000020069 00000 n -0000020121 00000 n -0000347620 00000 n -0000480805 00000 n -0000020169 00000 n -0000020222 00000 n -0000349428 00000 n -0000480711 00000 n -0000020270 00000 n -0000020326 00000 n -0000355607 00000 n -0000480578 00000 n -0000020374 00000 n -0000020411 00000 n -0000355661 00000 n -0000480499 00000 n -0000020463 00000 n -0000020512 00000 n -0000358641 00000 n -0000480381 00000 n -0000020564 00000 n -0000020611 00000 n -0000358695 00000 n -0000480302 00000 n -0000020668 00000 n -0000020722 00000 n -0000358753 00000 n -0000480209 00000 n -0000020779 00000 n -0000020837 00000 n -0000361012 00000 n -0000480116 00000 n -0000020894 00000 n -0000020950 00000 n -0000361066 00000 n -0000480023 00000 n -0000021007 00000 n -0000021059 00000 n -0000361124 00000 n -0000479930 00000 n -0000021116 00000 n -0000021165 00000 n -0000361181 00000 n -0000479851 00000 n -0000021222 00000 n -0000021272 00000 n -0000363695 00000 n -0000479771 00000 n -0000021320 00000 n -0000021367 00000 n -0000022625 00000 n -0000022843 00000 n -0000021420 00000 n -0000022737 00000 n -0000022790 00000 n -0000475494 00000 n -0000475930 00000 n -0000476364 00000 n -0000475785 00000 n -0000476655 00000 n -0000025206 00000 n -0000025417 00000 n -0000025074 00000 n -0000022953 00000 n -0000025364 00000 n -0000475640 00000 n -0000026251 00000 n -0000026086 00000 n -0000025514 00000 n -0000026198 00000 n -0000026696 00000 n -0000026531 00000 n -0000026322 00000 n -0000026643 00000 n -0000028480 00000 n -0000028630 00000 n -0000028785 00000 n -0000028941 00000 n -0000029097 00000 n -0000029253 00000 n -0000029409 00000 n -0000029565 00000 n -0000029727 00000 n -0000029888 00000 n -0000030050 00000 n -0000030201 00000 n -0000030356 00000 n -0000030511 00000 n -0000030667 00000 n -0000030823 00000 n -0000030979 00000 n -0000031135 00000 n -0000031291 00000 n -0000031446 00000 n -0000031608 00000 n -0000031770 00000 n -0000031930 00000 n -0000032090 00000 n -0000032251 00000 n -0000032411 00000 n -0000032567 00000 n -0000032724 00000 n -0000032881 00000 n -0000033038 00000 n -0000033195 00000 n -0000035276 00000 n -0000033461 00000 n -0000028108 00000 n -0000026767 00000 n -0000033351 00000 n -0000033404 00000 n -0000475348 00000 n -0000035427 00000 n -0000035583 00000 n -0000035745 00000 n -0000035904 00000 n -0000036064 00000 n -0000036224 00000 n -0000036385 00000 n -0000036547 00000 n -0000036708 00000 n -0000036864 00000 n -0000037026 00000 n -0000037187 00000 n -0000037349 00000 n -0000037511 00000 n -0000037671 00000 n -0000037831 00000 n -0000037993 00000 n -0000038153 00000 n -0000038312 00000 n -0000038471 00000 n -0000038627 00000 n -0000038789 00000 n -0000038951 00000 n -0000039107 00000 n -0000039269 00000 n -0000039429 00000 n -0000039589 00000 n -0000039749 00000 n -0000039910 00000 n -0000040070 00000 n -0000040230 00000 n -0000040390 00000 n -0000042312 00000 n -0000040603 00000 n -0000034888 00000 n -0000033558 00000 n -0000040550 00000 n -0000042473 00000 n -0000042633 00000 n -0000042793 00000 n -0000042944 00000 n -0000043100 00000 n -0000043262 00000 n -0000043424 00000 n -0000043584 00000 n -0000043744 00000 n -0000043903 00000 n -0000044063 00000 n -0000044222 00000 n -0000044382 00000 n -0000044542 00000 n -0000044702 00000 n -0000044862 00000 n -0000045018 00000 n -0000045180 00000 n -0000045340 00000 n -0000045499 00000 n -0000045659 00000 n -0000045819 00000 n -0000045980 00000 n -0000046140 00000 n -0000046302 00000 n -0000046462 00000 n -0000046622 00000 n -0000046782 00000 n -0000046942 00000 n -0000047100 00000 n -0000047262 00000 n -0000049243 00000 n -0000047474 00000 n -0000041932 00000 n -0000040687 00000 n -0000047421 00000 n -0000476773 00000 n -0000049403 00000 n -0000049563 00000 n -0000049723 00000 n -0000049883 00000 n -0000050043 00000 n -0000050205 00000 n -0000050365 00000 n -0000050525 00000 n -0000050686 00000 n -0000050846 00000 n -0000051006 00000 n -0000051166 00000 n -0000051322 00000 n -0000051484 00000 n -0000051644 00000 n -0000051804 00000 n -0000051963 00000 n -0000052123 00000 n -0000052285 00000 n -0000052440 00000 n -0000052602 00000 n -0000052762 00000 n -0000052922 00000 n -0000053082 00000 n -0000053246 00000 n -0000053410 00000 n -0000053574 00000 n -0000053738 00000 n -0000053901 00000 n -0000054065 00000 n -0000054225 00000 n -0000054389 00000 n -0000056382 00000 n -0000054605 00000 n -0000048855 00000 n -0000047558 00000 n -0000054552 00000 n -0000056546 00000 n -0000056706 00000 n -0000056868 00000 n -0000057028 00000 n -0000057188 00000 n -0000057348 00000 n -0000057504 00000 n -0000057664 00000 n -0000057826 00000 n -0000057982 00000 n -0000058139 00000 n -0000058302 00000 n -0000058464 00000 n -0000058621 00000 n -0000058784 00000 n -0000058945 00000 n -0000059104 00000 n -0000059267 00000 n -0000059423 00000 n -0000059585 00000 n -0000059745 00000 n -0000059906 00000 n -0000060067 00000 n -0000060224 00000 n -0000060387 00000 n -0000060548 00000 n -0000060709 00000 n -0000060871 00000 n -0000061028 00000 n -0000061190 00000 n -0000061354 00000 n -0000061518 00000 n -0000063566 00000 n -0000061735 00000 n -0000055968 00000 n -0000054676 00000 n -0000061680 00000 n -0000063726 00000 n -0000063888 00000 n -0000064050 00000 n -0000064212 00000 n -0000064373 00000 n -0000064535 00000 n -0000064696 00000 n -0000064858 00000 n -0000065021 00000 n -0000065184 00000 n -0000065346 00000 n -0000065509 00000 n -0000065672 00000 n -0000065836 00000 n -0000065994 00000 n -0000066158 00000 n -0000066321 00000 n -0000066483 00000 n -0000066644 00000 n -0000066806 00000 n -0000066968 00000 n -0000067130 00000 n -0000067292 00000 n -0000067454 00000 n -0000067616 00000 n -0000067778 00000 n -0000067931 00000 n -0000068088 00000 n -0000068241 00000 n -0000068394 00000 n -0000069507 00000 n -0000068601 00000 n -0000063160 00000 n -0000061807 00000 n -0000068546 00000 n -0000069660 00000 n -0000069817 00000 n -0000069974 00000 n -0000070137 00000 n -0000070299 00000 n -0000070462 00000 n -0000070625 00000 n -0000070788 00000 n -0000070951 00000 n -0000071158 00000 n -0000069290 00000 n -0000068686 00000 n -0000071103 00000 n -0000074268 00000 n -0000073933 00000 n -0000071243 00000 n -0000074048 00000 n -0000077983 00000 n -0000077755 00000 n -0000074366 00000 n -0000077871 00000 n -0000476895 00000 n -0000080828 00000 n -0000080547 00000 n -0000078068 00000 n -0000080663 00000 n -0000476220 00000 n -0000083634 00000 n -0000083350 00000 n -0000080939 00000 n -0000083466 00000 n -0000476508 00000 n -0000086730 00000 n -0000086502 00000 n -0000083746 00000 n -0000086618 00000 n -0000087789 00000 n -0000088054 00000 n -0000087652 00000 n -0000086829 00000 n -0000087946 00000 n -0000091281 00000 n -0000090943 00000 n -0000088153 00000 n -0000091059 00000 n -0000094609 00000 n -0000094766 00000 n -0000094929 00000 n -0000095313 00000 n -0000094454 00000 n -0000091393 00000 n -0000095087 00000 n -0000477020 00000 n -0000098142 00000 n -0000098820 00000 n -0000098005 00000 n -0000095398 00000 n -0000098299 00000 n -0000098525 00000 n -0000098584 00000 n -0000098643 00000 n -0000098702 00000 n -0000098761 00000 n -0000101994 00000 n -0000102156 00000 n -0000102314 00000 n -0000102467 00000 n -0000102621 00000 n -0000106613 00000 n -0000103061 00000 n -0000101821 00000 n -0000098905 00000 n -0000102778 00000 n -0000476075 00000 n -0000106774 00000 n -0000106928 00000 n -0000107261 00000 n -0000106458 00000 n -0000103160 00000 n -0000107091 00000 n -0000110401 00000 n -0000110230 00000 n -0000107360 00000 n -0000110346 00000 n -0000113319 00000 n -0000113888 00000 n -0000113182 00000 n -0000110487 00000 n -0000113482 00000 n -0000113537 00000 n -0000113596 00000 n -0000113655 00000 n -0000117439 00000 n -0000117596 00000 n -0000117920 00000 n -0000117293 00000 n -0000113986 00000 n -0000117750 00000 n -0000477145 00000 n -0000121036 00000 n -0000121193 00000 n -0000121461 00000 n -0000120890 00000 n -0000118018 00000 n -0000121348 00000 n -0000122480 00000 n -0000122309 00000 n -0000121559 00000 n -0000122425 00000 n -0000124973 00000 n -0000125129 00000 n -0000125284 00000 n -0000125440 00000 n -0000125597 00000 n -0000125757 00000 n -0000125916 00000 n -0000126076 00000 n -0000126235 00000 n -0000126398 00000 n -0000126561 00000 n -0000126724 00000 n -0000129077 00000 n -0000127112 00000 n -0000124737 00000 n -0000122552 00000 n -0000126887 00000 n -0000129351 00000 n -0000128940 00000 n -0000127210 00000 n -0000129238 00000 n -0000131557 00000 n -0000131769 00000 n -0000131420 00000 n -0000129463 00000 n -0000131714 00000 n -0000133928 00000 n -0000134142 00000 n -0000133791 00000 n -0000131855 00000 n -0000134087 00000 n -0000477270 00000 n -0000136800 00000 n -0000137129 00000 n -0000136663 00000 n -0000134228 00000 n -0000136959 00000 n -0000139722 00000 n -0000139885 00000 n -0000140101 00000 n -0000139576 00000 n -0000137228 00000 n -0000140046 00000 n -0000142433 00000 n -0000145399 00000 n -0000142703 00000 n -0000142296 00000 n -0000140187 00000 n -0000142590 00000 n -0000145557 00000 n -0000146063 00000 n -0000145253 00000 n -0000142802 00000 n -0000145716 00000 n -0000145887 00000 n -0000145946 00000 n -0000149178 00000 n -0000149341 00000 n -0000149503 00000 n -0000149774 00000 n -0000149023 00000 n -0000146175 00000 n -0000149661 00000 n -0000151992 00000 n -0000152149 00000 n -0000152424 00000 n -0000151846 00000 n -0000149873 00000 n -0000152311 00000 n -0000477395 00000 n -0000155034 00000 n -0000155195 00000 n -0000155358 00000 n -0000158267 00000 n -0000155570 00000 n -0000154879 00000 n -0000152537 00000 n -0000155515 00000 n -0000158420 00000 n -0000158583 00000 n -0000158795 00000 n -0000158112 00000 n -0000155656 00000 n -0000158740 00000 n -0000161766 00000 n -0000161537 00000 n -0000158894 00000 n -0000161653 00000 n -0000164733 00000 n -0000165116 00000 n -0000164596 00000 n -0000161865 00000 n -0000164891 00000 n -0000167568 00000 n -0000167169 00000 n -0000165229 00000 n -0000167285 00000 n -0000170388 00000 n -0000170043 00000 n -0000167681 00000 n -0000170159 00000 n -0000477520 00000 n -0000172235 00000 n -0000172395 00000 n -0000172785 00000 n -0000172089 00000 n -0000170500 00000 n -0000172556 00000 n -0000176316 00000 n -0000176479 00000 n -0000176642 00000 n -0000177087 00000 n -0000176161 00000 n -0000172910 00000 n -0000176805 00000 n -0000180536 00000 n -0000180699 00000 n -0000180860 00000 n -0000181023 00000 n -0000181298 00000 n -0000180372 00000 n -0000177199 00000 n -0000181185 00000 n -0000184200 00000 n -0000184362 00000 n -0000184525 00000 n -0000184688 00000 n -0000184964 00000 n -0000184036 00000 n -0000181397 00000 n -0000184851 00000 n -0000188128 00000 n -0000188291 00000 n -0000188449 00000 n -0000188602 00000 n -0000189047 00000 n -0000187964 00000 n -0000185063 00000 n -0000188760 00000 n -0000192226 00000 n -0000192384 00000 n -0000195593 00000 n -0000192708 00000 n -0000192080 00000 n -0000189146 00000 n -0000192541 00000 n -0000477645 00000 n -0000195751 00000 n -0000196021 00000 n -0000195447 00000 n -0000192819 00000 n -0000195908 00000 n -0000198650 00000 n -0000198924 00000 n -0000198513 00000 n -0000196120 00000 n -0000198813 00000 n -0000202047 00000 n -0000202210 00000 n -0000202364 00000 n -0000202871 00000 n -0000201892 00000 n -0000199023 00000 n -0000202527 00000 n -0000206414 00000 n -0000205899 00000 n -0000202956 00000 n -0000206015 00000 n -0000208785 00000 n -0000208938 00000 n -0000209212 00000 n -0000208639 00000 n -0000206525 00000 n -0000209100 00000 n -0000212624 00000 n -0000212164 00000 n -0000209324 00000 n -0000212280 00000 n -0000212450 00000 n -0000212508 00000 n -0000212566 00000 n -0000477770 00000 n -0000215958 00000 n -0000215263 00000 n -0000212736 00000 n -0000215379 00000 n -0000215434 00000 n -0000215489 00000 n -0000215548 00000 n -0000215607 00000 n -0000215665 00000 n -0000215724 00000 n -0000215783 00000 n -0000215842 00000 n -0000218604 00000 n -0000218375 00000 n -0000216070 00000 n -0000218491 00000 n -0000221377 00000 n -0000221032 00000 n -0000218729 00000 n -0000221148 00000 n -0000224620 00000 n -0000224333 00000 n -0000221476 00000 n -0000224449 00000 n -0000227671 00000 n -0000227889 00000 n -0000227534 00000 n -0000224732 00000 n -0000227834 00000 n -0000230262 00000 n -0000230037 00000 n -0000227988 00000 n -0000230153 00000 n -0000477895 00000 n -0000233176 00000 n -0000232773 00000 n -0000230374 00000 n -0000232889 00000 n -0000236443 00000 n -0000235812 00000 n -0000233301 00000 n -0000235928 00000 n -0000236209 00000 n -0000236268 00000 n -0000238166 00000 n -0000237995 00000 n -0000236542 00000 n -0000238111 00000 n -0000240393 00000 n -0000240222 00000 n -0000238265 00000 n -0000240338 00000 n -0000242976 00000 n -0000242747 00000 n -0000240492 00000 n -0000242863 00000 n -0000246193 00000 n -0000249146 00000 n -0000246630 00000 n -0000246056 00000 n -0000243088 00000 n -0000246347 00000 n -0000478020 00000 n -0000249300 00000 n -0000249454 00000 n -0000249953 00000 n -0000248991 00000 n -0000246729 00000 n -0000249612 00000 n -0000253043 00000 n -0000252815 00000 n -0000250065 00000 n -0000252931 00000 n -0000254837 00000 n -0000254612 00000 n -0000253142 00000 n -0000254728 00000 n -0000257759 00000 n -0000260133 00000 n -0000258083 00000 n -0000257622 00000 n -0000254936 00000 n -0000257917 00000 n -0000260514 00000 n -0000259996 00000 n -0000258208 00000 n -0000260290 00000 n -0000262900 00000 n -0000262671 00000 n -0000260626 00000 n -0000262787 00000 n -0000478145 00000 n -0000266182 00000 n -0000265667 00000 n -0000262999 00000 n -0000265783 00000 n -0000268503 00000 n -0000268220 00000 n -0000266294 00000 n -0000268336 00000 n -0000271386 00000 n -0000271099 00000 n -0000268615 00000 n -0000271215 00000 n -0000274175 00000 n -0000273834 00000 n -0000271498 00000 n -0000273950 00000 n -0000276862 00000 n -0000276517 00000 n -0000274274 00000 n -0000276633 00000 n -0000279423 00000 n -0000279017 00000 n -0000276961 00000 n -0000279133 00000 n -0000279188 00000 n -0000279247 00000 n -0000279306 00000 n -0000478270 00000 n -0000281973 00000 n -0000282130 00000 n -0000282516 00000 n -0000281827 00000 n -0000279522 00000 n -0000282287 00000 n -0000284865 00000 n -0000284636 00000 n -0000282628 00000 n -0000284752 00000 n -0000287198 00000 n -0000286853 00000 n -0000284964 00000 n -0000286969 00000 n -0000290089 00000 n -0000290530 00000 n -0000289952 00000 n -0000287310 00000 n -0000290247 00000 n -0000292730 00000 n -0000292443 00000 n -0000290628 00000 n -0000292559 00000 n -0000295423 00000 n -0000295580 00000 n -0000296022 00000 n -0000295277 00000 n -0000292829 00000 n -0000295737 00000 n -0000478395 00000 n -0000297983 00000 n -0000297754 00000 n -0000296134 00000 n -0000297870 00000 n -0000299431 00000 n -0000299202 00000 n -0000298082 00000 n -0000299318 00000 n -0000301329 00000 n -0000301486 00000 n -0000301640 00000 n -0000301969 00000 n -0000301174 00000 n -0000299530 00000 n -0000301798 00000 n -0000304257 00000 n -0000304534 00000 n -0000304120 00000 n -0000302081 00000 n -0000304421 00000 n -0000305997 00000 n -0000305826 00000 n -0000304633 00000 n -0000305942 00000 n -0000308512 00000 n -0000308664 00000 n -0000309055 00000 n -0000308366 00000 n -0000306082 00000 n -0000308826 00000 n -0000478520 00000 n -0000310890 00000 n -0000310546 00000 n -0000309154 00000 n -0000310662 00000 n -0000312932 00000 n -0000313093 00000 n -0000313425 00000 n -0000312786 00000 n -0000310989 00000 n -0000313254 00000 n -0000316381 00000 n -0000316652 00000 n -0000316244 00000 n -0000313524 00000 n -0000316539 00000 n -0000319301 00000 n -0000319635 00000 n -0000319164 00000 n -0000316764 00000 n -0000319464 00000 n -0000322047 00000 n -0000322321 00000 n -0000321910 00000 n -0000319748 00000 n -0000322208 00000 n -0000324655 00000 n -0000324426 00000 n -0000322434 00000 n -0000324542 00000 n -0000478645 00000 n -0000327233 00000 n -0000326946 00000 n -0000324768 00000 n -0000327062 00000 n -0000329783 00000 n -0000329438 00000 n -0000327346 00000 n -0000329554 00000 n -0000332833 00000 n -0000332991 00000 n -0000333148 00000 n -0000333530 00000 n -0000332678 00000 n -0000329909 00000 n -0000333301 00000 n -0000336278 00000 n -0000335763 00000 n -0000333629 00000 n -0000335879 00000 n -0000337436 00000 n -0000337211 00000 n -0000336377 00000 n -0000337327 00000 n -0000337918 00000 n -0000337747 00000 n -0000337535 00000 n -0000337863 00000 n -0000478770 00000 n -0000340323 00000 n -0000340098 00000 n -0000337990 00000 n -0000340214 00000 n -0000342421 00000 n -0000342250 00000 n -0000340421 00000 n -0000342366 00000 n -0000343876 00000 n -0000343651 00000 n -0000342506 00000 n -0000343767 00000 n -0000345720 00000 n -0000345495 00000 n -0000343974 00000 n -0000345611 00000 n -0000347674 00000 n -0000347449 00000 n -0000345818 00000 n -0000347565 00000 n -0000349482 00000 n -0000349257 00000 n -0000347759 00000 n -0000349373 00000 n -0000478895 00000 n -0000351634 00000 n -0000351463 00000 n -0000349567 00000 n -0000351579 00000 n -0000353159 00000 n -0000352988 00000 n -0000351733 00000 n -0000353104 00000 n -0000355719 00000 n -0000355436 00000 n -0000353258 00000 n -0000355552 00000 n -0000358811 00000 n -0000358470 00000 n -0000355818 00000 n -0000358586 00000 n -0000361238 00000 n -0000360841 00000 n -0000358909 00000 n -0000360957 00000 n -0000364456 00000 n -0000363524 00000 n -0000361323 00000 n -0000363640 00000 n -0000363749 00000 n -0000363808 00000 n -0000363867 00000 n -0000363926 00000 n -0000363985 00000 n -0000364044 00000 n -0000364103 00000 n -0000364161 00000 n -0000364220 00000 n -0000364279 00000 n -0000364338 00000 n -0000364397 00000 n -0000479020 00000 n -0000367945 00000 n -0000367071 00000 n -0000364567 00000 n -0000367187 00000 n -0000367242 00000 n -0000367297 00000 n -0000367355 00000 n -0000367414 00000 n -0000367473 00000 n -0000367532 00000 n -0000367591 00000 n -0000367650 00000 n -0000367709 00000 n -0000367768 00000 n -0000367827 00000 n -0000367886 00000 n -0000371241 00000 n -0000370249 00000 n -0000368030 00000 n -0000370365 00000 n -0000370420 00000 n -0000370475 00000 n -0000370534 00000 n -0000370593 00000 n -0000370652 00000 n -0000370711 00000 n -0000370770 00000 n -0000370829 00000 n -0000370888 00000 n -0000370947 00000 n -0000371006 00000 n -0000371065 00000 n -0000371124 00000 n -0000371183 00000 n -0000373032 00000 n -0000372512 00000 n -0000371326 00000 n -0000372628 00000 n -0000372683 00000 n -0000372738 00000 n -0000372796 00000 n -0000372855 00000 n -0000372914 00000 n -0000372973 00000 n -0000375233 00000 n -0000375384 00000 n -0000375535 00000 n -0000375684 00000 n -0000375834 00000 n -0000375984 00000 n -0000376134 00000 n -0000376283 00000 n -0000376434 00000 n -0000376586 00000 n -0000376738 00000 n -0000376889 00000 n -0000377040 00000 n -0000377192 00000 n -0000377343 00000 n -0000377494 00000 n -0000377645 00000 n -0000377796 00000 n -0000377945 00000 n -0000378095 00000 n -0000378244 00000 n -0000378394 00000 n -0000378543 00000 n -0000378692 00000 n -0000378842 00000 n -0000378992 00000 n -0000379142 00000 n -0000379293 00000 n -0000379442 00000 n -0000379593 00000 n -0000379745 00000 n -0000379894 00000 n -0000380043 00000 n -0000380194 00000 n -0000380344 00000 n -0000380495 00000 n -0000380645 00000 n -0000380795 00000 n -0000380946 00000 n -0000381096 00000 n -0000381247 00000 n -0000381399 00000 n -0000381550 00000 n -0000381700 00000 n -0000381851 00000 n -0000382002 00000 n -0000382153 00000 n -0000382305 00000 n -0000382455 00000 n -0000382606 00000 n -0000382756 00000 n -0000382906 00000 n -0000383055 00000 n -0000383205 00000 n -0000383355 00000 n -0000383503 00000 n -0000383653 00000 n -0000383804 00000 n -0000383954 00000 n -0000384105 00000 n -0000384257 00000 n -0000384407 00000 n -0000384557 00000 n -0000384704 00000 n -0000384850 00000 n -0000385000 00000 n -0000385151 00000 n -0000385302 00000 n -0000385452 00000 n -0000385603 00000 n -0000385755 00000 n -0000385906 00000 n -0000386057 00000 n -0000386209 00000 n -0000386361 00000 n -0000386512 00000 n -0000386663 00000 n -0000386814 00000 n -0000386966 00000 n -0000387118 00000 n -0000387269 00000 n -0000387420 00000 n -0000387571 00000 n -0000387723 00000 n -0000387874 00000 n -0000388025 00000 n -0000388175 00000 n -0000388325 00000 n -0000388475 00000 n -0000388625 00000 n -0000388774 00000 n -0000388924 00000 n -0000389074 00000 n -0000389225 00000 n -0000389375 00000 n -0000389527 00000 n -0000389676 00000 n -0000389826 00000 n -0000389977 00000 n -0000390127 00000 n -0000390393 00000 n -0000374205 00000 n -0000373117 00000 n -0000390279 00000 n -0000390334 00000 n -0000390676 00000 n -0000390643 00000 n -0000390610 00000 n -0000390577 00000 n -0000390544 00000 n -0000390511 00000 n -0000390478 00000 n -0000390709 00000 n -0000390863 00000 n -0000391255 00000 n -0000391318 00000 n -0000391958 00000 n -0000391994 00000 n -0000392622 00000 n -0000392833 00000 n -0000393426 00000 n -0000394080 00000 n -0000408670 00000 n -0000409124 00000 n -0000421668 00000 n -0000422114 00000 n -0000423923 00000 n -0000424158 00000 n -0000442345 00000 n -0000442953 00000 n -0000451414 00000 n -0000451770 00000 n -0000454516 00000 n -0000454746 00000 n -0000456680 00000 n -0000456902 00000 n -0000458477 00000 n -0000458736 00000 n -0000474731 00000 n -0000479136 00000 n -0000479260 00000 n -0000479386 00000 n -0000479512 00000 n -0000479602 00000 n -0000479694 00000 n -0000498994 00000 n -0000499173 00000 n -0000499350 00000 n -0000499525 00000 n -0000499700 00000 n -0000499877 00000 n -0000500053 00000 n -0000500230 00000 n -0000500406 00000 n -0000500583 00000 n -0000500759 00000 n -0000500936 00000 n -0000501115 00000 n -0000501302 00000 n -0000501485 00000 n -0000501668 00000 n -0000501853 00000 n -0000502037 00000 n -0000502221 00000 n -0000502400 00000 n -0000502575 00000 n -0000502752 00000 n -0000502926 00000 n -0000503100 00000 n -0000503277 00000 n -0000503452 00000 n -0000503629 00000 n -0000503804 00000 n -0000503981 00000 n -0000504156 00000 n -0000504333 00000 n -0000504508 00000 n -0000504685 00000 n -0000504860 00000 n -0000505055 00000 n -0000505305 00000 n -0000505556 00000 n -0000505807 00000 n -0000506058 00000 n -0000506318 00000 n -0000506580 00000 n -0000506839 00000 n -0000507098 00000 n -0000507351 00000 n -0000507602 00000 n -0000507853 00000 n -0000508104 00000 n -0000508355 00000 n -0000508606 00000 n -0000508857 00000 n -0000509060 00000 n -0000509325 00000 n -0000509590 00000 n -0000509814 00000 n -0000510044 00000 n -0000510266 00000 n -0000510495 00000 n -0000510724 00000 n -0000510951 00000 n -0000511212 00000 n -0000511479 00000 n -0000511746 00000 n -0000512013 00000 n -0000512288 00000 n -0000512555 00000 n -0000512822 00000 n -0000513089 00000 n -0000513356 00000 n -0000513474 00000 n -0000513593 00000 n -0000513713 00000 n -0000513830 00000 n -0000513946 00000 n -0000514072 00000 n -0000514209 00000 n -0000514346 00000 n -0000514479 00000 n -0000514614 00000 n -0000514754 00000 n -0000514849 00000 n -0000514977 00000 n -0000515115 00000 n -0000515209 00000 n -0000515249 00000 n -0000515381 00000 n -trailer -<< /Size 1929 -/Root 1927 0 R -/Info 1928 0 R -/ID [<97AA13A313DA3EACE2EBC67A44CC1966> <97AA13A313DA3EACE2EBC67A44CC1966>] >> -startxref -515733 -%%EOF diff --git a/branches/s100/Doc/RomWBW Architecture.pdf b/branches/s100/Doc/RomWBW Architecture.pdf deleted file mode 100644 index 0491a4ad..00000000 Binary files a/branches/s100/Doc/RomWBW Architecture.pdf and /dev/null differ diff --git a/branches/s100/Doc/S100_Project_Board_List.xlsx b/branches/s100/Doc/S100_Project_Board_List.xlsx deleted file mode 100644 index daee62bf..00000000 Binary files a/branches/s100/Doc/S100_Project_Board_List.xlsx and /dev/null differ diff --git a/branches/s100/Doc/SD-howto.txt b/branches/s100/Doc/SD-howto.txt deleted file mode 100644 index 5b2b72d2..00000000 --- a/branches/s100/Doc/SD-howto.txt +++ /dev/null @@ -1,234 +0,0 @@ -Using an SD card with the RomWBW firmware. - -This document describes using the SD-card interface for the Z80-SBC, Zeta and -N8 systems with the RomWBW firmware. It does not cover the ParPortProp SD -interface. -V2.0 supports the bit-bang method as well as CSI/O port on the N8. It does not -support the original connection by Juha to the Z80-SBC MK-I. The firmware does -have support for the high capacity (HC) cards. -V2.1 supports the Mini-PPISD board for the Z80-SBC and Zeta. - -An SD-card interface uses four signal lines. A chip select, data out to the -card, clock out to the card and a data in from the card. Except for the CSIO -port interface on the N8-2312 board, all N8VEM interfaces use a bit-banging -technique. The hardware is slightly different for each and will be discussed -in turn. The configuration options are given for those who tailor their -versions of the firmware. -- Z80-SBC MK-II with SD-mini board -- Zeta with SD-mini board -- N8-2511 (prototype) -- N8-2312 (production) -- Mini-PPISD board - - ---Z80-SBC MK-II with SD-mini board-- -The Z80-SBC interface uses the latch and input port normally used for the -DS1302 RTC chip. The latch for the RTC is only 6-bits wide so we will be -doubling up on the RTC data out and clock lines. The chip select uses a spare -latch output and the data in uses the 'config' header input. -Miniboard MK II SBC Use -1 +5v -2 GND -3 U5 pin 9 Data in to SBC from card -4 U18 pin 15 Data out from SBC to card -5 N/C alternative to pin 3 -6 N/C alternative to pin 4 -7 U18 pin 12 Clock out to card -8 U18 pin 2 Chip select to card -The jumpers on the miniboard are K1 1-2, K2 1-2. -Resistor R11 must be removed. - ---Zeta with SD-mini board-- -The Zeta uses a 6-bit latch for the RTC so we will be doubling up on the RTC -data out and clock lines. The chip select uses a spare latch output and the -data in uses the 'config' header input. -First a modification to the Zeta board. The 'config' input has a 4k7 pull-up -resistor which must be removed or isolated (RTC_PLUP at pin 6 of RR1). To -isolate this resistor cut the pcb track on the underside of the PCB that goes -to pin 9 of U14 (the 74LS125). SD-cards work at 3.3v and a pull-up to 5v can -damage the card. The config header is left open. -Connections to the Zeta from the SD miniboard are: -Miniboard Zeta Use -1 +5v -2 GND -3 U14 pin 9 Data in to SBC from card -4 U11 pin 2 Data out from SBC to card -5 N/C alternative to pin 3 -6 N/C alternative to pin 4 -7 U11 pin 10 Clock out to card -8 U11 pin 7 Chip select to card -The jumpers on the SD miniboard are K1 1-2, K2 1-2. - -Testing the Zeta and Z80-SBC MK-II boards -With the miniboard connected to the Zeta BUT WITH NO SD-CARD INSTALLED do the -following. -1. Power up and check the voltages on all pins of the SD-card socket. None of -them should be over 3.3v. -2. From the monitor type ->I 70 and it should come back with something like 78 -Short out the config header to bring the data in line low, type >I 70 and it -should come back with 38 proving the data in line. -3. Test the outputs by turning them all on (except the DS1302 enable line) with ->O 70 CF -Now check all the voltages again. If they are 3.0 to 3.3v then go to the next -step. If two of them are closer to 2.0v then you are likely using a 74LS174 -instead of a 74HCT174 (or similar) for U11. To bring the outputs up enough -(3.0v) change the 2k7 resistors R4 and R8 to 560 ohms on the miniboard. -4. If you want to test the individual output lines then ->O 70 80 activates the data out line ->O 70 40 activates the clock line ->O 70 04 activates the chip select line -5. Power down, plug in the SD-card and power-up. There is no hot-swapping in -this interface. After that it should behave as the other drives. -Note that the SD-interface is SLOW and can take a few seconds to respond. -For assembly in the relative config_xxx.asm file alter the following: -SDENABLE .EQU TRUE -SDTRACE .EQU 1 -SDCAPACITY .EQU (whatever your card size is in MB) -SDCSIO .EQU FALSE (FALSE for bit-banging) -SDCSIOFAST .EQU FALSE (ignore this, only for N8 CSIO port) -PPISD .EQU FALSE - ---N8-2511 (prototype)-- -The N8-2511 board by default uses a similar bit-banging technique and interface -as the Z80 MK-II and Zeta boards. A hardware modification is needed to use the -faster CSI/O port of the Z180 CPU. - Make sure you have cut the track to or removed 4k7 pullup resistor marked -PU4.7K-H that goes to the data out of the SD-card and pin 9 of U4 (the -74LS125). It has damaged the SD-card I was initially testing as they are not -designed for 5v on any pin. Before putting any SD-card into the connector, -check all voltages and make sure they are less than 3.6v, preferably about -3.3v. You can use the monitor's 'O 88 07' command to set all outputs on. - -For assembly in the config_n8_2511.asm file alter the following: -SDENABLE .EQU TRUE -SDTRACE .EQU 1 -SDCAPACITY .EQU (whatever your card size is in MB) -SDCSIO .EQU FALSE (FALSE for bit-banging) -SDCSIOFAST .EQU FALSE (ignore this, only for CSIO port) -PPISD .EQU FALSE - ---The quick guide to modifying the SD-card interface to use the CSI/O -port on the N8-2511 board.-- - -It is assumed that you have got the standard SD-card interface running and -have a known working SD-card (though not necessary for either). - -1. Remove jumper JP-1 to disconnect SD-Data out from U4 (74LS125) - -2. Cut tracks/IC pins 18 and 19 of U11 (74LS574) to disconnect SD_CLK - and SD_DATA IN. - -3. If you are using U60 (MAX-232) for the secondary serial port RS-232 - interface, cut or bend pin 12 of U60 out of the socket. Cutting the - track between this pin and pin 56 of the cpu is not possible - with the chip sockets in place. - This will stop U60 from inhibiting the CSI/O receiver. If you are - using the RS-485 interface then you don't have to do this mod. - -4. Connect pin 55 of the CPU (TXS) to SD_DATA_IN. Easiest way is pin 3 of P49 - to R6. - -5. Connect pin 56 of the CPU (RXS) to SD_DATA_OUT. Easiest way is pin 4 of P49 - to pin 4 of RR3. - -6. Connect pin 57 of the CPU (CLK) to SD_CLK. Easist way is pin 2 of P49 to - R10. - -7. DO NOT INSTALL THE SD CARD YET. Power up the N8 and grab your voltmeter. -Looking at the SD card connector from the edge closest to the joystick headers -you should have the following voltages: -PIN VOLTAGE USE ---9 3.3v not used, pulled high --1 3.3v /CS --2 0 or 3.3v data to card (TXS) ---3 0v GND ---4 3.3v Vcc --5 3.3v CLK --6 0v GND --7 3.3v data from card (RXS) --8 3.3v not used, pulled high - -If you have >3.5v on any pin, switch off and check your wiring. - -8. I had a fault in the PCB, there was a broken track around pin 5 of the - connector. A quick continuity check between the SD connector and the CPU - at this point may save headaches later. You should read 2k7 between pin - 55 of CPU and pin 2 of SD connector, 2k7 between pin 57 of CPU and pin 5 - of SD connector, and <10 ohms between pin 56 of CPU and pin 7 of - SD connector. - -9. Power up again and check each pin's operation. -RXS: From the monitor do the following - O 4A 06 ;sets up CNTR with slowest clock speed - O 4A 26 ;receive a byte - I 4B ;read byte - the result should be $FF due to the pullup resistor in RR3. - Now clip a jumper wire from any 0v point to RXS and do the last two - commands again. The result should be $00. - -CLK: Use a logic probe or oscilloscope connected to the SD_CLK pin. - CLK is normally high and will pulse low when used. Use the - O 4A 26 to receive a byte and watch your probe/scope. - -TXS: TXS will stay at the same level as the last bit sent. If it is hi use - O 4B 00 ;send lo byte - O 4A 46 ;enable transmit - or if it is lo use - O 4B FF ;send hi byte - O 4a 46 ;enable transmit - -If everything has gone as detailed above then you should be ready to try the -firmware. -There are two extra configurations for the CSIO port in the config_n8.asm file. -SDCSIO should be set to TRUE if you are using the CSIO port. The CSIO -transfers data LSB first, the SD card uses MSB first. Each data byte has to be -mirrored (i.e. swap bits around). There are two methods used. The rotate and -shift is slow but uses very little code. The lookup table is much faster but -uses an extra 256 bytes of code space. -For assembly in the config_n8_2511.asm file alter the following: -SDENABLE .EQU TRUE -SDTRACE .EQU 1 -SDCAPACITY .EQU (whatever your card size is in MB) -SDCSIO .EQU TRUE (FALSE for bit-banging) -SDCSIOFAST .EQU TRUE (only use FALSE if memory space is tight) -PPISD .EQU FALSE - ---N8-2312 (production)-- -The production version has the CSI/O modifications already taken care of. If -there are problems then the hardware can be tested from Step 7 of the -modification guide above. NOTE: JP15 should be open. -The config_n8_2312.asm file should contain the following: -SDENABLE .EQU TRUE -SDTRACE .EQU 1 -SDCAPACITY .EQU (whatever your card size is in MB) -SDCSIO .EQU TRUE -SDCSIOFAST .EQU TRUE (only use FALSE if memory space is tight) -PPISD .EQU FALSE - ---Mini-PPISD board-- -The PPISD is an updated version of the bit-bang design. It uses the PPI port -found throughout the N8VEM range and can be used with the 6x0x mezzanine board. -It has full 5v to 3.3v level translation, can use power from the PPI connector -or an external supply and has a choice chip select inputs so two boards can be -used on the one computer. An extra header is given for daisy chaining a DSKY -board or another PPISD board. -There are only a few points to watch out for. It cannot be used with a PPIDE -or a ParPortProp board as they double up on several pins, but it can be used -with the DSKY board on the same PPI connector. The chip select line is active -LOW - opposite to the SD-mini board. -If the PPI is being used for other purposes (such as the DSKY) then the only -programming requirements are that PPI outputs PC4 and PC5 must be kept high. -There are two jumpers. K1 selects the power source. Jumper 1-2 for an -external supply (Z80-SBC MK-I or 6x0x system), or jumper 2-3 to be powered -from the PPI connector (Z80-SBC MK-II, Zeta, N8 or SBC-188). -K2 selects which card-select line to be used. 1-2 uses PC4 and is the default -for the RomWBW firmware. Jumper 2-3 to use PC5. -There is a page on the N8VEM Wiki with the latest details. -In the config_xxx.asm files make -PPISD .EQU TRUE -PPIDEENABLE .EQU FALSE - -DGG - - diff --git a/branches/s100/Doc/Source/Bank Switched Memory.vsd b/branches/s100/Doc/Source/Bank Switched Memory.vsd deleted file mode 100644 index 9d949940..00000000 Binary files a/branches/s100/Doc/Source/Bank Switched Memory.vsd and /dev/null differ diff --git a/branches/s100/Doc/Source/Character Emulation Video Services.vsd b/branches/s100/Doc/Source/Character Emulation Video Services.vsd deleted file mode 100644 index 9f01ad06..00000000 Binary files a/branches/s100/Doc/Source/Character Emulation Video Services.vsd and /dev/null differ diff --git a/branches/s100/Doc/Source/RomWBW Architecture.docx b/branches/s100/Doc/Source/RomWBW Architecture.docx deleted file mode 100644 index da14e051..00000000 Binary files a/branches/s100/Doc/Source/RomWBW Architecture.docx and /dev/null differ diff --git a/branches/s100/Doc/Z180 Clocking.txt b/branches/s100/Doc/Z180 Clocking.txt deleted file mode 100644 index 3f60b889..00000000 --- a/branches/s100/Doc/Z180 Clocking.txt +++ /dev/null @@ -1,19 +0,0 @@ -The table below can be used to determine the correct value for CLKDIV AND CNTLB -in an Z180 (N8) configuration file. OSC Freq referes to the hardware clock -oscillator frequency you are using. You can then choose a CLKDIV value which -will result in the CPU speed (frequency) shown below the oscillator frequency. - -Using your oscillator frequency (OSC) and chosen value for CLKDIV, you can -use the appropriate column to derive values to use for CNTLB for different -baud rates. - - ----- CLKDIV = 0 ----- ----- CLKDIV = 1 ----- -OSC Freq (MHz) 6.144 12.288 18.432 6.144 12.288 18.432 -CPU Freq (MHz) 3.072 6.144 9.216 6.144 12.288 18.432 - -1200 baud 04H 05H 24H 05H 06H 25H -2400 baud 03H 04H 23H 04H 05H 24H -4800 baud 02H 03H 22H 03H 04H 23H -9600 baud 01H 02H 21H 02H 03H 22H -19200 baud 00H 01H 20H 01H 02H 21H -38400 baud --- 00H --- 00H 01H 20H \ No newline at end of file diff --git a/branches/s100/Doc/ZSystem.txt b/branches/s100/Doc/ZSystem.txt deleted file mode 100644 index ff807ebf..00000000 --- a/branches/s100/Doc/ZSystem.txt +++ /dev/null @@ -1,47 +0,0 @@ -This file is a log of the work done to adapt the ZSDOS distribution to the N8VEM platforms under RomWBW. I strongly recommend reviewing the zsdos.pdf file in the Doc directory. - -The starting point was the general public release of ZSDOS that is generally available. The first line of the README file is "ZSDOS-GP. General Public Release of the ZSDOS 1.x Operating System." - -The actual ZSDOS source code was minimally modified to achieve TASM assembler compatibility. In order to minimize the number of changes to the source, I created a "wrapper" that defines a bunch of helper macros to improve compatibility. The wrapper uses a #INCLUDE to imbed the actual ZSDOS source. - -ZSDOS is really two things. ZSDOS and ZDDOS. It is the same source file, an equate determines which variation you want to build. The wrapper mentioned above can be changed to pick either one. Basically, ZSDOS has more features. ZDDOS has less features, but inlcudes date stamping code. Refer to the zsdos.pdf file for more information. I have chosen to use ZSDOS to pick up the maximum number of features. DateStamping is still available, it just uses memory outside of the OS. - -The source also allows you to compile the OS code as either v1.1 or v1.2 via an equate. This can be controled by the wrapper just like the choice of ZSDOS/ZDDOS. Version 1.2 has only a couple of small changes versus v1.1 (apparently a minor bug fix). However, there are warnings in the source that compiling the DOS as v1.2 will make it incompatible with existing overlays and applications. I encountered this myself with the date stamping code -- won't work with v1.2 because it does a version check. For now, I have chosen to use v1.1 to maximize compatibility (seems to be what everyone is doing). Ultimately, I may go back and try to rebuild everything in the distribution to bring it all up to v1.2. That is for the future though. - -As I worked through the files in the distribution, it became clear that there were problems with the distribution. For example, the .CFG files for some apps (like FILEDATE) are not acceptable to ZCNFG. Additionally, the STAMPS.DAT file contains code that simply does not work. In all of these cases, I found updated or fixed versions of the files. However, the point is that I concluded I would need to go through the distribution file-by-file and validate everything, replacing anything that was not working as needed. See the notes below for what I did. - -Beyond the construction and integration of the actual DOS itself, the majority of the work has been to update the distribution files as needed to get them all functional. Then, as appropriate, I have added application files to the ROM Disk for the ZSystem builds. - -The remainder of this document details the changes I made as I went along. In all cases, my goal was to keep the result as close to the original distribution as possible. I started by copying all of the files from the distribution (contained in zsdos2.zip) into Support\ZSDOS. From there I tested, modified, updated, and customized as documented below. Finally, I cherry picked files that made sense to include on the ZSystem ROM disks. - -1. CLOCKS.DAT has been updated to include the N8VEM clock drivers, N8VEMCLK AND N8CLK. I have also added the SIMHCLOK clock driver. - -2. STAMPS.DAT has been replaced with an updated version. The update was called STAMPS11.DAT and was found on the Walnut Creek CP/M CDROM. The original version has a bug that prevents RSX (resident system extension) mode to fail to load properly. - -3. The original LDTIMD and LDTIMP were built against ZSDOS 1.0 and refused to load under ZSDOS 1.1. Used SETUPZST to recreate LDTIMD and LDTIMP for compatibility with ZSDOS 1.1. They were built exactly the same as previously: Relative Clock driver and RSX mode loading. - -4. Updated FILEDATE.COM and FILEDATE.CFG from original v1.7 to v2.1. The FILEDATE.CFG originally supplied was invalid. - -5. Updated COPY.CFG. The original one was invalid and appeared to be for a much oder version of COPY. - -6. Updated FILEATTR to v1.6A. Original FILEATTR.CFG was invalid. FILEATTR.CFG replaced with FA16.CFG. Added associated files FA16.DOC, FA16A.FOR, FA16CFG.TXT. - - -Usage Notes ------------ - -1. ZSDOS has a concept of fast relog of drives. This means that after a warm start, it avoids the overhead of relogging all the disk drives. There are times when this causes issues. After using tools like CLRDIR or MAP, you may need to run "RELOG" to get the drive properly recognized by ZSDOS. - -2. ZSVSTAMP expects to be running under the ZCPR 3.X command processor. By default, RomWBW uses ZCPR 1.0 (intentionally, to reduce space usage) and ZSVSTAMP will just abort in this case. It will work fine if you implement NZCOM. ZSVSTAMP is included solely to facilitate usage if/when you install NZCOM. - -3. FILEDATE only works with DateStamper style date stamping. If you run it on a drive that is not initialized for DateStamper, it will complain "FILEDATE, !!!TIME&.DAT missing". This is normal and just means that you have not initialized that drive for DateStamper (using PUTDS). - -4. ZXD will handle either DateStamper or P2DOS type date stamping. However, it MUST be configured appropriately. As distributed, it will look for P2DOS date stamps. Use ZCNFG to reconfigure it for P2DOS if that is what you are using. - -4. Many of the tools can be configured (using either ZCNFG or DSCONFIG). The configuration process modifies the actual application file itself. This will fail if you try to modify one that is on the ROM disk because it will not be able to update the image. - -5. DATSWEEP can be configured using DSCONFIG. However, DSCONFIG itself needs to be configured first for proper terminal emulation by using SETTERM. So, run SETTERM on DSCONFIG before using DSCONFIG to configure DATSWEEP! - -6. After using PUTDS to initialize a directory for ZDS date stamping, I am finding that it is necessary to run RELOG before the stamping routines will actually start working. - -7. Generic CP/M PIP and ZSDOS path searching do not mix well if you use PIP to copy to or from a directory in the ZSDOS search path. Best to use COPY from the ZSDOS distribution. \ No newline at end of file diff --git a/branches/s100/Doc/flash.man b/branches/s100/Doc/flash.man deleted file mode 100644 index 3b6a35df..00000000 --- a/branches/s100/Doc/flash.man +++ /dev/null @@ -1,42 +0,0 @@ -NAME - flash - in-situ 29F040 flash ROM programmer for N8VEM, Zeta and N8 - computers. - -SYNOPSIS - flashz - flashn8 - -DESCRIPTION - The flashz and flashn8 erase and program the FLASH ROM chip from an - image file. flashz is used for the N8VEM Z80-SBC and Zeta computers. - flashn8 is used with the N8 home computer. Both function the same - except in the way memory is addressed. - - flash expects a 512k file in the same directory containing the image - that will be programmed into the ROM. This file must have the - unimaginative filename of ROM.IMG. The whole process of erasing and - programming the ROM takes less than a minute for an 8MHz Zeta - far - less than the time taken to upload your new image. - - This program is only suitable for 512k FLASH ROMs. Older chips - use 14-bit addresses of 5555h and 2AAAh for their command sequences, - newer chips use x555h and x2AAh. This program uses the older addresses - as the newer chips are backward compatible. Versions of this program - earlier than v0.6 were for newer chips only. - - Assemble with TASM using the commands - tasm -t80 -g3 flashz.asm flashz.com - tasm -t80 -g3 flashn8.asm flashn8.com - -JUMPERS - The following jumpers must be in place on the boards to allow the - 29F040 to be programmed. - For the N8VEM Z8-SBC MK-II: K1 1-2, K6 2-3, K8 2-3 - For the N8: K3 1-2, K4 2-3, K5 2-3 - For the Zeta, no jumpers need (or can) be set. - -AUTHOR - Written by David Giles so he doesn't have to open the box his Zeta - lives in so often. Reports to N8VEM group or vk5dg@internode.on.net - - diff --git a/branches/s100/FixPowerShell.cmd b/branches/s100/FixPowerShell.cmd deleted file mode 100644 index 8b66d0a5..00000000 --- a/branches/s100/FixPowerShell.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -echo Setting PowerShell ExecutionPolicy = RemoteSigned... -echo. -PowerShell Set-ExecutionPolicy RemoteSigned -echo PowerShell ExecutionPolicy is now: -PowerShell Get-ExecutionPolicy -echo. -echo The execution policy should be "RemoteSigned" -echo. -pause \ No newline at end of file diff --git a/branches/s100/LSource/Makefile b/branches/s100/LSource/Makefile deleted file mode 100644 index b588a48a..00000000 --- a/branches/s100/LSource/Makefile +++ /dev/null @@ -1,379 +0,0 @@ -# RomWBW/branches/dwg/LSource/Makefile 1/16/2013 dwg - Makefile for scientific Linux (red hat enterprise) -# RomWBW/branches/dwg/LSource/Makefile 11/09/2012 dwg - added rule to copy n8chars.minc -# RomWBW/branches/dwg/LSource/Makefile 10/27/2012 dwg - -# -# GCC based makefile -# -# 10/27/2012 2.x dwg - updated for Linux -# -# 09/28/2012 2.2 dwg - updated for Mac OS X 10.8.2 Mountain Lion -# -# 06/18/2012 2.0 dgg - updated for v2.0 -# -# 02/22/2012 1.5 dgg - modified for assembly under Linux -# -# 01/11/2011 1.4 wbw - added support for ZSDOS/ZDDOS/ZCPR -# -# 12/22/2011 1.3 wbw - removed all built-in config stuff, operation is now entirely -# dependent on variables CONFIG, ROMSIZE, and CPU -# -# 12/02/2011 1.3 wbw - replaced makever functionality with built-in makefile stuff -# -# 11/29/2011 1.3 dwg - uses makever to generate stdincl.inc from the version.hpp file -# -# 11/19/2011 1.3 dwg - added n8vem_vdu to "usage" and "all" rules -# enhanced clean to get files in $(OUTDIR) -# added custom to "all" rule - -# -# The operation of this makefile is entirely dependent on the setting -# of three variables: CONFIG, ROMSIZE, and CPU: -# -# CONFIG determines which configuration to build which means that -# it will determine the config_xxx.asm config settings file to -# include as well as the output file names. So, for example, -# if CONFIG is "n8vem", the config_n8vem.asm file will be used -# for BIOS configuration settings and the output files will be -# n8vem.rom, n8vem.sys, and n8vem.com. -# -# ROMSIZE specifies the size of the ROM image to be produced and -# currently must be either "1024" for a 1MB ROM or "512" for a -# 512KB ROM. -# -# CPU specifies the instruction set to be used in assembly and -# must be either "80" for Z80 or "180" for Z180. Currently, -# you should use 180 for N8 ROMs and 80 for everything else. -# -# SYS specifies the system variant to build in. CPM will -# build traditional CP/M. ZSYS will build ZSystem which -# currently means ZSDOS 1.2 & ZCPR 1.0 -# -# ROMNAME names the output file. It defaults to -# CONFIG. The output of the build will be: -# .rom, .sys, and .com. -# -# These variables can be passed into the makefile by the command -# line, hardcoded in this file, or set as environment variables -# in the OS. To use a command line, use the following format: -# -# make CONFIG= ROMSIZE= CPU= SYS= ROMNAME= -# -# An example of this is: -# -# make CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# Alternatively, you can specify the variables by hardcoding them -# in this file. To do so, uncomment the five lines after these -# comments and change the values as desired. -# If the variables are specified this way, you would then invoke -# the make by simply using "make" -# -# If you want to set them as environment variables, you can -# do this with commands like the following at an OS command -# prompt or in a batch file: -# -# SET CONFIG=zeta -# SET ROMSIZE=512 -# SET CPU=80 -# SET SYS=CPM -# SET ROMNAME=zeta -# -# Note: use "make clean" to delete temporary and output files -# -# A good idea is to do a clean with every build and this can be -# accomplished on one command line doing something like this: -# -# make clean all CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# or, if you are using hard coded variables above: -# -# make clean all -# -# Uncomment and update values below to hardcode settings: -# -CONFIG := n8_2312 -ROMSIZE := 512 -CPU := 180 -SYS := CPM -ROMNAME := n8_2312 - -ifndef ROMNAME -ROMNAME := $(CONFIG) -endif - -CPMCP := bin/CPMCP -CVT := bin/CVT2LINUX - -SRC := ../Source/ - -ROMDSKFILES := ../RomDsk/$(SYS)_$(ROMSIZE)KB/*.* ../RomDsk/cfg_$(CONFIG)/*.* ../Apps/core/*.* - -ifeq "$(SYS)" "CPM" -DOSBIN := bdosb01.bin -CPBIN := ccpb03.bin -else -DOSBIN :s= zsdos.bin -CPBIN := zcprw.bin -endif - -OUTDIR := ../Output - -TASM := bin/TASM -TASMTABS := bin -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -NULL := -SPACE := ${NULL} ${NULL} - -%.bin: %.asm - $(ASM80) $< $@ - -%.com: %.asm - $(ASM80) $< $@ - -%.img: %.asm - $(ASMIMG) $< $@ - -%.exe: %.cpp - $(CC) $< -o $@ - -ifneq ($(MAKECMDGOALS),clean) -ifeq "$(and $(CONFIG), $(ROMSIZE), $(CPU), $(SYS), $(ROMNAME))" "" -$(error sage: make CONFIG= ROMSIZE=[512|1024] CPU=[80|180] SYS=[CPM|ZSYS] ROMNAME=) -endif -endif - -all: tasm80.tab tasm85.tab $(OUTDIR)/$(ROMNAME).rom $(OUTDIR)/$(ROMNAME).sys $(OUTDIR)/$(ROMNAME).com - -tasm80.tab: bin/TASM80.TAB - cp bin/TASM80.TAB tasm80.tab - -tasm85.tab: bin/TASM85.TAB - cp bin/TASM85.TAB tasm85.tab - - -build.inc: - /bin/echo ';' >$@ - /bin/echo -n '; RomWBW Configured for '$(CONFIG)' ' >>$@ - date >> $@ - /bin/echo ; >>$@ - /bin/echo -n '#DEFINE TIMESTAMP "' >>$@ - date '+%Y %m %d %H%M"' >>$@ - /bin/echo ; >>$@ - /bin/echo '#DEFINE VARIANT "WBW-$(USERNAME)"' >>$@ - /bin/echo ; >>$@ - /bin/echo ROMSIZE .EQU $(ROMSIZE) >>$@ - /bin/echo ; >>$@ - /bin/echo '#INCLUDE "config_'$(CONFIG)'.asm"' >>$@ - /bin/echo ; >>$@ - -bootrom.bin : bootrom.asm std.asm build.inc ver.inc memmgr.asm config_$(CONFIG).asm xio.asm - $(TASM) $(ASMOPT80) $< $@ - -bootapp.bin: bootapp.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -pgzero.bin: pgzero.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -zcprw.bin: zcprw.asm zcpr.asm - $(TASM) $(ASMOPT85) $< $@ - -zsdos.bin: zsdos.asm zsdos.lib zsdos-gp.z80 - $(TASM) $(ASMOPT80) $< $@ - -cbios.bin: cbios.asm fd_data.asm ide_data.asm ppide_data.asm sd_data.asm prp_data.asm ppp_data.asm uart.asm vdu.asm std.asm ver.inc build.inc infolist.inc - $(TASM) $(ASMOPT80) -dBLD_SYS=SYS_$(SYS) $< $@ - -dbgmon.bin: dbgmon.asm std.asm ver.inc build.inc - -syscfg.bin: syscfg.asm std.asm build.inc ver.inc - -os.bin: $(CPBIN) $(DOSBIN) cbios.bin - cat $(CPBIN) $(DOSBIN) cbios.bin >>$@ - -rom0.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin >>$@ - -rom1.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin >>$@ - -$(OUTDIR)/$(ROMNAME).rom: rom0.bin rom1.bin $(ROMDISKFILES) $(OUTDIR)/$(ROMNAME).sys diskdefs - cp $(SRC)blank$(ROMSIZE)KB.dat RomDisk.tmp - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp $(ROMDSKFILES) 0: - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp ../Output/$(ROMNAME).sys 0:$(SYS).sys - cat rom0.bin rom1.bin RomDisk.tmp >>$@ - -$(OUTDIR)/$(ROMNAME).com: bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin - cat bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin >>$@ - -$(OUTDIR)/$(ROMNAME).sys: prefix.bin os.bin - cat prefix.bin os.bin >>$@ - -ansi.asm: $(SRC)ansi.asm - cp $< $@ - $(CVT) $@ - -bdosb01.asm: $(SRC)bdosb01.asm - cp $< $@ - $(CVT) $@ - -hbios.asm: $(SRC)hbios.asm fd.asm ppide.asm n8v.asm n8chars.inc ppk.asm sd.asm tty.asm ansi.asm - cp $(SRC)hbios.asm $@ - $(CVT) $@ - -bootapp.asm: $(SRC)bootapp.asm - cp $< $@ - $(CVT) $@ - -bootrom.asm: $(SRC)bootrom.asm - cp $< $@ - $(CVT) $@ - -cbios.asm: $(SRC)cbios.asm - cp $< $@ - $(CVT) $@ - -ccpb03.asm: $(SRC)ccpb03.asm - cp $< $@ - $(CVT) $@ - -cnfgdata.inc: $(SRC)cnfgdata.inc - cp $< $@ - $(CVT) $@ - -##config_zeta.asm: $(SRC)config_zeta.asm -## cp $< $@ -## $(CVT) $@ - -config_$(CONFIG).asm: $(SRC)config_$(CONFIG).asm - cp $< $@ - $(CVT) $@ - -dbgmon.asm: $(SRC)dbgmon.asm - cp $< $@ - $(CVT) $@ - -diskdefs: $(SRC)diskdefs - cp $< $@ - $(CVT) $@ - -fd.asm: $(SRC)fd.asm - cp $< $@ - $(CVT) $@ - -fd_data.asm: $(SRC)fd_data.asm - cp $< $@ - $(CVT) $@ - -hbfill.asm: $(SRC)hbfill.asm - cp $< $@ - $(CVT) $@ - -ide_data.asm: $(SRC)ide_data.asm - cp $< $@ - $(CVT) $@ - -infolist.inc: $(SRC)infolist.inc - cp $< $@ - $(CVT) $@ - -loader.asm: $(SRC)loader.asm util.asm - cp $(SRC)loader.asm $@ - $(CVT) $@ - -memmgr.asm: $(SRC)memmgr.asm - cp $< $@ - $(CVT) $@ - -n8chars.inc: $(SRC)n8chars.inc - cp $< $@ - $(CVT) $@ - -n8v.asm: $(SRC)n8v.asm - cp $< $@ - $(CVT) $@ - -pgzero.asm: $(SRC)pgzero.asm - cp $< $@ - $(CVT) $@ - -ppide.asm: $(SRC)ppide.asm - cp $< $@ - $(CVT) $@ - -ppide_data.asm: $(SRC)ppide_data.asm - cp $< $@ - $(CVT) $@ - -ppk.asm: $(SRC)ppk.asm - cp $< $@ - $(CVT) $@ - -ppp_data.asm: $(SRC)ppp_data.asm - cp $< $@ - $(CVT) $@ - -prefix.asm: $(SRC)prefix.asm - cp $< $@ - $(CVT) $@ - -prp_data.asm: $(SRC)prp_data.asm - cp $< $@ - $(CVT) $@ - -romfill.asm: $(SRC)romfill.asm - cp $< $@ - $(CVT) $@ - -sd.asm: $(SRC)sd.asm - cp $< $@ - $(CVT) $@ - -sd_data.asm: $(SRC)sd_data.asm - cp $< $@ - $(CVT) $@ - -std.asm: $(SRC)std.asm - cp $< $@ - $(CVT) $@ - -syscfg.asm: $(SRC)syscfg.asm config_$(CONFIG).asm cnfgdata.inc - cp $< $@ - $(CVT) $@ - -tty.asm: $(SRC)tty.asm - cp $< $@ - $(CVT) $@ - -uart.asm: $(SRC)uart.asm - cp $< $@ - $(CVT) $@ - -util.asm: $(SRC)util.asm - cp $< $@ - $(CVT) $@ - -vdu.asm: $(SRC)vdu.asm - cp $< $@ - $(CVT) $@ - -ver.inc: $(SRC)ver.inc - cp $< $@ - $(CVT) $@ - -xio.asm: $(SRC)xio.asm - cp $< $@ - $(CVT) $@ - -clean: - rm -f *.tab *.TAB *.inc *.asm *.bin *.com *.img *.rom *.lst *.exp *.tmp - rm -f build.inc diskdefs - rm -f $(OUTDIR)/*.* diff --git a/branches/s100/LSource/bin/CPMCHATTR b/branches/s100/LSource/bin/CPMCHATTR deleted file mode 100755 index adf84bb4..00000000 Binary files a/branches/s100/LSource/bin/CPMCHATTR and /dev/null differ diff --git a/branches/s100/LSource/bin/CPMCHMOD b/branches/s100/LSource/bin/CPMCHMOD deleted file mode 100755 index 2f89a4b0..00000000 Binary files a/branches/s100/LSource/bin/CPMCHMOD and /dev/null differ diff --git a/branches/s100/LSource/bin/CPMCP b/branches/s100/LSource/bin/CPMCP deleted file mode 100755 index b74af05a..00000000 Binary files a/branches/s100/LSource/bin/CPMCP and /dev/null differ diff --git a/branches/s100/LSource/bin/CPMLS b/branches/s100/LSource/bin/CPMLS deleted file mode 100755 index ff570616..00000000 Binary files a/branches/s100/LSource/bin/CPMLS and /dev/null differ diff --git a/branches/s100/LSource/bin/CPMRM b/branches/s100/LSource/bin/CPMRM deleted file mode 100755 index 589392e4..00000000 Binary files a/branches/s100/LSource/bin/CPMRM and /dev/null differ diff --git a/branches/s100/LSource/bin/CVT2LINUX b/branches/s100/LSource/bin/CVT2LINUX deleted file mode 100755 index f5592e6a..00000000 Binary files a/branches/s100/LSource/bin/CVT2LINUX and /dev/null differ diff --git a/branches/s100/LSource/bin/TASM b/branches/s100/LSource/bin/TASM deleted file mode 100755 index 2f7ef33e..00000000 Binary files a/branches/s100/LSource/bin/TASM and /dev/null differ diff --git a/branches/s100/LSource/bin/TASM05.TAB b/branches/s100/LSource/bin/TASM05.TAB deleted file mode 100644 index 1072d3dc..00000000 --- a/branches/s100/LSource/bin/TASM05.TAB +++ /dev/null @@ -1,215 +0,0 @@ -"TASM 6805 Assembler. " -/*************************************************************************** -/* $Id -/*************************************************************************** -/* This is the instruction set definition table for the 6805 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, April 1988. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC #* A9 2 NOP 1 -ADC ,X F9 1 NOP 1 -ADC *,X D9 3 MZERO 1 -ADC * C9 3 MZERO 1 - -ADD #* AB 2 NOP 1 -ADD ,X FB 1 NOP 1 -ADD *,X DB 3 MZERO 1 -ADD * CB 3 MZERO 1 - -AND #* A4 2 NOP 1 -AND ,X F4 1 NOP 1 -AND *,X D4 3 MZERO 1 -AND * C4 3 MZERO 1 - -ASLA "" 48 1 NOP 1 -ASLX "" 58 1 NOP 1 -ASL ,X 78 1 NOP 1 -ASL *,X 68 2 NOP 1 -ASL * 38 2 NOP 1 - -ASRA "" 47 1 NOP 1 -ASRX "" 57 1 NOP 1 -ASR ,X 77 1 NOP 1 -ASR *,X 67 2 NOP 1 -ASR * 37 2 NOP 1 - -BCC * 24 2 R1 1 -BCLR *,* 11 2 MBIT 1 -BCS * 25 2 R1 1 -BEQ * 27 2 R1 1 -BHCC * 28 2 R1 1 -BHCS * 29 2 R1 1 -BHI * 22 2 R1 1 -BHS * 24 2 R1 1 -BIH * 2F 2 R1 1 -BIL * 2E 2 R1 1 - -BIT #* A5 2 NOP 1 -BIT ,X F5 1 NOP 1 -BIT *,X D5 3 MZERO 1 -BIT * C5 3 MZERO 1 - -BLO * 25 2 R1 1 -BLS * 23 2 R1 1 -BMC * 2C 2 R1 1 -BMI * 2B 2 R1 1 -BMS * 2D 2 R1 1 -BNE * 26 2 R1 1 -BPL * 2A 2 R1 1 -BRA * 20 2 R1 1 - -BRCLR *,*,* 01 3 MBIT 1 -BRN * 21 2 R1 1 -BRSET *,*,* 00 3 MBIT 1 -BSET *,* 10 2 MBIT 1 -BSR * AD 2 R1 1 - -CLC "" 98 1 NOP 1 -CLI "" 9A 1 NOP 1 - -CLRA "" 4F 1 NOP 1 -CLRX "" 5F 1 NOP 1 -CLR ,X 7F 1 NOP 1 -CLR *,X 6F 2 NOP 1 -CLR * 3F 2 NOP 1 - -CMP #* A1 2 NOP 1 -CMP ,X F1 1 NOP 1 -CMP *,X D1 3 MZERO 1 -CMP * C1 3 MZERO 1 - -CMPX #* A3 2 NOP 1 /* equivalent to CPX */ -CMPX ,X F3 1 NOP 1 -CMPX *,X D3 3 MZERO 1 -CMPX * C3 3 MZERO 1 - -COMA "" 43 1 NOP 1 -COMX "" 53 1 NOP 1 -COM ,X 73 1 NOP 1 -COM *,X 63 2 NOP 1 -COM * 33 2 NOP 1 - -CPX #* A3 2 NOP 1 -CPX ,X F3 1 NOP 1 -CPX *,X D3 3 MZERO 1 -CPX * C3 3 MZERO 1 - -DECA "" 4A 1 NOP 1 -DECX "" 5A 1 NOP 1 -DEX "" 5A 1 NOP 1 -DEC ,X 7A 1 NOP 1 -DEC *,X 6A 2 NOP 1 -DEC * 3A 2 NOP 1 - -EOR #* A8 2 NOP 1 -EOR ,X F8 1 NOP 1 -EOR *,X D8 3 MZERO 1 -EOR * C8 3 MZERO 1 - -INCA "" 4C 1 NOP 1 -INCX "" 5C 1 NOP 1 -INX "" 5C 1 NOP 1 -INC ,X 7C 1 NOP 1 -INC *,X 6C 2 NOP 1 -INC * 3C 2 NOP 1 - -JMP ,X FC 1 NOP 1 -JMP *,X DC 3 MZERO 1 -JMP * CC 3 MZERO 1 - -JSR ,X FD 1 NOP 1 -JSR *,X DD 3 MZERO 1 -JSR * CD 3 MZERO 1 - -LDA #* A6 2 NOP 1 -LDA ,X F6 1 NOP 1 -LDA *,X D6 3 MZERO 1 -LDA * C6 3 MZERO 1 - -LDX #* AE 2 NOP 1 -LDX ,X FE 1 NOP 1 -LDX *,X DE 3 MZERO 1 -LDX * CE 3 MZERO 1 - -LSLA "" 48 1 NOP 1 -LSLX "" 58 1 NOP 1 -LSL ,X 78 1 NOP 1 -LSL *,X 68 2 NOP 1 -LSL * 38 2 NOP 1 - -LSRA "" 44 1 NOP 1 -LSRX "" 54 1 NOP 1 -LSR ,X 74 1 NOP 1 -LSR *,X 64 2 NOP 1 -LSR * 34 2 NOP 1 - -MUL "" 42 1 NOP 4 /* HC05C4 only */ - -NEGA "" 40 1 NOP 1 -NEGX "" 50 1 NOP 1 -NEG ,X 70 1 NOP 1 -NEG *,X 60 2 NOP 1 -NEG * 30 2 NOP 1 - -NOP "" 9D 1 NOP 1 - -ORA #* AA 2 NOP 1 -ORA ,X FA 1 NOP 1 -ORA *,X DA 3 MZERO 1 -ORA * CA 3 MZERO 1 - -ROLA "" 49 1 NOP 1 -ROLX "" 59 1 NOP 1 -ROL ,X 79 1 NOP 1 -ROL *,X 69 2 NOP 1 -ROL * 39 2 NOP 1 - -RORA "" 46 1 NOP 1 -RORX "" 56 1 NOP 1 -ROR ,X 76 1 NOP 1 -ROR *,X 66 2 NOP 1 -ROR * 36 2 NOP 1 - -RSP "" 9C 1 NOP 1 -RTI "" 80 1 NOP 1 -RTS "" 81 1 NOP 1 - -SBC #* A2 2 NOP 1 -SBC ,X F2 1 NOP 1 -SBC *,X D2 3 MZERO 1 -SBC * C2 3 MZERO 1 - -SEC "" 99 1 NOP 1 -SEI "" 9B 1 NOP 1 - -STA ,X F7 1 NOP 1 -STA *,X D7 3 MZERO 1 -STA * C7 3 MZERO 1 - -STOP "" 8E 1 NOP 2 /* M146805 CMOS only */ - -STX ,X FF 1 NOP 1 -STX *,X DF 3 MZERO 1 -STX * CF 3 MZERO 1 - -SUB #* A0 2 NOP 1 -SUB ,X F0 1 NOP 1 -SUB *,X D0 3 MZERO 1 -SUB * C0 3 MZERO 1 - -SWI "" 83 1 NOP 1 - -TAX "" 97 1 NOP 1 - -TSTA "" 4D 1 NOP 1 -TSTX "" 5D 1 NOP 1 -TST ,X 7D 1 NOP 1 -TST *,X 6D 2 NOP 1 -TST * 3D 2 NOP 1 - -TXA "" 9F 1 NOP 1 - -WAIT "" 8F 1 NOP 2 /* M146805 CMOS only */ - diff --git a/branches/s100/LSource/bin/TASM3210.TAB b/branches/s100/LSource/bin/TASM3210.TAB deleted file mode 100644 index d5aed946..00000000 --- a/branches/s100/LSource/bin/TASM3210.TAB +++ /dev/null @@ -1,205 +0,0 @@ -"TASM TMS32010 Assembler." -/**************************************************************************** -/* $Id: tasm3210.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the TMS32010 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK */ -/*-------------------------------------------*/ - -/* Generate opcodes high byte first */ -.MSFIRST -/* Don't use '*' as the wild card since it is used for indirect addressing */ -/* In this table '@' is the wild card indicating where expression may appear*/ -.ALTWILD -/* Use word addressing (not byte addressing) -.WORDADDRS -/* All shift/and stuff applies to opcodes, not args -.NOARGSHIFT - -.REGSET *+ A0 1 -.REGSET *- 90 1 -.REGSET * 80 1 - -ABS "" 7F88 2 NOP 1 - -ADD !,@,@ 0000 2 T1 1 8 0F00 -ADD !,@ 0008 2 T1 1 8 0F00 -ADD ! 0008 2 NOP 1 -ADD @,@ 0000 2 TDMA 1 8 0F00 -ADD @ 0000 2 T1 1 0 007F - -ADDH !,@ 6000 2 T1 1 0 01 -ADDH ! 6008 2 NOP 1 -ADDH @ 6000 2 T1 1 0 007F - -ADDS !,@ 6100 2 T1 1 0 01 -ADDS ! 6108 2 NOP 1 -ADDS @ 6100 2 T1 1 0 007F - -AND !,@ 7900 2 T1 1 0 01 -AND ! 7908 2 NOP 1 -AND @ 7900 2 T1 1 0 7F - -APAC "" 7F8F 2 NOP 1 -B @ F900 4 SWAP 1 -BANZ @ F400 4 SWAP 1 -BGEZ @ FD00 4 SWAP 1 -BGZ @ FC00 4 SWAP 1 -BIOZ @ F600 4 SWAP 1 -BLEZ @ FB00 4 SWAP 1 -BLZ @ FA00 4 SWAP 1 -BNZ @ FE00 4 SWAP 1 -BV @ F500 4 SWAP 1 -BZ @ FF00 4 SWAP 1 -CALA "" 7F8C 2 NOP 1 -CALL @ F800 4 SWAP 1 -DINT "" 7F81 2 NOP 1 - -DMOV !,@ 6900 2 T1 1 0 01 -DMOV ! 6908 2 NOP 1 -DMOV @ 6900 2 T1 1 0 007F - -EINT "" 7F82 2 NOP 1 - -IN !,@,@ 4000 2 T1 1 8 0700 -IN !,@ 4008 2 T1 1 8 0700 -IN @,@ 4000 2 TDMA 1 8 0700 - -LAC !,@,@ 2000 2 T1 1 8 0F00 -LAC !,@ 2008 2 T1 1 8 0F00 -LAC ! 2008 2 NOP 1 -LAC @,@ 2000 2 TDMA 1 8 0F00 -LAC @ 2000 2 T1 1 0 007F - -LACK @ 7E00 2 T1 1 0 00FF - -LAR @,!,@ 3800 2 TAR 1 0 0001 -LAR @,! 3808 2 TAR 1 0 0001 -LAR @,@ 3800 2 TAR 1 0 007F - -LARK @,@ 7000 2 TAR 1 0 00FF -LARP @ 6880 2 T1 1 0 0001 - -LDP !,@ 6F00 2 T1 1 0 01 -LDP ! 6F08 2 NOP 1 -LDP @ 6F00 2 T1 1 0 007F - -LDPK @ 6E00 2 T1 1 0 01 - -LST !,@ 7B00 2 T1 1 0 01 -LST ! 7B08 2 NOP 1 -LST @ 7B00 2 T1 1 0 007F - -LT !,@ 6A00 2 T1 1 0 01 -LT ! 6A08 2 NOP 1 -LT @ 6A00 2 T1 1 0 007F - -LTA !,@ 6C00 2 T1 1 0 01 -LTA ! 6C08 2 NOP 1 -LTA @ 6C00 2 T1 1 0 007F - -LTD !,@ 6B00 2 T1 1 0 01 -LTD ! 6B08 2 NOP 1 -LTD @ 6B00 2 T1 1 0 007F - -MAR !,@ 6800 2 T1 1 0 01 -MAR ! 6808 2 NOP 1 -MAR @ 6800 2 T1 1 0 007F - -MPY !,@ 6D00 2 T1 1 0 01 -MPY ! 6D08 2 NOP 1 -MPY @ 6D00 2 T1 1 0 007F - -MPYK @ 8000 2 T1 1 0 1FFF - -NOP "" 7F80 2 NOP 1 - -OR !,@ 7A00 2 T1 1 0 01 -OR ! 7A08 2 NOP 1 -OR @ 7A00 2 T1 1 0 007F - -OUT !,@,@ 4800 2 T1 1 8 0700 -OUT !,@ 4808 2 T1 1 8 0700 -OUT @,@ 4800 2 TDMA 1 8 0700 - -PAC "" 7F8E 2 NOP 1 -POP "" 7F9D 2 NOP 1 -PUSH "" 7F9C 2 NOP 1 -RET "" 7F8D 2 NOP 1 -ROVM "" 7F8A 2 NOP 1 - -/* shift count for SACH can only be 0,1, or 4. The mask allows */ -/* 0,1,4, or 5. Let the user beware */ -SACH !,@,@ 5800 2 T1 1 8 0500 -SACH !,@ 5808 2 T1 1 8 0500 -SACH ! 5808 2 NOP 1 -SACH @,@ 5800 2 TDMA 1 8 0500 -SACH @ 5800 2 T1 1 0 007F - -/* The data book shows a shift field for SACL but states it must be 0. -/* The previous version of this table left the shift field out -/* for simplicity, but here I have put it back for compatibility. -/* The AND mask is set to zero in this case so a error message -/* will result from non-zero shifts. -SACL !,@,@ 5000 2 T1 1 8 0000 -SACL !,@ 5008 2 T1 1 8 0000 -SACL ! 5008 2 NOP 1 -SACL @,@ 5000 2 TDMA 1 8 0000 -SACL @ 5000 2 T1 1 0 007F - -SAR @,!,@ 3000 2 TAR 1 0 0001 -SAR @,! 3008 2 TAR 1 0 0001 -SAR @,@ 3000 2 TAR 1 0 007F - -SOVM "" 7F8B 2 NOP 1 -SPAC "" 7F90 2 NOP 1 - -SST !,@ 7C00 2 T1 1 0 0001 -SST ! 7C08 2 NOP 1 -SST @ 7C00 2 T1 1 0 007F - -SUB !,@,@ 1000 2 T1 1 8 0F00 -SUB !,@ 1008 2 T1 1 8 0F00 -SUB ! 1008 2 NOP 1 -SUB @,@ 1000 2 TDMA 1 8 0F00 -SUB @ 1000 2 T1 1 0 007F - -SUBC !,@ 6400 2 T1 1 0 01 -SUBC ! 6408 2 NOP 1 -SUBC @ 6400 2 T1 1 0 007F - -SUBH !,@ 6200 2 T1 1 0 01 -SUBH ! 6208 2 NOP 1 -SUBH @ 6200 2 T1 1 0 007F - -SUBS !,@ 6300 2 T1 1 0 01 -SUBS ! 6308 2 NOP 1 -SUBS @ 6300 2 T1 1 0 007F - -TBLR !,@ 6700 2 T1 1 0 01 -TBLR ! 6708 2 NOP 1 -TBLR @ 6700 2 T1 1 0 007F - -TBLW !,@ 7D00 2 T1 1 0 01 -TBLW ! 7D08 2 NOP 1 -TBLW @ 7D00 2 T1 1 0 007F - -XOR !,@ 7800 2 T1 1 0 01 -XOR ! 7808 2 NOP 1 -XOR @ 7800 2 T1 1 0 007F - -ZAC "" 7F89 2 NOP 1 - -ZALH !,@ 6500 2 T1 1 0 01 -ZALH ! 6508 2 NOP 1 -ZALH @ 6500 2 T1 1 0 007F - -ZALS !,@ 6600 2 T1 1 0 01 -ZALS ! 6608 2 NOP 1 -ZALS @ 6600 2 T1 1 0 007F - diff --git a/branches/s100/LSource/bin/TASM3225.TAB b/branches/s100/LSource/bin/TASM3225.TAB deleted file mode 100644 index 30dcd4c8..00000000 --- a/branches/s100/LSource/bin/TASM3225.TAB +++ /dev/null @@ -1,456 +0,0 @@ -"TASM TMS32025 Assembler." -/**************************************************************************** -/* $Id: tasm3225.tab 1.2 1997/09/28 22:16:44 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the TMS32025 version of TASM. -/* Bob Stricklin -/* -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK */ -/*-------------------------------------------*/ - -/* Generate opcodes high byte first */ -.MSFIRST -/* Don't use '*' as the wild card since it is used for indirect addressing */ -/* In this table '@' is the wild card indicating where expression may appear*/ -.ALTWILD -.WORDADDRS -.NOARGSHIFT - -/* Addressing mode definitions. -/* Value gets OR'd in to the opcode if the -/* addressing mode is recognized -/* Note: no special classes are defined, so if this -/* table is used for TMS32020, invalid instructions -/* will not result in errors (no BR0+/- addressing mode (for example) -/* The ! character can match any of the patterns in the REGSET: -.REGSET *BR0+ F0 1 -.REGSET *BR0- C0 1 -.REGSET *0+ E0 1 -.REGSET *0- D0 1 -.REGSET *+ A0 1 -.REGSET *- 90 1 -.REGSET * 80 1 - - - - -ABS "" CE1B 2 NOP 1 - -ADD !,@,@ 0088 2 T1 1 8 0F00 -ADD !,@ 0080 2 T1 1 8 0F00 -ADD ! 0080 2 NOP 1 -ADD @,@ 0000 2 TDMA 1 8 0F00 -ADD @ 0000 2 T1 1 0 007F - -ADDC !,@ 4388 2 T1 1 0 0007 -ADDC ! 4380 2 NOP 1 -ADDC @ 4300 2 T1 1 0 007F - -ADDH !,@ 4888 2 T1 1 0 0007 -ADDH ! 4880 2 NOP 1 -ADDH @ 4800 2 T1 1 0 007F - -ADDK @ CC00 2 T1 1 0 00FF ;8 bit constant - -ADDS !,@ 4988 2 T1 1 0 0007 -ADDS ! 4980 2 NOP 1 -ADDS @ 4900 2 T1 1 0 007F - -ADDT !,@ 4A88 2 T1 1 0 0007 -ADDT ! 4A80 2 NOP 1 -ADDT @ 4A00 2 T1 1 0 007F - -ADLK @,@ D002 4 TLK 1 8 0F00 -ADLK @ D002 4 TLK 1 - -ADRK @ 7E00 2 T1 1 0 00FF ;8 bit constant - -AND !,@ 4E88 2 T1 1 0 0007 -AND ! 4E80 2 NOP 1 -AND @ 4E00 2 T1 1 0 007F - -ANDK @,@ D004 4 TLK 1 8 0F00 -ANDK @ D004 4 TLK 1 - -APAC "" CE15 2 NOP 1 - -B @,!,@ FF88 4 TLK 1 0 07 -B @,! FF80 4 SWAP 1 -B @ FF80 4 SWAP 1 - -BACC "" CE25 2 NOP 1 - -BANZ @,!,@ FB88 4 TLK 1 0 07 -BANZ @,! FB80 4 SWAP 1 -BANZ @ FB90 4 SWAP 1 ; Default to the equivalent of - ; BANZ loop,*- (as per spec) for - ; TMS32010 compatibility. - -BBNZ @,!,@ F988 4 TLK 1 0 07 -BBNZ @,! F980 4 SWAP 1 -BBNZ @ F980 4 SWAP 1 - -BBZ @,!,@ F888 4 TLK 1 0 07 -BBZ @,! F880 4 SWAP 1 -BBZ @ F880 4 SWAP 1 - -BC @,!,@ 5E88 4 TLK 1 0 07 -BC @,! 5E80 4 SWAP 1 -BC @ 5E80 4 SWAP 1 - -BGEZ @,!,@ F488 4 TLK 1 0 07 -BGEZ @,! F480 4 SWAP 1 -BGEZ @ F480 4 SWAP 1 - -BGZ @,!,@ F188 4 TLK 1 0 07 -BGZ @,! F180 4 SWAP 1 -BGZ @ F180 4 SWAP 1 - -BIOZ @,!,@ FA88 4 TLK 1 0 07 -BIOZ @,! FA80 4 SWAP 1 -BIOZ @ FA80 4 SWAP 1 - -BIT !,@,@ 9088 2 T1 1 8 0F00 ;8 bit shift -BIT !,@ 9080 2 T1 1 8 0F00 -BIT @,@ 9000 2 TDMA 1 8 0F00 - -BITT !,@ 5788 2 T1 1 0 07 -BITT ! 5780 2 T1 1 -BITT @ 5700 2 T1 1 0 7F - -BLEZ @,!,@ F288 4 TLK 1 0 07 -BLEZ @,! F280 4 SWAP 1 -BLEZ @ F280 4 SWAP 1 - -BLKD @,!,@ FD88 4 TLK 1 0 07 -BLKD @,! FD80 4 TLK 1 0 07 -BLKD @,@ FD00 4 TLK 1 0 FF - -BLKP @,!,@ FC88 4 TLK 1 0 07 -BLKP @,! FC80 4 TLK 1 0 07 -BLKP @,@ FC00 4 TLK 1 0 FF - -BLZ @,!,@ F388 4 TLK 1 0 07 -BLZ @,! F380 4 SWAP 1 -BLZ @ F380 4 SWAP 1 - -BNC @,!,@ 5F88 4 TLK 1 0 07 -BNC @,! 5F80 4 SWAP 1 -BNC @ 5F80 4 SWAP 1 - -BNV @,!,@ F788 4 TLK 1 0 07 -BNV @,! F780 4 SWAP 1 -BNV @ F780 4 SWAP 1 - -BNZ @,!,@ F588 4 TLK 1 0 07 -BNZ @,! F580 4 SWAP 1 -BNZ @ F580 4 SWAP 1 - -BV @,!,@ F088 4 TLK 1 0 07 -BV @,! F080 4 SWAP 1 -BV @ F080 4 SWAP 1 - -BZ @,!,@ F688 4 TLK 1 0 07 -BZ @,! F680 4 SWAP 1 -BZ @ F680 4 SWAP 1 - -CALA "" CE24 2 NOP 1 - -CALL @,!,@ FE88 4 TLK 1 0 07 -CALL @,! FE80 4 SWAP 1 -CALL @ FE80 4 SWAP 1 - -CMPL "" CE27 2 NOP 1 - -CMPR @ CE50 2 T1 1 0 03 ;2 BIT CONTANT - -CNFD "" CE04 2 NOP 1 - -CNFP "" CE05 2 NOP 1 - -CONF "" CE3C 2 T1 4 0 03 ; c26 ONLY - -DINT "" CE01 2 NOP 1 - -DMOV !,@ 5688 2 T1 1 0 07 -DMOV ! 5680 2 NOP 1 -DMOV @ 5600 2 T1 1 0 007F - -EINT "" CE00 2 NOP 1 - -FORT @ CE0E 2 T1 1 0 01 - -IDLE "" CE1F 2 NOP 1 - -IN !,@,@ 8088 2 T1 1 8 0F00 -IN !,@ 8080 2 T1 1 8 0F00 -IN @,@ 8000 2 TDMA 1 8 0F00 - -LAC !,@,@ 2088 2 T1 1 8 0F00 -LAC !,@ 2080 2 T1 1 8 0F00 -LAC ! 2080 2 NOP 1 -LAC @,@ 2000 2 TDMA 1 8 0F00 -LAC @ 2000 2 T1 1 0 007F - -LACK @ CA00 2 T1 1 0 00FF ;tested for -25 - -LACT !,@ 4288 2 T1 1 0 07 -LACT ! 4280 2 NOP 1 -LACT @ 4200 2 T1 1 0 007F - -LALK @,@ D001 4 TLK 1 8 0F00 -LALK @ D001 4 TLK 1 - -LAR @,!,@ 3088 2 TAR 1 0 07 -LAR @,! 3080 2 TAR 1 0 07 -LAR @,@ 3000 2 TAR 1 0 7F - -LARK @,@ C000 2 TAR 1 0 00FF -LARP @ 5588 2 T1 1 0 0007 - -LDP !,@ 5288 2 T1 1 0 07 -LDP ! 5280 2 NOP 1 -LDP @ 5200 2 T1 1 0 007F - -LDPK @ C800 2 T1 1 0 01FF ;9 bit constant - -LPH !,@ 5388 2 T1 1 0 07 -LPH ! 5380 2 NOP 1 -LPH @ 5300 2 T1 1 0 7F - -LRLK @,@ D000 4 T5 1 8 0700 ;, - -LST !,@ 5088 2 T1 1 0 07 -LST ! 5080 2 NOP 1 -LST @ 5000 2 T1 1 0 7F - -LST1 !,@ 5188 2 T1 1 0 07 -LST1 ! 5180 2 NOP 1 -LST1 @ 5100 2 T1 1 0 7F - -LT !,@ 3C88 2 T1 1 0 07 -LT ! 3C80 2 NOP 1 -LT @ 3C00 2 T1 1 0 7F - -LTA !,@ 3D88 2 T1 1 0 07 -LTA ! 3D80 2 NOP 1 -LTA @ 3D00 2 T1 1 0 7F - -LTD !,@ 3F88 2 T1 1 0 07 -LTD ! 3F80 2 NOP 1 -LTD @ 3F00 2 T1 1 0 7F - -LTP !,@ 3E88 2 T1 1 0 07 -LTP ! 3E80 2 NOP 1 -LTP @ 3E00 2 T1 1 0 7F - -LTS !,@ 5B88 2 T1 1 0 07 -LTS ! 5B80 2 NOP 1 -LTS @ 5B00 2 T1 1 0 7F - -MAC @,!,@ 5D88 4 TLK 1 0 07 -MAC @,! 5D80 4 TLK 1 0 07 -MAC @,@ 5D00 4 TLK 1 0 7F - -MACD @,!,@ 5C88 4 TLK 1 0 07 -MACD @,! 5C80 4 TLK 1 0 07 -MACD @,@ 5C00 4 TLK 1 0 7F - -MAR !,@ 5588 2 T1 1 0 07 -MAR ! 5580 2 NOP 1 -MAR @ 5500 2 T1 1 0 7F - -MPY !,@ 3888 2 T1 1 0 07 -MPY ! 3880 2 NOP 1 -MPY @ 3800 2 T1 1 0 7F - -MPYA !,@ 3A88 2 T1 1 0 07 -MPYA ! 3A80 2 NOP 1 -MPYA @ 3A00 2 T1 1 0 7F - -MPYK @ A000 2 T1 1 0 1FFF ;13 BIT CONTSTANT - -MPYS !,@ 3B88 2 T1 1 0 07 -MPYS ! 3B80 2 NOP 1 -MPYS @ 3B00 2 T1 1 0 7F - -MPYU !,@ CF88 2 T1 1 0 07 -MPYU ! CF80 2 NOP 1 -MPYU @ CF00 2 T1 1 0 7F - -NEG "" CE23 2 NOP 1 - -NOP "" 5500 2 NOP 1 - -NORM ! CE82 2 NOP 1 ; C25 -NORM "" CEA2 2 NOP 1 ; C20 - -OR !,@ 4D88 2 T1 1 0 07 -OR ! 4D80 2 NOP 1 -OR @ 4D00 2 T1 1 0 7F - -ORK @,@ D005 4 TLK 1 8 0F00 -ORK @ D005 4 TLK 1 - -OUT !,@,@ E088 2 T1 1 8 0F00 -OUT !,@ E080 2 T1 1 8 0F00 -OUT @,@ E000 2 TDMA 1 8 0F00 - -PAC "" CE14 2 NOP 1 - -POP "" CE1D 2 NOP 1 - -POPD !,@ 7A88 2 T1 1 0 07 -POPD ! 7A80 2 NOP 1 -POPD @ 7A00 2 T1 1 0 7F - -PSHD !,@ 5488 2 T1 1 0 07 -PSHD ! 5480 2 NOP 1 -PSHD @ 5400 2 T1 1 0 7F - -PUSH "" CE1C 2 NOP 1 -RC "" CE30 2 NOP 1 -RET "" CE26 2 NOP 1 -RFSM "" CE36 2 NOP 1 -RHM "" CE38 2 NOP 1 -ROL "" CE34 2 NOP 1 -ROR "" CE35 2 NOP 1 -ROVM "" CE02 2 NOP 1 - -RPT !,@ 4B88 2 T1 1 0 07 -RPT ! 4B80 2 NOP 1 -RPT @ 4B00 2 T1 1 0 7F - -RPTK @ CB00 2 T1 1 0 00FF ;8 bit constant - -RSXM "" CE06 2 NOP 1 -RTC "" CE32 2 NOP 1 -RTXM "" CE20 2 NOP 1 -RXF "" CE0C 2 NOP 1 - -/* shift count for SACH can only be 0,1, or 4 FOR 32020 -/* 0-7 FOR 320c25. For now, build the table specifically for the 320C25 -SACH !,@,@ 6888 2 T1 1 8 0700 -SACH !,@ 6880 2 T1 1 8 0700 -SACH ! 6880 2 NOP 1 -SACH @,@ 6800 2 TDMA 1 8 0700 -SACH @ 6800 2 T1 1 0 007F - -SACL !,@,@ 6088 2 T1 1 8 0700 -SACL !,@ 6080 2 T1 1 8 0700 -SACL ! 6080 2 NOP 1 -SACL @,@ 6000 2 TDMA 1 8 0700 -SACL @ 6000 2 T1 1 0 007F - -SAR @,!,@ 7088 2 TAR 1 0 0007 -SAR @,! 7080 2 TAR 1 0 0007 -SAR @,@ 7000 2 TAR 1 0 007F - -SBLK @,@ D003 4 TLK 1 8 0F00 -SBLK @ D003 4 TLK 1 - -SBRK @ 7F00 2 T1 1 0 00FF - -SC "" CE31 2 NOP 1 -SFL "" CE18 2 NOP 1 -SFR "" CE19 2 NOP 1 -SFSM "" CE37 2 NOP 1 -SHM "" CE39 2 NOP 1 -SOVM "" CE03 2 NOP 1 -SPAC "" CE16 2 NOP 1 - -SPH !,@ 7D88 2 T1 1 0 07 -SPH ! 7D80 2 NOP 1 -SPH @ 7D00 2 T1 1 0 7F - -SPL !,@ 7C88 2 T1 1 0 07 -SPL ! 7C80 2 NOP 1 -SPL @ 7C00 2 T1 1 0 7F - -SPM @ CE08 2 T1 1 0 03 ;2 bit constant - -SQRA !,@ 3988 2 T1 1 0 07 -SQRA ! 3980 2 NOP 1 -SQRA @ 3900 2 T1 1 0 7F - -SQRS !,@ 5A88 2 T1 1 0 07 -SQRS ! 5A80 2 NOP 1 -SQRS @ 5A00 2 T1 1 0 7F - -SST !,@ 7888 2 T1 1 0 07 -SST ! 7880 2 NOP 1 -SST @ 7800 2 T1 1 0 7F - -SST1 !,@ 7988 2 T1 1 0 07 -SST1 ! 7980 2 NOP 1 -SST1 @ 7900 2 T1 1 0 7F - -SSXM "" CE07 2 NOP 1 -STC "" CE33 2 NOP 1 -STXM "" CE21 2 NOP 1 - - -SUB !,@,@ 1088 2 T1 1 8 0F00 -SUB !,@ 1080 2 T1 1 8 0F00 -SUB ! 1080 2 NOP 1 -SUB @,@ 1000 2 TDMA 1 8 0F00 -SUB @ 1000 2 T1 1 0 007F - -SUBB !,@ 4F88 2 T1 1 0 07 -SUBB ! 4F80 2 NOP 1 -SUBB @ 4F00 2 T1 1 0 7F - -SUBC !,@ 4788 2 T1 1 0 07 -SUBC ! 4780 2 NOP 1 -SUBC @ 4700 2 T1 1 0 7F - -SUBH !,@ 4488 2 T1 1 0 07 -SUBH ! 4480 2 NOP 1 -SUBH @ 4400 2 T1 1 0 7F - -SUBK @ CD00 2 T1 1 0 00FF - -SUBS !,@ 4588 2 T1 1 0 07 -SUBS ! 4580 2 NOP 1 -SUBS @ 4500 2 T1 1 0 7F - -SUBT !,@ 4688 2 T1 1 0 07 -SUBT ! 4680 2 NOP 1 -SUBT @ 4600 2 T1 1 0 7F - -SXF "" CE0D 2 NOP 1 - -TBLR !,@ 5888 2 T1 1 0 07 -TBLR ! 5880 2 NOP 1 -TBLR @ 5800 2 T1 1 0 7F - -TBLW !,@ 5988 2 T1 1 0 07 -TBLW ! 5980 2 NOP 1 -TBLW @ 5900 2 T1 1 0 7F - -TRAP "" CE1E 2 NOP 1 - -XOR !,@ 4C88 2 T1 1 0 07 -XOR ! 4C80 2 NOP 1 -XOR @ 4C00 2 T1 1 0 7F - -XORK @,@ D006 4 TLK 1 8 0F00 -XORK @ D006 4 TLK 1 - -ZAC "" CA00 2 NOP 1 - -ZALH !,@ 4088 2 T1 1 0 07 -ZALH ! 4080 2 NOP 1 -ZALH @ 4000 2 T1 1 0 7F - -ZALR !,@ 7B88 2 T1 1 0 07 -ZALR ! 7B80 2 NOP 1 -ZALR @ 7B00 2 T1 1 0 7F - -ZALS !,@ 4188 2 T1 1 0 07 -ZALS ! 4180 2 NOP 1 -ZALS @ 4100 2 T1 1 0 7F - diff --git a/branches/s100/LSource/bin/TASM48.TAB b/branches/s100/LSource/bin/TASM48.TAB deleted file mode 100644 index a76454ae..00000000 --- a/branches/s100/LSource/bin/TASM48.TAB +++ /dev/null @@ -1,281 +0,0 @@ -"TASM 8048 Assembler. " -/**************************************************************************** -/* $Id: tasm48.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8048 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* CLASS bits are assigned as follows: -/* bit 0 = 8X48, 8035, 8039, 8049 instructions -/* bit 1 = 8X41A -/* bit 2 = 8022 -/* bit 3 = 8021 -/* Note that some of the base instructions should be disabled for the -/* 8041, 8022, and 8021, but are not. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ADD A,R0 68 1 NOP 1 -ADD A,R1 69 1 NOP 1 -ADD A,R2 6A 1 NOP 1 -ADD A,R3 6B 1 NOP 1 -ADD A,R4 6C 1 NOP 1 -ADD A,R5 6D 1 NOP 1 -ADD A,R6 6E 1 NOP 1 -ADD A,R7 6F 1 NOP 1 -ADD A,@R0 60 1 NOP 1 -ADD A,@R1 61 1 NOP 1 -ADD A,#* 03 2 NOP 1 - -ADDC A,R0 78 1 NOP 1 -ADDC A,R1 79 1 NOP 1 -ADDC A,R2 7A 1 NOP 1 -ADDC A,R3 7B 1 NOP 1 -ADDC A,R4 7C 1 NOP 1 -ADDC A,R5 7D 1 NOP 1 -ADDC A,R6 7E 1 NOP 1 -ADDC A,R7 7F 1 NOP 1 -ADDC A,@R0 70 1 NOP 1 -ADDC A,@R1 71 1 NOP 1 -ADDC A,#* 13 2 NOP 1 - -ANL A,R0 58 1 NOP 1 -ANL A,R1 59 1 NOP 1 -ANL A,R2 5A 1 NOP 1 -ANL A,R3 5B 1 NOP 1 -ANL A,R4 5C 1 NOP 1 -ANL A,R5 5D 1 NOP 1 -ANL A,R6 5E 1 NOP 1 -ANL A,R7 5F 1 NOP 1 -ANL A,@R0 50 1 NOP 1 -ANL A,@R1 51 1 NOP 1 -ANL A,#* 53 2 NOP 1 -ANL BUS,#* 98 2 NOP 1 -ANL P1,#* 99 2 NOP 1 -ANL P2,#* 9A 2 NOP 1 - -ANLD P4,A 9C 1 NOP 1 -ANLD P5,A 9D 1 NOP 1 -ANLD P6,A 9E 1 NOP 1 -ANLD P7,A 9F 1 NOP 1 - -CALL * 14 2 JMP 1 - -CLR A 27 1 NOP 1 -CLR C 97 1 NOP 1 -CLR F0 85 1 NOP 1 -CLR F1 A5 1 NOP 1 - -CPL A 37 1 NOP 1 -CPL C A7 1 NOP 1 -CPL F0 95 1 NOP 1 -CPL F1 B5 1 NOP 1 - -DA A 57 1 NOP 1 - -DEC A 07 1 NOP 1 -DEC R0 C8 1 NOP 1 -DEC R1 C9 1 NOP 1 -DEC R2 CA 1 NOP 1 -DEC R3 CB 1 NOP 1 -DEC R4 CC 1 NOP 1 -DEC R5 CD 1 NOP 1 -DEC R6 CE 1 NOP 1 -DEC R7 CF 1 NOP 1 - -DIS I 15 1 NOP 1 -DIS TCNTI 35 1 NOP 1 - -DJNZ R0,* E8 2 JTHISPAGE 1 -DJNZ R1,* E9 2 JTHISPAGE 1 -DJNZ R2,* EA 2 JTHISPAGE 1 -DJNZ R3,* EB 2 JTHISPAGE 1 -DJNZ R4,* EC 2 JTHISPAGE 1 -DJNZ R5,* ED 2 JTHISPAGE 1 -DJNZ R6,* EE 2 JTHISPAGE 1 -DJNZ R7,* EF 2 JTHISPAGE 1 - -EN DMA E5 1 NOP 2 ;8041 -EN FLAGS F5 1 NOP 2 ;8041 -EN I 05 1 NOP 1 -EN TCNTI 25 1 NOP 1 -ENT0 CLK 75 1 NOP 1 - -IN A,DBB 22 1 NOP 2 ;8041 -IN A,P0 08 1 NOP 8 ;8021 -IN A,P1 09 1 NOP 1 -IN A,P2 0A 1 NOP 1 - -INC A 17 1 NOP 1 -INC R0 18 1 NOP 1 -INC R1 19 1 NOP 1 -INC R2 1A 1 NOP 1 -INC R3 1B 1 NOP 1 -INC R4 1C 1 NOP 1 -INC R5 1D 1 NOP 1 -INC R6 1E 1 NOP 1 -INC R7 1F 1 NOP 1 -INC @R0 10 1 NOP 1 -INC @R1 11 1 NOP 1 - -INS A,BUS 08 1 NOP 1 - -JB0 * 12 2 JTHISPAGE 1 -JB1 * 32 2 JTHISPAGE 1 -JB2 * 52 2 JTHISPAGE 1 -JB3 * 72 2 JTHISPAGE 1 -JB4 * 92 2 JTHISPAGE 1 -JB5 * B2 2 JTHISPAGE 1 -JB6 * D2 2 JTHISPAGE 1 -JB7 * F2 2 JTHISPAGE 1 - -JMP * 04 2 JMP 1 - -JC * F6 2 JTHISPAGE 1 -JF0 * B6 2 JTHISPAGE 1 -JF1 * 76 2 JTHISPAGE 1 -JNC * E6 2 JTHISPAGE 1 -JNI * 86 2 JTHISPAGE 1 -JNIBF * D6 2 JTHISPAGE 2 ;8041 -JNT0 * 26 2 JTHISPAGE 1 -JNT1 * 46 2 JTHISPAGE 1 -JNZ * 96 2 JTHISPAGE 1 -JOBF * 86 2 JTHISPAGE 2 ;8041 -JTF * 16 2 JTHISPAGE 1 -JT0 * 36 2 JTHISPAGE 1 -JT1 * 56 2 JTHISPAGE 1 -JZ * C6 2 JTHISPAGE 1 - -JMPP @A B3 1 NOP 1 - -MOV A,PSW C7 1 NOP 1 -MOV A,R0 F8 1 NOP 1 -MOV A,R1 F9 1 NOP 1 -MOV A,R2 FA 1 NOP 1 -MOV A,R3 FB 1 NOP 1 -MOV A,R4 FC 1 NOP 1 -MOV A,R5 FD 1 NOP 1 -MOV A,R6 FE 1 NOP 1 -MOV A,R7 FF 1 NOP 1 -MOV A,T 42 1 NOP 1 -MOV A,@R0 F0 1 NOP 1 -MOV A,@R1 F1 1 NOP 1 -MOV A,#* 23 2 NOP 1 -MOV PSW,A D7 1 NOP 1 -MOV R0,A A8 1 NOP 1 -MOV R1,A A9 1 NOP 1 -MOV R2,A AA 1 NOP 1 -MOV R3,A AB 1 NOP 1 -MOV R4,A AC 1 NOP 1 -MOV R5,A AD 1 NOP 1 -MOV R6,A AE 1 NOP 1 -MOV R7,A AF 1 NOP 1 -MOV R0,#* B8 2 NOP 1 -MOV R1,#* B9 2 NOP 1 -MOV R2,#* BA 2 NOP 1 -MOV R3,#* BB 2 NOP 1 -MOV R4,#* BC 2 NOP 1 -MOV R5,#* BD 2 NOP 1 -MOV R6,#* BE 2 NOP 1 -MOV R7,#* BF 2 NOP 1 -MOV STS,A 90 1 NOP 2 ;8041 -MOV T,A 62 1 NOP 1 -MOV @R0,A A0 1 NOP 1 -MOV @R1,A A1 1 NOP 1 -MOV @R0,#* B0 2 NOP 1 -MOV @R1,#* B1 2 NOP 1 - -MOVD A,P4 0C 1 NOP 1 -MOVD A,P5 0D 1 NOP 1 -MOVD A,P6 0E 1 NOP 1 -MOVD A,P7 0F 1 NOP 1 -MOVD P4,A 3C 1 NOP 1 -MOVD P5,A 3D 1 NOP 1 -MOVD P6,A 3E 1 NOP 1 -MOVD P7,A 3F 1 NOP 1 - -MOVP A,@A A3 1 NOP 1 -MOVP3 A,@A E3 1 NOP 1 - -MOVX A,@R0 80 1 NOP 1 -MOVX A,@R1 81 1 NOP 1 -MOVX @R0,A 90 1 NOP 1 -MOVX @R1,A 91 1 NOP 1 - -NOP "" 00 1 NOP 1 - -ORL A,R0 48 1 NOP 1 -ORL A,R1 49 1 NOP 1 -ORL A,R2 4A 1 NOP 1 -ORL A,R3 4B 1 NOP 1 -ORL A,R4 4C 1 NOP 1 -ORL A,R5 4D 1 NOP 1 -ORL A,R6 4E 1 NOP 1 -ORL A,R7 4F 1 NOP 1 -ORL A,@R0 40 1 NOP 1 -ORL A,@R1 41 1 NOP 1 -ORL A,#* 43 2 NOP 1 -ORL BUS,#* 88 2 NOP 1 -ORL P1,#* 89 2 NOP 1 -ORL P2,#* 8A 2 NOP 1 - -ORLD P4,A 8C 1 NOP 1 -ORLD P5,A 8D 1 NOP 1 -ORLD P6,A 8E 1 NOP 1 -ORLD P7,A 8F 1 NOP 1 - -OUTL BUS,A 02 1 NOP 1 -OUT DBB,A 02 1 NOP 2 ;8041 -OUTL P0,A 90 1 NOP 8 ;8021 -OUTL P1,A 39 1 NOP 1 -OUTL P2,A 3A 1 NOP 1 - -RAD "" 80 1 NOP 4 ;8022 - -RET "" 83 1 NOP 1 -RETI "" 93 1 NOP 4 ;8022 -RETR "" 93 1 NOP 1 - -RL A E7 1 NOP 1 -RLC A F7 1 NOP 1 -RR A 77 1 NOP 1 -RRC A 67 1 NOP 1 - -SEL AN0 85 1 NOP 4 ;8022 -SEL AN1 95 1 NOP 4 ;8022 -SEL MB0 E5 1 NOP 1 -SEL MB1 F5 1 NOP 1 -SEL RB0 C5 1 NOP 1 -SEL RB1 D5 1 NOP 1 - -STOP TCNT 65 1 NOP 1 -STRT CNT 45 1 NOP 1 -STRT T 55 1 NOP 1 - -SWAP A 47 1 NOP 1 - -XCH A,R0 28 1 NOP 1 -XCH A,R1 29 1 NOP 1 -XCH A,R2 2A 1 NOP 1 -XCH A,R3 2B 1 NOP 1 -XCH A,R4 2C 1 NOP 1 -XCH A,R5 2D 1 NOP 1 -XCH A,R6 2E 1 NOP 1 -XCH A,R7 2F 1 NOP 1 -XCH A,@R0 20 1 NOP 1 -XCH A,@R1 21 1 NOP 1 - -XCHD A,@R0 30 1 NOP 1 -XCHD A,@R1 31 1 NOP 1 - -XRL A,R0 D8 1 NOP 1 -XRL A,R1 D9 1 NOP 1 -XRL A,R2 DA 1 NOP 1 -XRL A,R3 DB 1 NOP 1 -XRL A,R4 DC 1 NOP 1 -XRL A,R5 DD 1 NOP 1 -XRL A,R6 DE 1 NOP 1 -XRL A,R7 DF 1 NOP 1 -XRL A,@R0 D0 1 NOP 1 -XRL A,@R1 D1 1 NOP 1 -XRL A,#* D3 2 NOP 1 - diff --git a/branches/s100/LSource/bin/TASM51.TAB b/branches/s100/LSource/bin/TASM51.TAB deleted file mode 100644 index 24c2a142..00000000 --- a/branches/s100/LSource/bin/TASM51.TAB +++ /dev/null @@ -1,285 +0,0 @@ -"TASM 8051 Assembler. " -/**************************************************************************** -/* $Id: tasm51.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8051 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* - -.NOARGSHIFT - -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ACALL * 11 2 JMP 1 0 F800 - -ADD A,R0 28 1 NOP 1 -ADD A,R1 29 1 NOP 1 -ADD A,R2 2A 1 NOP 1 -ADD A,R3 2B 1 NOP 1 -ADD A,R4 2C 1 NOP 1 -ADD A,R5 2D 1 NOP 1 -ADD A,R6 2E 1 NOP 1 -ADD A,R7 2F 1 NOP 1 -ADD A,@R0 26 1 NOP 1 -ADD A,@R1 27 1 NOP 1 -ADD A,#* 24 2 NOP 1 -ADD A,* 25 2 NOP 1 - -ADDC A,R0 38 1 NOP 1 -ADDC A,R1 39 1 NOP 1 -ADDC A,R2 3A 1 NOP 1 -ADDC A,R3 3B 1 NOP 1 -ADDC A,R4 3C 1 NOP 1 -ADDC A,R5 3D 1 NOP 1 -ADDC A,R6 3E 1 NOP 1 -ADDC A,R7 3F 1 NOP 1 -ADDC A,@R0 36 1 NOP 1 -ADDC A,@R1 37 1 NOP 1 -ADDC A,#* 34 2 NOP 1 -ADDC A,* 35 2 NOP 1 - -AJMP * 01 2 JMP 1 0 F800 - -ANL A,R0 58 1 NOP 1 -ANL A,R1 59 1 NOP 1 -ANL A,R2 5A 1 NOP 1 -ANL A,R3 5B 1 NOP 1 -ANL A,R4 5C 1 NOP 1 -ANL A,R5 5D 1 NOP 1 -ANL A,R6 5E 1 NOP 1 -ANL A,R7 5F 1 NOP 1 -ANL A,@R0 56 1 NOP 1 -ANL A,@R1 57 1 NOP 1 -ANL A,#* 54 2 NOP 1 -ANL A,* 55 2 NOP 1 -ANL C,/* b0 2 NOP 1 -ANL C,* 82 2 NOP 1 -ANL *,A 52 2 NOP 1 -ANL *,#* 53 3 COMBINE 1 - -CJNE A,#*,* b4 3 CR 1 -CJNE A,*,* b5 3 CR 1 -CJNE R0,#*,* b8 3 CR 1 -CJNE R1,#*,* b9 3 CR 1 -CJNE R2,#*,* ba 3 CR 1 -CJNE R3,#*,* bb 3 CR 1 -CJNE R4,#*,* bc 3 CR 1 -CJNE R5,#*,* bd 3 CR 1 -CJNE R6,#*,* be 3 CR 1 -CJNE R7,#*,* bf 3 CR 1 -CJNE @R0,#*,* b6 3 CR 1 -CJNE @R1,#*,* b7 3 CR 1 - -CLR A e4 1 NOP 1 -CLR C c3 1 NOP 1 -CLR * c2 2 NOP 1 - -CPL A f4 1 NOP 1 -CPL C b3 1 NOP 1 -CPL * b2 2 NOP 1 - -DA A d4 1 NOP 1 - -DEC A 14 1 NOP 1 -DEC R0 18 1 NOP 1 -DEC R1 19 1 NOP 1 -DEC R2 1A 1 NOP 1 -DEC R3 1B 1 NOP 1 -DEC R4 1C 1 NOP 1 -DEC R5 1D 1 NOP 1 -DEC R6 1E 1 NOP 1 -DEC R7 1F 1 NOP 1 -DEC @R0 16 1 NOP 1 -DEC @R1 17 1 NOP 1 -DEC * 15 2 NOP 1 - -DIV AB 84 1 NOP 1 - -DJNZ R0,* d8 2 R1 1 -DJNZ R1,* d9 2 R1 1 -DJNZ R2,* dA 2 R1 1 -DJNZ R3,* dB 2 R1 1 -DJNZ R4,* dC 2 R1 1 -DJNZ R5,* dD 2 R1 1 -DJNZ R6,* dE 2 R1 1 -DJNZ R7,* dF 2 R1 1 -DJNZ *,* d5 3 CR 1 - -INC A 04 1 NOP 1 -INC R0 08 1 NOP 1 -INC R1 09 1 NOP 1 -INC R2 0A 1 NOP 1 -INC R3 0B 1 NOP 1 -INC R4 0C 1 NOP 1 -INC R5 0D 1 NOP 1 -INC R6 0E 1 NOP 1 -INC R7 0F 1 NOP 1 -INC @R0 06 1 NOP 1 -INC @R1 07 1 NOP 1 -INC DPTR a3 1 NOP 1 -INC * 05 2 NOP 1 - -JB *,* 20 3 CR 1 -JBC *,* 10 3 CR 1 -JC * 40 2 R1 1 -JMP @A+DPTR 73 1 NOP 1 -JNB *,* 30 3 CR 1 -JNC * 50 2 R1 1 -JNZ * 70 2 R1 1 -JZ * 60 2 R1 1 - -LCALL * 12 3 SWAP 1 - -LJMP * 02 3 SWAP 1 - -MOV A,R0 e8 1 NOP 1 -MOV A,R1 e9 1 NOP 1 -MOV A,R2 eA 1 NOP 1 -MOV A,R3 eB 1 NOP 1 -MOV A,R4 eC 1 NOP 1 -MOV A,R5 eD 1 NOP 1 -MOV A,R6 eE 1 NOP 1 -MOV A,R7 eF 1 NOP 1 -MOV A,@R0 e6 1 NOP 1 -MOV A,@R1 e7 1 NOP 1 -MOV A,#* 74 2 NOP 1 -MOV A,* e5 2 NOP 1 -MOV C,* a2 2 NOP 1 -MOV DPTR,#* 90 3 SWAP 1 -MOV R0,A f8 1 NOP 1 -MOV R1,A f9 1 NOP 1 -MOV R2,A fA 1 NOP 1 -MOV R3,A fB 1 NOP 1 -MOV R4,A fC 1 NOP 1 -MOV R5,A fD 1 NOP 1 -MOV R6,A fE 1 NOP 1 -MOV R7,A fF 1 NOP 1 -MOV R0,#* 78 2 NOP 1 -MOV R1,#* 79 2 NOP 1 -MOV R2,#* 7A 2 NOP 1 -MOV R3,#* 7B 2 NOP 1 -MOV R4,#* 7C 2 NOP 1 -MOV R5,#* 7D 2 NOP 1 -MOV R6,#* 7E 2 NOP 1 -MOV R7,#* 7F 2 NOP 1 -MOV R0,* a8 2 NOP 1 -MOV R1,* a9 2 NOP 1 -MOV R2,* aA 2 NOP 1 -MOV R3,* aB 2 NOP 1 -MOV R4,* aC 2 NOP 1 -MOV R5,* aD 2 NOP 1 -MOV R6,* aE 2 NOP 1 -MOV R7,* aF 2 NOP 1 -MOV @R0,A f6 1 NOP 1 -MOV @R1,A f7 1 NOP 1 -MOV @R0,#* 76 2 NOP 1 -MOV @R1,#* 77 2 NOP 1 -MOV @R0,* a6 2 NOP 1 -MOV @R1,* a7 2 NOP 1 -MOV *,A f5 2 NOP 1 -MOV *,C 92 2 NOP 1 -MOV *,R0 88 2 NOP 1 -MOV *,R1 89 2 NOP 1 -MOV *,R2 8A 2 NOP 1 -MOV *,R3 8B 2 NOP 1 -MOV *,R4 8C 2 NOP 1 -MOV *,R5 8D 2 NOP 1 -MOV *,R6 8E 2 NOP 1 -MOV *,R7 8F 2 NOP 1 -MOV *,@R0 86 2 NOP 1 -MOV *,@R1 87 2 NOP 1 -MOV *,#* 75 3 COMBINE 1 -MOV *,* 85 3 CSWAP 1 - -MOVC A,@A+DPTR 93 1 NOP 1 -MOVC A,@A+PC 83 1 NOP 1 - -MOVX A,@R0 e2 1 NOP 1 -MOVX A,@R1 e3 1 NOP 1 -MOVX A,@DPTR e0 1 NOP 1 -MOVX @R0,A f2 1 NOP 1 -MOVX @R1,A f3 1 NOP 1 -MOVX @DPTR,A f0 1 NOP 1 - -MUL AB a4 1 NOP 1 - -NOP "" 00 1 NOP 1 - -ORL A,R0 48 1 NOP 1 -ORL A,R1 49 1 NOP 1 -ORL A,R2 4A 1 NOP 1 -ORL A,R3 4B 1 NOP 1 -ORL A,R4 4C 1 NOP 1 -ORL A,R5 4D 1 NOP 1 -ORL A,R6 4E 1 NOP 1 -ORL A,R7 4F 1 NOP 1 -ORL A,@R0 46 1 NOP 1 -ORL A,@R1 47 1 NOP 1 -ORL A,#* 44 2 NOP 1 -ORL A,* 45 2 NOP 1 -ORL C,/* a0 2 NOP 1 -ORL C,* 72 2 NOP 1 -ORL *,A 42 2 NOP 1 -ORL *,#* 43 3 COMBINE 1 - -POP * d0 2 NOP 1 -PUSH * c0 2 NOP 1 - -RET "" 22 1 NOP 1 -RETI "" 32 1 NOP 1 - -RL A 23 1 NOP 1 -RLC A 33 1 NOP 1 -RR A 03 1 NOP 1 -RRC A 13 1 NOP 1 - -SETB C d3 1 NOP 1 -SETB * d2 2 NOP 1 - -SJMP * 80 2 R1 1 - -SUBB A,R0 98 1 NOP 1 -SUBB A,R1 99 1 NOP 1 -SUBB A,R2 9A 1 NOP 1 -SUBB A,R3 9B 1 NOP 1 -SUBB A,R4 9C 1 NOP 1 -SUBB A,R5 9D 1 NOP 1 -SUBB A,R6 9E 1 NOP 1 -SUBB A,R7 9F 1 NOP 1 -SUBB A,@R0 96 1 NOP 1 -SUBB A,@R1 97 1 NOP 1 -SUBB A,#* 94 2 NOP 1 -SUBB A,* 95 2 NOP 1 - -SWAP A c4 1 NOP 1 - -XCH A,R0 c8 1 NOP 1 -XCH A,R1 c9 1 NOP 1 -XCH A,R2 cA 1 NOP 1 -XCH A,R3 cB 1 NOP 1 -XCH A,R4 cC 1 NOP 1 -XCH A,R5 cD 1 NOP 1 -XCH A,R6 cE 1 NOP 1 -XCH A,R7 cF 1 NOP 1 -XCH A,@R0 c6 1 NOP 1 -XCH A,@R1 c7 1 NOP 1 -XCH A,* c5 2 NOP 1 - -XCHD A,@R0 d6 1 NOP 1 -XCHD A,@R1 d7 1 NOP 1 - -XRL A,R0 68 1 NOP 1 -XRL A,R1 69 1 NOP 1 -XRL A,R2 6A 1 NOP 1 -XRL A,R3 6B 1 NOP 1 -XRL A,R4 6C 1 NOP 1 -XRL A,R5 6D 1 NOP 1 -XRL A,R6 6E 1 NOP 1 -XRL A,R7 6F 1 NOP 1 -XRL A,@R0 66 1 NOP 1 -XRL A,@R1 67 1 NOP 1 -XRL A,#* 64 2 NOP 1 -XRL A,* 65 2 NOP 1 -XRL *,A 62 2 NOP 1 -XRL *,#* 63 3 COMBINE 1 - diff --git a/branches/s100/LSource/bin/TASM65.TAB b/branches/s100/LSource/bin/TASM65.TAB deleted file mode 100644 index c6b95ce7..00000000 --- a/branches/s100/LSource/bin/TASM65.TAB +++ /dev/null @@ -1,222 +0,0 @@ -"TASM 6502 Assembler. " -/**************************************************************************** -/* $Id: tasm65.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 6502 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* Note that there are two classes of extended instructions beyond -/* the standard set. The classes are assigned bits as follows: -/* bit 0 = standard set -/* bit 1 = extended instructions for R65C02 -/* bit 2 = extended instructions for R65C00/21 -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ADC #* 69 2 NOP 1 -ADC (*,X) 61 2 NOP 1 -ADC (*),Y 71 2 NOP 1 -ADC (*) 72 2 NOP 2 -ADC *,X 7D 3 ZP 1 -ADC *,Y 79 3 NOP 1 -ADC * 6D 3 ZP 1 - -AND #* 29 2 NOP 1 -AND (*,X) 21 2 NOP 1 -AND (*),Y 31 2 NOP 1 -AND (*) 32 2 NOP 2 -AND *,X 3D 3 ZP 1 -AND *,Y 39 3 NOP 1 -AND * 2D 3 ZP 1 - -ASL A 0A 1 NOP 1 -ASL *,X 1E 3 ZP 1 -ASL * 0E 3 ZP 1 - -BBR0 *,* 0f 3 CR 6 -BBR1 *,* 1f 3 CR 6 -BBR2 *,* 2f 3 CR 6 -BBR3 *,* 3f 3 CR 6 -BBR4 *,* 4f 3 CR 6 -BBR5 *,* 5f 3 CR 6 -BBR6 *,* 6f 3 CR 6 -BBR7 *,* 7f 3 CR 6 - -BBS0 *,* 8f 3 CR 6 -BBS1 *,* 9f 3 CR 6 -BBS2 *,* af 3 CR 6 -BBS3 *,* bf 3 CR 6 -BBS4 *,* cf 3 CR 6 -BBS5 *,* df 3 CR 6 -BBS6 *,* ef 3 CR 6 -BBS7 *,* ff 3 CR 6 - -BCC * 90 2 R1 1 -BCS * B0 2 R1 1 -BEQ * F0 2 R1 1 -BMI * 30 2 R1 1 -BNE * D0 2 R1 1 -BPL * 10 2 R1 1 -BRA * 80 2 R1 6 -BVC * 50 2 R1 1 -BVS * 70 2 R1 1 - -BIT #* 89 2 NOP 2 -BIT *,X 3C 3 ZP 2 -BIT * 2C 3 ZP 1 - -BRK "" 00 1 NOP 1 - -CLC "" 18 1 NOP 1 -CLD "" D8 1 NOP 1 -CLI "" 58 1 NOP 1 -CLV "" B8 1 NOP 1 - -CMP #* C9 2 NOP 1 -CMP (*,X) C1 2 NOP 1 -CMP (*),Y D1 2 NOP 1 -CMP (*) D2 2 NOP 2 -CMP *,X DD 3 ZP 1 -CMP *,Y D9 3 NOP 1 -CMP * CD 3 ZP 1 - -CPX #* E0 2 NOP 1 -CPX * EC 3 ZP 1 - -CPY #* C0 2 NOP 1 -CPY * CC 3 ZP 1 - -DEC A 3A 1 NOP 2 -DEC *,X DE 3 ZP 1 -DEC * CE 3 ZP 1 - -DEX "" CA 1 NOP 1 -DEY "" 88 1 NOP 1 - -EOR #* 49 2 NOP 1 -EOR (*,X) 41 2 NOP 1 -EOR (*),Y 51 2 NOP 1 -EOR (*) 52 2 NOP 2 -EOR *,X 5D 3 ZP 1 -EOR *,Y 59 3 NOP 1 -EOR * 4D 3 ZP 1 - -INC A 1A 1 NOP 2 -INC *,X FE 3 ZP 1 -INC * EE 3 ZP 1 - -INX "" E8 1 NOP 1 -INY "" C8 1 NOP 1 - -JMP (*,X) 7C 3 NOP 2 -JMP (*) 6C 3 NOP 1 -JMP * 4C 3 NOP 1 - -JSR * 20 3 NOP 1 - -LDA #* A9 2 NOP 1 -LDA (*,X) A1 2 NOP 1 -LDA (*),Y B1 2 NOP 1 -LDA (*) B2 2 NOP 2 -LDA *,X BD 3 ZP 1 -LDA *,Y B9 3 NOP 1 -LDA * AD 3 ZP 1 - -LDX #* A2 2 NOP 1 -LDX *,Y BE 3 ZP 1 -LDX * AE 3 ZP 1 - -LDY #* A0 2 NOP 1 -LDY *,X BC 3 ZP 1 -LDY * AC 3 ZP 1 - -LSR A 4A 1 NOP 1 -LSR *,X 5E 3 ZP 1 -LSR * 4E 3 ZP 1 - -MUL "" 02 1 NOP 4 /* R65C00/21 only*/ - -NOP "" EA 1 NOP 1 - -ORA #* 09 2 NOP 1 -ORA (*,X) 01 2 NOP 1 -ORA (*),Y 11 2 NOP 1 -ORA (*) 12 2 NOP 2 -ORA *,X 1D 3 ZP 1 -ORA *,Y 19 3 NOP 1 -ORA * 0D 3 ZP 1 - -PHA "" 48 1 NOP 1 -PHP "" 08 1 NOP 1 -PHX "" DA 1 NOP 6 -PHY "" 5A 1 NOP 6 -PLA "" 68 1 NOP 1 -PLP "" 28 1 NOP 1 -PLX "" FA 1 NOP 6 -PLY "" 7A 1 NOP 6 - -RMB0 * 07 2 NOP 6 -RMB1 * 17 2 NOP 6 -RMB2 * 27 2 NOP 6 -RMB3 * 37 2 NOP 6 -RMB4 * 47 2 NOP 6 -RMB5 * 57 2 NOP 6 -RMB6 * 67 2 NOP 6 -RMB7 * 77 2 NOP 6 - -ROL A 2A 1 NOP 1 -ROL *,X 3E 3 ZP 1 -ROL * 2E 3 ZP 1 - -ROR A 6A 1 NOP 1 -ROR *,X 7E 3 ZP 1 -ROR * 6E 3 ZP 1 - -RTI "" 40 1 NOP 1 -RTS "" 60 1 NOP 1 - -SBC #* E9 2 NOP 1 -SBC (*,X) E1 2 NOP 1 -SBC (*),Y F1 2 NOP 1 -SBC (*) F2 2 NOP 2 -SBC *,X FD 3 ZP 1 -SBC *,Y F9 3 NOP 1 -SBC * ED 3 ZP 1 - -SEC "" 38 1 NOP 1 -SED "" F8 1 NOP 1 -SEI "" 78 1 NOP 1 - -SMB0 * 87 2 NOP 6 -SMB1 * 97 2 NOP 6 -SMB2 * a7 2 NOP 6 -SMB3 * b7 2 NOP 6 -SMB4 * c7 2 NOP 6 -SMB5 * d7 2 NOP 6 -SMB6 * e7 2 NOP 6 -SMB7 * f7 2 NOP 6 - -STA (*,X) 81 2 NOP 1 -STA (*),Y 91 2 NOP 1 -STA (*) 92 2 NOP 2 -STA *,X 9D 3 ZP 1 -STA *,Y 99 3 NOP 1 -STA * 8D 3 ZP 1 - -STX *,Y 96 2 ZP 1 -STX * 8E 3 ZP 1 - -STY *,X 94 2 NOP 1 -STY * 8C 3 ZP 1 - -STZ *,X 9e 3 ZP 2 -STZ * 9c 3 ZP 2 - -TAX "" AA 1 NOP 1 -TAY "" A8 1 NOP 1 -TRB * 1c 3 ZP 2 -TSB * 0c 3 ZP 2 -TSX "" BA 1 NOP 1 -TXA "" 8A 1 NOP 1 -TXS "" 9A 1 NOP 1 -TYA "" 98 1 NOP 1 - diff --git a/branches/s100/LSource/bin/TASM68.TAB b/branches/s100/LSource/bin/TASM68.TAB deleted file mode 100644 index 7b9f5190..00000000 --- a/branches/s100/LSource/bin/TASM68.TAB +++ /dev/null @@ -1,348 +0,0 @@ -"TASM 6800-6811 Assembler" -/**************************************************************************** -/* $Id: tasm68.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* Originally submitted by Richard P. White, June 4,1989 */ -/* Corrected and enhanced by T.N. Anderson, STI */ -/* Enhanced for the 68HC11 by George Blat, Nov 3, 1990 -/* Class bits defined as follows: -/* -/* bit 0 for 6800 -/* bit 1 for 6801/6803 -/* bit 2 for 68HC11 -/* -/* Note that TASM deviates from motorola syntax for BCLR, BSET, -/* BRCLR, and BRSET instructions. TASM requires commas between -/* each arg. Motorola requires white space before the make and -/* label args. - -.MSFIRST - -ABA "" 1B 1 NOP 1 -ABX "" 3A 1 NOP 2 -ABY "" 183A 2 NOP 4 - -ADCA #* 89 2 NOP 1 -ADCA *,Y 18A9 3 NOP 4 -ADCA *,X A9 2 NOP 1 -ADCA * B9 3 MZERO 1 - -ADCB #* C9 2 NOP 1 -ADCB *,Y 18E9 3 NOP 4 -ADCB *,X E9 2 NOP 1 -ADCB * F9 3 MZERO 1 - -ADDA #* 8B 2 NOP 1 -ADDA *,Y 18AB 3 NOP 4 -ADDA *,X AB 2 NOP 1 -ADDA * BB 3 MZERO 1 - -ADDB #* CB 2 NOP 1 -ADDB *,Y 18EB 3 NOP 4 -ADDB *,X EB 2 NOP 1 -ADDB * FB 3 MZERO 1 - -ADDD #* C3 3 SWAP 2 -ADDD *,Y 18E3 3 NOP 4 -ADDD *,X E3 2 NOP 2 -ADDD * F3 3 MZERO 2 - -ANDA #* 84 2 NOP 1 -ANDA *,Y 18A4 3 NOP 4 -ANDA *,X A4 2 NOP 1 -ANDA * B4 3 MZERO 1 - -ANDB #* C4 2 NOP 1 -ANDB *,Y 18E4 3 NOP 4 -ANDB *,X E4 2 NOP 1 -ANDB * F4 3 MZERO 1 - -ASL *,Y 1868 3 NOP 4 -ASL *,X 68 2 NOP 1 -ASL * 78 3 SWAP 1 -ASLA "" 48 1 NOP 1 -ASLB "" 58 1 NOP 1 -ASLD "" 05 1 NOP 2 - -ASR *,Y 1867 3 NOP 4 -ASR *,X 67 2 NOP 1 -ASR * 77 3 SWAP 1 -ASRA "" 47 1 NOP 1 -ASRB "" 57 1 NOP 1 - -BCC * 24 2 R1 1 -BCLR *,X,* 1D 3 COMB 4 -BCLR *,Y,* 181D 4 COMB 4 -BCLR *,#* 15 3 COMB 4 /* allow # since mask is immediate data -BCLR *,* 15 3 COMB 4 -BCS * 25 2 R1 1 -BEQ * 27 2 R1 1 -BGE * 2C 2 R1 1 -BGT * 2E 2 R1 1 -BHI * 22 2 R1 1 -BHS * 24 2 R1 1 -BITA #* 85 2 NOP 1 -BITA *,Y 18A5 3 NOP 4 -BITA *,X A5 2 NOP 1 -BITA * B5 3 MZERO 1 -BITB #* C5 2 NOP 1 -BITB *,Y 18E5 3 NOP 4 -BITB *,X E5 2 NOP 1 -BITB * F5 3 MZERO 1 -BLE * 2F 2 R1 1 -BLO * 25 2 R1 1 -BLS * 23 2 R1 1 -BLT * 2D 2 R1 1 -BMI * 2B 2 R1 1 -BNE * 26 2 R1 1 -BPL * 2A 2 R1 1 -BRA * 20 2 R1 1 -BRCLR *,X,*,* 1F 4 3REL 4 -BRCLR *,Y,*,* 181F 5 3REL 4 -BRCLR *,*,* 13 4 3REL 4 -BRN * 21 2 R1 2 /* NOT SURE ABOUT 6803 */ -BRSET *,X,*,* 1E 4 3REL 4 -BRSET *,Y,*,* 181E 5 3REL 4 -BRSET *,*,* 12 4 3REL 4 -BSET *,X,* 1C 3 COMB 4 -BSET *,Y,* 181C 4 COMB 4 -BSET *,#* 14 3 COMB 4 /* allow # -BSET *,* 14 3 COMB 4 -BSR * 8D 2 R1 1 -BVC * 28 2 R1 1 -BVS * 29 2 R1 1 -CBA "" 11 1 NOP 1 -CLC "" 0C 1 NOP 1 -CLI "" 0E 1 NOP 1 -CLR *,Y 186F 3 NOP 4 -CLR *,X 6F 2 NOP 1 -CLR * 7F 3 SWAP 1 -CLRA "" 4F 1 NOP 1 -CLRB "" 5F 1 NOP 1 -CLV "" 0A 1 NOP 1 -CMPA #* 81 2 NOP 1 -CMPA *,X A1 2 NOP 1 -CMPA *,Y 18A1 3 NOP 4 -CMPA * B1 3 MZERO 1 -CMPB #* C1 2 NOP 1 -CMPB *,Y 18E1 3 NOP 4 -CMPB *,X E1 2 NOP 1 -CMPB * F1 3 MZERO 1 -CMPD #* 1A83 4 SWAP 4 /* alias for CPD */ -CMPD *,X 1AA3 3 NOP 4 -CMPD *,Y CDA3 3 NOP 4 -CMPD * 1AB3 4 MZERO 4 -COM *,X 63 2 NOP 1 -COM *,Y 1863 3 NOP 4 -COM * 73 3 SWAP 1 -COMA "" 43 1 NOP 1 -COMB "" 53 1 NOP 1 -CPD #* 1A83 4 SWAP 4 -CPD *,X 1AA3 3 NOP 4 -CPD *,Y CDA3 3 NOP 4 -CPD * 1AB3 4 MZERO 4 -CPX #* 8C 3 SWAP 1 -CPX *,X AC 2 NOP 1 -CPX *,Y CDAC 3 NOP 4 -CPX * BC 3 MZERO 1 -CPY #* 188C 4 SWAP 4 -CPY *,Y 18AC 3 NOP 4 -CPY *,X 1AAC 3 NOP 4 -CPY * 18BC 4 MZERO 4 -DAA "" 19 1 NOP 1 -DEC *,Y 186A 3 NOP 4 -DEC *,X 6A 2 NOP 1 -DEC * 7A 3 SWAP 1 -DECA "" 4A 1 NOP 1 -DECB "" 5A 1 NOP 1 -DES "" 34 1 NOP 1 -DEX "" 09 1 NOP 1 -DEY "" 1809 2 NOP 4 -EORA #* 88 2 NOP 1 -EORA *,Y 18A8 3 NOP 4 -EORA *,X A8 2 NOP 1 -EORA * B8 3 MZERO 1 -EORB #* C8 2 NOP 1 -EORB *,Y 18E8 3 NOP 4 -EORB *,X E8 2 NOP 1 -EORB * F8 3 MZERO 1 -FDIV "" 03 1 NOP 4 -IDIV "" 02 1 NOP 4 -INC *,Y 186C 3 NOP 4 -INC *,X 6C 2 NOP 1 -INC * 7C 3 SWAP 1 -INCA "" 4C 1 NOP 1 -INCB "" 5C 1 NOP 1 -INS "" 31 1 NOP 1 -INX "" 08 1 NOP 1 -INY "" 1808 2 NOP 4 -JMP *,Y 186E 3 NOP 4 -JMP *,X 6E 2 NOP 1 -JMP * 7E 3 SWAP 1 -JSR *,Y 18AD 3 NOP 4 -JSR *,X AD 2 NOP 1 -JSR * BD 3 MZERO 1 - -LDAA #* 86 2 NOP 1 -LDAA *,Y 18A6 3 NOP 4 -LDAA *,X A6 2 NOP 1 -LDAA >* B6 3 SWAP 1 /* Force EXT mode */ -LDAA * B6 3 MZERO 1 - -LDAB #* C6 2 NOP 1 -LDAB *,Y 18E6 3 NOP 4 -LDAB *,X E6 2 NOP 1 -LDAB >* F6 3 SWAP 1 /* Force EXT mode */ -LDAB * F6 3 MZERO 1 - -LDD #* CC 3 SWAP 2 -LDD *,Y 18EC 3 NOP 4 -LDD *,X EC 2 NOP 2 -LDD >* FC 3 SWAP 2 /* Force EXT mode */ -LDD * FC 3 MZERO 2 - -LDS #* 8E 3 SWAP 1 -LDS *,Y 18AE 3 NOP 4 -LDS *,X AE 2 NOP 1 -LDS >* BE 3 SWAP 1 /* Force EXT mode */ -LDS * BE 3 MZERO 1 - -LDX #* CE 3 SWAP 1 -LDX *,X EE 2 NOP 1 -LDX *,Y CDEE 3 NOP 4 -LDX >* FE 3 SWAP 1 /* Force EXT mode */ -LDX * FE 3 MZERO 1 - -LDY #* 18CE 4 SWAP 4 -LDY *,Y 18EE 3 NOP 4 -LDY *,X 1AEE 3 NOP 4 -LDY >* 18FE 4 SWAP 4 /* Force EXT mode */ -LDY * 18FE 4 MZERO 4 - -LSL *,Y 1868 3 NOP 4 -LSL *,X 68 2 NOP 1 /*SAME AS ASL */ -LSL * 78 3 SWAP 1 -LSLA "" 48 1 NOP 1 -LSLB "" 58 1 NOP 1 -LSLD "" 05 1 NOP 2 -LSR *,Y 1864 3 NOP 4 -LSR *,X 64 2 NOP 1 -LSR * 74 3 SWAP 1 -LSRA "" 44 1 NOP 1 -LSRB "" 54 1 NOP 1 -LSRD "" 04 1 NOP 2 -MUL "" 3D 1 NOP 2 -NEG *,Y 1860 3 NOP 4 -NEG *,X 60 2 NOP 1 -NEG * 70 3 SWAP 1 -NEGA "" 40 1 NOP 1 -NEGB "" 50 1 NOP 1 -NOP "" 01 1 NOP 1 -ORAA #* 8A 2 NOP 1 -ORAA *,Y 18AA 3 NOP 4 -ORAA *,X AA 2 NOP 1 -ORAA * BA 3 MZERO 1 -ORAB #* CA 2 NOP 1 -ORAB *,Y 18EA 3 NOP 4 -ORAB *,X EA 2 NOP 1 -ORAB * FA 3 MZERO 1 -PSHA "" 36 1 NOP 1 -PSHB "" 37 1 NOP 1 -PSHX "" 3C 1 NOP 2 -PSHY "" 183C 2 NOP 4 -PULA "" 32 1 NOP 1 -PULB "" 33 1 NOP 1 -PULX "" 38 1 NOP 2 -PULY "" 1838 2 NOP 4 -ROL *,Y 1869 3 NOP 4 -ROL *,X 69 2 NOP 1 -ROL * 79 3 SWAP 1 -ROLA "" 49 1 NOP 1 -ROLB "" 59 1 NOP 1 -ROR *,Y 1866 3 NOP 4 -ROR *,X 66 2 NOP 1 -ROR * 76 3 SWAP 1 -RORA "" 46 1 NOP 1 -RORB "" 56 1 NOP 1 -RTI "" 3B 1 NOP 1 -RTS "" 39 1 NOP 1 -SBA "" 10 1 NOP 1 -SBCA #* 82 2 NOP 1 -SBCA *,Y 18A2 3 NOP 4 -SBCA *,X A2 2 NOP 1 -SBCA * B2 3 MZERO 1 -SBCB #* C2 2 NOP 1 -SBCB *,Y 18E2 3 NOP 4 -SBCB *,X E2 2 NOP 1 -SBCB * F2 3 MZERO 1 -SEC "" 0D 1 NOP 1 -SEI "" 0F 1 NOP 1 -SEV "" 0B 1 NOP 1 - -STAA *,Y 18A7 3 NOP 4 -STAA *,X A7 2 NOP 1 -STAA >* B7 3 SWAP 1 /* Force EXT mode */ -STAA * B7 3 MZERO 1 - -STAB *,Y 18E7 3 NOP 4 -STAB *,X E7 2 NOP 1 -STAB >* F7 3 SWAP 1 /* Force EXT mode */ -STAB * F7 3 MZERO 1 - -STD *,Y 18ED 3 NOP 4 -STD *,X ED 2 NOP 2 -STD >* FD 3 SWAP 2 /* Force EXT mode */ -STD * FD 3 MZERO 2 - -STOP "" CF 1 NOP 1 - -STS *,X AF 2 NOP 1 -STS *,Y 18AF 3 NOP 4 -STS >* BF 3 SWAP 1 /* Force EXT mode */ -STS * BF 3 MZERO 1 - -STX *,X EF 2 NOP 1 -STX *,Y CDEF 3 NOP 4 -STX >* FF 3 SWAP 1 /* Force EXT mode */ -STX * FF 3 MZERO 1 - -STY *,Y 18EF 3 NOP 4 -STY *,X 1AEF 3 NOP 4 -STY >* 18FF 4 SWAP 4 /* Force EXT mode */ -STY * 18FF 4 MZERO 4 - -SUBA #* 80 2 NOP 1 -SUBA *,Y 18A0 3 NOP 4 -SUBA *,X A0 2 NOP 1 -SUBA * B0 3 MZERO 1 - -SUBB #* C0 2 NOP 1 -SUBB *,Y 18E0 3 NOP 4 -SUBB *,X E0 2 NOP 1 -SUBB * F0 3 MZERO 1 - -SUBD #* 83 3 SWAP 2 -SUBD *,Y 18A3 3 NOP 4 -SUBD *,X A3 2 NOP 2 -SUBD * B3 3 MZERO 2 - -SWI "" 3F 1 NOP 1 -TAB "" 16 1 NOP 1 -TAP "" 06 1 NOP 1 -TBA "" 17 1 NOP 1 -TEST "" 00 1 NOP 1 -TPA "" 07 1 NOP 1 -TST *,Y 186D 3 NOP 4 -TST *,X 6D 2 NOP 1 -TST * 7D 3 SWAP 1 -TSTA "" 4D 1 NOP 1 -TSTB "" 5D 1 NOP 1 -TSX "" 30 1 NOP 1 -TSY "" 1830 2 NOP 4 -TXS "" 35 1 NOP 1 -TYS "" 1835 2 NOP 4 -WAI "" 3E 1 NOP 1 -XGDX "" 8F 1 NOP 4 -XGDY "" 188F 2 NOP 4 -/* That's all folks */ - diff --git a/branches/s100/LSource/bin/TASM70.TAB b/branches/s100/LSource/bin/TASM70.TAB deleted file mode 100644 index b1cc5e04..00000000 --- a/branches/s100/LSource/bin/TASM70.TAB +++ /dev/null @@ -1,290 +0,0 @@ -"TASM 7000 Assembler. " -/**************************************************************************** -/* $Id: tasm70.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* Table for TMS7000 micros -/* Note that the table does not require the 'Rnn' nomenclature -/* for reference of locations in the register file. Any expression -/* will do, the value of which indicates the register. This is more -/* flexible then making an entry like "ADC R*,A". -/* -/* TASM has trouble with the MOVD +(B),+ instruction so -/* we convert it to MOVD +[B],+ -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -.ALTWILD+ - -ADC B,A 69 1 NOP 1 -ADC %+,A 29 2 NOP 1 -ADC %+,B 59 2 NOP 1 -ADC %+,+ 79 3 COMB 1 -ADC +,A 19 2 NOP 1 -ADC +,B 39 2 NOP 1 -ADC +,+ 49 3 COMB 1 - -ADD B,A 68 1 NOP 1 -ADD %+,A 28 2 NOP 1 -ADD %+,B 58 2 NOP 1 -ADD %+,+ 78 3 COMB 1 -ADD +,A 18 2 NOP 1 -ADD +,B 38 2 NOP 1 -ADD +,+ 48 3 COMB 1 - -AND B,A 63 1 NOP 1 -AND %+,A 23 2 NOP 1 -AND %+,B 53 2 NOP 1 -AND %+,+ 73 3 COMB 1 -AND +,A 13 2 NOP 1 -AND +,B 33 2 NOP 1 -AND +,+ 43 3 COMB 1 - -ANDP A,+ 83 2 NOP 1 -ANDP B,+ 93 2 NOP 1 -ANDP %+,+ A3 3 COMB 1 - -BTJO B,A,+ 66 2 R1 1 -BTJO %+,A,+ 26 3 CREL 1 -BTJO %+,B,+ 56 3 CREL 1 -BTJO %+,+,+ 76 4 3REL 1 -BTJO +,A,+ 16 3 CREL 1 -BTJO +,B,+ 36 3 CREL 1 -BTJO +,+,+ 46 4 3REL 1 - - -BTJOP A,+,+ 86 3 CREL 1 -BTJOP B,+,+ 96 3 CREL 1 -BTJOP %+,+,+ A6 4 3REL 1 - -BTJZ B,A,+ 67 2 R1 1 -BTJZ %+,A,+ 27 3 CREL 1 -BTJZ %+,B,+ 57 3 CREL 1 -BTJZ %+,+,+ 77 4 3REL 1 -BTJZ +,A,+ 17 3 CREL 1 -BTJZ +,B,+ 37 3 CREL 1 -BTJZ +,+,+ 47 4 3REL 1 - -BTJZP A,+,+ 87 3 CREL 1 -BTJZP B,+,+ 97 3 CREL 1 -BTJZP %+,+,+ A7 4 3REL 1 - -BR @+(B) AC 3 SWAP 1 -BR @+[B] AC 3 SWAP 1 -BR @+ 8C 3 SWAP 1 -BR *+ 9C 2 NOP 1 - -CALL @+(B) AE 3 SWAP 1 -CALL @+[B] AE 3 SWAP 1 -CALL @+ 8E 3 SWAP 1 -CALL *+ 9E 2 NOP 1 - -CLR A B5 1 NOP 1 -CLR B C5 1 NOP 1 -CLR + D5 2 NOP 1 - -CLRC "" B0 1 NOP 1 - -CMP B,A 6D 1 NOP 1 -CMP %+,A 2D 2 NOP 1 -CMP %+,B 5D 2 NOP 1 -CMP %+,+ 7D 3 COMB 1 -CMP +,A 1D 2 NOP 1 -CMP +,B 3D 2 NOP 1 -CMP +,+ 4D 3 COMB 1 - -CMPA @+(B) AD 3 SWAP 1 -CMPA @+[B] AD 3 SWAP 1 -CMPA @+ 8D 3 SWAP 1 -CMPA *+ 9D 2 NOP 1 - -DAC B,A 6E 1 NOP 1 -DAC %+,A 2E 2 NOP 1 -DAC %+,B 5E 2 NOP 1 -DAC %+,+ 7E 3 COMB 1 -DAC +,A 1E 2 NOP 1 -DAC +,B 3E 2 NOP 1 -DAC +,+ 4E 3 COMB 1 - -DEC A B2 1 NOP 1 -DEC B C2 1 NOP 1 -DEC + D2 2 NOP 1 - -DECD A BB 1 NOP 1 -DECD B CB 1 NOP 1 -DECD + DB 2 NOP 1 - -DINT "" 06 1 NOP 1 - -DJNZ A,+ BA 2 R1 1 -DJNZ B,+ CA 2 R1 1 -DJNZ +,+ DA 3 CREL 1 - -DSB B,A 6F 1 NOP 1 -DSB %+,A 2F 2 NOP 1 -DSB %+,B 5F 2 NOP 1 -DSB %+,+ 7F 3 COMB 1 -DSB +,A 1F 2 NOP 1 -DSB +,B 3F 2 NOP 1 -DSB +,+ 4F 3 COMB 1 - -EINT "" 05 1 NOP 1 - -IDLE "" 01 1 NOP 1 - -INC A B3 1 NOP 1 -INC B C3 1 NOP 1 -INC + D3 2 NOP 1 - -INV A B4 1 NOP 1 -INV B C4 1 NOP 1 -INV + D4 2 NOP 1 - -JMP + E0 2 R1 1 - -JC + E3 2 R1 1 -JEQ + E2 2 R1 1 -JGE + E5 2 R1 1 -JGT + E4 2 R1 1 -JHS + E3 2 R1 1 -JL + E7 2 R1 1 -JN + E1 2 R1 1 /+ ?? -JNC + E7 2 R1 1 -JNE + E6 2 R1 1 -JNZ + E6 2 R1 1 -JP + E4 2 R1 1 -JPZ + E5 2 R1 1 -JZ + E2 2 R1 1 - -LDA @+(B) AA 3 SWAP 1 -LDA @+[B] AA 3 SWAP 1 -LDA @+ 8A 3 SWAP 1 -LDA *+ 9A 2 NOP 1 - -LDSP "" 0D 1 NOP 1 - -MOV A,B C0 1 NOP 1 -MOV B,A 62 1 NOP 1 -MOV A,+ D0 2 NOP 1 -MOV B,+ D1 2 NOP 1 -MOV %+,A 22 2 NOP 1 -MOV %+,B 52 2 NOP 1 -MOV %+,+ 72 3 COMB 1 -MOV +,A 12 2 NOP 1 -MOV +,B 32 2 NOP 1 -MOV +,+ 42 3 COMB 1 - -MOVD %+[B],+ A8 4 CSWAP 1 -MOVD %+,+ 88 4 CSWAP 1 -MOVD +,+ 98 3 COMB 1 - -MOVP A,+ 82 2 NOP 1 -MOVP B,+ 92 2 NOP 1 -MOVP %+,+ A2 3 COMB 1 -MOVP +,A 80 2 NOP 1 -MOVP +,B 91 2 NOP 1 - -MPY B,A 6C 1 NOP 1 -MPY %+,A 2C 2 NOP 1 -MPY %+,B 5C 2 NOP 1 -MPY %+,+ 7C 3 COMB 1 -MPY +,A 1C 2 NOP 1 -MPY +,B 3C 2 NOP 1 -MPY +,+ 4C 3 COMB 1 - -NOP "" 00 1 NOP 1 - -OR B,A 64 1 NOP 1 -OR %+,A 24 2 NOP 1 -OR %+,B 54 2 NOP 1 -OR %+,+ 74 3 COMB 1 -OR +,A 14 2 NOP 1 -OR +,B 34 2 NOP 1 -OR +,+ 44 3 COMB 1 - -ORP A,+ 84 2 NOP 1 -ORP B,+ 94 2 NOP 1 -ORP %+,+ A4 3 COMB 1 - -POP A B9 1 NOP 1 -POP B C9 1 NOP 1 -POP ST 08 1 NOP 1 -POP + D9 2 NOP 1 -POPST "" 08 1 NOP 1 - -PUSH A B8 1 NOP 1 -PUSH B C8 1 NOP 1 -PUSH ST 0E 1 NOP 1 -PUSH + D8 2 NOP 1 -PUSHST "" 0E 1 NOP 1 - -RETI "" 0B 1 NOP 1 - -RETS "" 0A 1 NOP 1 - -RL A BE 1 NOP 1 -RL B CE 1 NOP 1 -RL + DE 2 NOP 1 - -RLC A BF 1 NOP 1 -RLC B CF 1 NOP 1 -RLC + DF 2 NOP 1 - -RR A BC 1 NOP 1 -RR B CC 1 NOP 1 -RR + DC 2 NOP 1 - -RRC A BD 1 NOP 1 -RRC B CD 1 NOP 1 -RRC + DD 2 NOP 1 - -SBB B,A 6B 1 NOP 1 -SBB %+,A 2B 2 NOP 1 -SBB %+,B 5B 2 NOP 1 -SBB %+,+ 7B 3 COMB 1 -SBB +,A 1B 2 NOP 1 -SBB +,B 3B 2 NOP 1 -SBB +,+ 4B 3 COMB 1 - -SETC "" 07 1 NOP 1 - -STA @+(B) AB 3 SWAP 1 -STA @+[B] AB 3 SWAP 1 -STA @+ 8B 3 SWAP 1 -STA *+ 9B 2 NOP 1 - -STSP "" 09 1 NOP 1 - -SUB B,A 6A 1 NOP 1 -SUB %+,A 2A 2 NOP 1 -SUB %+,B 5A 2 NOP 1 -SUB %+,+ 7A 3 COMB 1 -SUB +,A 1A 2 NOP 1 -SUB +,B 3A 2 NOP 1 -SUB +,+ 4A 3 COMB 1 - -SWAP A B7 1 NOP 1 -SWAP B C7 1 NOP 1 -SWAP + D7 2 NOP 1 - -TRAP + FF 1 SUB 1 - -TST A B0 1 NOP 1 -TSTA "" B0 1 NOP 1 -TST B C1 1 NOP 1 -TSTB "" C1 1 NOP 1 - -XCHB A B6 1 NOP 1 -XCHB + D6 2 NOP 1 - -XOR B,A 65 1 NOP 1 -XOR %+,A 25 2 NOP 1 -XOR %+,B 55 2 NOP 1 -XOR %+,+ 75 3 COMB 1 -XOR +,A 15 2 NOP 1 -XOR +,B 35 2 NOP 1 -XOR +,+ 45 3 COMB 1 - -XORP A,+ 85 2 NOP 1 -XORP B,+ 95 2 NOP 1 -XORP %+,+ A5 3 COMB 1 - diff --git a/branches/s100/LSource/bin/TASM80.TAB b/branches/s100/LSource/bin/TASM80.TAB deleted file mode 100644 index f644ccd4..00000000 --- a/branches/s100/LSource/bin/TASM80.TAB +++ /dev/null @@ -1,594 +0,0 @@ -"TASM Z80 Assembler. " -/**************************************************************************** -/* $Id: tasm80.tab 1.2 1998/02/28 14:31:22 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the Z80 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Carl A. Wall, VE3APY. -/* -/* Class bits assigned as follows: -/* Bit-0 = Z80 (base instruction set) -/* Bit-1 = HD64180 (extended instructions) -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OP BYTES RULE CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC A,(HL) 8E 1 NOP 1 -ADC A,(IX*) 8EDD 3 ZIX 1 -ADC A,(IY*) 8EFD 3 ZIX 1 -ADC A,A 8F 1 NOP 1 -ADC A,B 88 1 NOP 1 -ADC A,C 89 1 NOP 1 -ADC A,D 8A 1 NOP 1 -ADC A,E 8B 1 NOP 1 -ADC A,H 8C 1 NOP 1 -ADC A,L 8D 1 NOP 1 -ADC A,* CE 2 NOP 1 -ADC HL,BC 4AED 2 NOP 1 -ADC HL,DE 5AED 2 NOP 1 -ADC HL,HL 6AED 2 NOP 1 -ADC HL,SP 7AED 2 NOP 1 - -ADD A,(HL) 86 1 NOP 1 -ADD A,(IX*) 86DD 3 ZIX 1 -ADD A,(IY*) 86FD 3 ZIX 1 -ADD A,A 87 1 NOP 1 -ADD A,B 80 1 NOP 1 -ADD A,C 81 1 NOP 1 -ADD A,D 82 1 NOP 1 -ADD A,E 83 1 NOP 1 -ADD A,H 84 1 NOP 1 -ADD A,L 85 1 NOP 1 -ADD A,* C6 2 NOP 1 -ADD HL,BC 09 1 NOP 1 -ADD HL,DE 19 1 NOP 1 -ADD HL,HL 29 1 NOP 1 -ADD HL,SP 39 1 NOP 1 -ADD IX,BC 09DD 2 NOP 1 -ADD IX,DE 19DD 2 NOP 1 -ADD IX,IX 29DD 2 NOP 1 -ADD IX,SP 39DD 2 NOP 1 -ADD IY,BC 09FD 2 NOP 1 -ADD IY,DE 19FD 2 NOP 1 -ADD IY,IY 29FD 2 NOP 1 -ADD IY,SP 39FD 2 NOP 1 - -AND (HL) A6 1 NOP 1 -AND (IX*) A6DD 3 ZIX 1 -AND (IY*) A6FD 3 ZIX 1 -AND A A7 1 NOP 1 -AND B A0 1 NOP 1 -AND C A1 1 NOP 1 -AND D A2 1 NOP 1 -AND E A3 1 NOP 1 -AND H A4 1 NOP 1 -AND L A5 1 NOP 1 -AND * E6 2 NOP 1 - -BIT *,(HL) 46CB 2 ZBIT 1 -BIT *,(IX*) CBDD 4 ZBIT 1 0 4600 -BIT *,(IY*) CBFD 4 ZBIT 1 0 4600 -BIT *,A 47CB 2 ZBIT 1 -BIT *,B 40CB 2 ZBIT 1 -BIT *,C 41CB 2 ZBIT 1 -BIT *,D 42CB 2 ZBIT 1 -BIT *,E 43CB 2 ZBIT 1 -BIT *,H 44CB 2 ZBIT 1 -BIT *,L 45CB 2 ZBIT 1 - -CALL C,* DC 3 NOP 1 -CALL M,* FC 3 NOP 1 -CALL NC,* D4 3 NOP 1 -CALL NZ,* C4 3 NOP 1 -CALL P,* F4 3 NOP 1 -CALL PE,* EC 3 NOP 1 -CALL PO,* E4 3 NOP 1 -CALL Z,* CC 3 NOP 1 -CALL * CD 3 NOP 1 - -CCF "" 3F 1 NOP 1 - -CP (HL) BE 1 NOP 1 -CP (IX*) BEDD 3 ZIX 1 -CP (IY*) BEFD 3 ZIX 1 -CP A BF 1 NOP 1 -CP B B8 1 NOP 1 -CP C B9 1 NOP 1 -CP D BA 1 NOP 1 -CP E BB 1 NOP 1 -CP H BC 1 NOP 1 -CP L BD 1 NOP 1 -CP * FE 2 NOP 1 -CPD "" A9ED 2 NOP 1 -CPDR "" B9ED 2 NOP 1 -CPIR "" B1ED 2 NOP 1 -CPI "" A1ED 2 NOP 1 -CPL "" 2F 1 NOP 1 - -DAA "" 27 1 NOP 1 - -DEC (HL) 35 1 NOP 1 -DEC (IX*) 35DD 3 ZIX 1 -DEC (IY*) 35FD 3 ZIX 1 -DEC A 3D 1 NOP 1 -DEC B 05 1 NOP 1 -DEC BC 0B 1 NOP 1 -DEC C 0D 1 NOP 1 -DEC D 15 1 NOP 1 -DEC DE 1B 1 NOP 1 -DEC E 1D 1 NOP 1 -DEC H 25 1 NOP 1 -DEC HL 2B 1 NOP 1 -DEC IX 2BDD 2 NOP 1 -DEC IY 2BFD 2 NOP 1 -DEC L 2D 1 NOP 1 -DEC SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -DJNZ * 10 2 R1 1 - -EI "" FB 1 NOP 1 -EX (SP),HL E3 1 NOP 1 -EX (SP),IX E3DD 2 NOP 1 -EX (SP),IY E3FD 2 NOP 1 -EX AF,AF' 08 1 NOP 1 -EX DE,HL EB 1 NOP 1 -EXX "" D9 1 NOP 1 -HALT "" 76 1 NOP 1 - -IM 0 46ED 2 NOP 1 -IM 1 56ED 2 NOP 1 -IM 2 5EED 2 NOP 1 - -/* Alternate form of above -IM0 46ED 2 NOP 1 -IM1 56ED 2 NOP 1 -IM2 5EED 2 NOP 1 - -IN A,(C) 78ED 2 NOP 1 -IN B,(C) 40ED 2 NOP 1 -IN C,(C) 48ED 2 NOP 1 -IN D,(C) 50ED 2 NOP 1 -IN E,(C) 58ED 2 NOP 1 -IN H,(C) 60ED 2 NOP 1 -IN L,(C) 68ED 2 NOP 1 - -IN A,(*) DB 2 NOP 1 - -IN0 A,(*) 38ED 3 NOP 2 -IN0 B,(*) 00ED 3 NOP 2 -IN0 C,(*) 08ED 3 NOP 2 -IN0 D,(*) 10ED 3 NOP 2 -IN0 E,(*) 18ED 3 NOP 2 -IN0 H,(*) 20ED 3 NOP 2 -IN0 L,(*) 28ED 3 NOP 2 - -INC (HL) 34 1 NOP 1 -INC (IX*) 34DD 3 ZIX 1 -INC (IY*) 34FD 3 ZIX 1 -INC A 3C 1 NOP 1 -INC B 04 1 NOP 1 -INC BC 03 1 NOP 1 -INC C 0C 1 NOP 1 -INC D 14 1 NOP 1 -INC DE 13 1 NOP 1 -INC E 1C 1 NOP 1 -INC H 24 1 NOP 1 -INC HL 23 1 NOP 1 -INC IX 23DD 2 NOP 1 -INC IY 23FD 2 NOP 1 -INC L 2C 1 NOP 1 -INC SP 33 1 NOP 1 - - -IND "" AAED 2 NOP 1 -INDR "" BAED 2 NOP 1 -INI "" A2ED 2 NOP 1 -INIR "" B2ED 2 NOP 1 - -JP (HL) E9 1 NOP 1 -JP (IX) E9DD 2 NOP 1 -JP (IY) E9FD 2 NOP 1 -JP C,* DA 3 NOP 1 -JP M,* FA 3 NOP 1 -JP NC,* D2 3 NOP 1 -JP NZ,* C2 3 NOP 1 -JP P,* F2 3 NOP 1 -JP PE,* EA 3 NOP 1 -JP PO,* E2 3 NOP 1 -JP Z,* CA 3 NOP 1 -JP * C3 3 NOP 1 - -JR C,* 38 2 R1 1 -JR NC,* 30 2 R1 1 -JR NZ,* 20 2 R1 1 -JR Z,* 28 2 R1 1 -JR * 18 2 R1 1 - -LD (BC),A 02 1 NOP 1 -LD (DE),A 12 1 NOP 1 -LD (HL),A 77 1 NOP 1 -LD (HL),B 70 1 NOP 1 -LD (HL),C 71 1 NOP 1 -LD (HL),D 72 1 NOP 1 -LD (HL),E 73 1 NOP 1 -LD (HL),H 74 1 NOP 1 -LD (HL),L 75 1 NOP 1 -LD (HL),* 36 2 NOP 1 -LD (IX*),A 77DD 3 ZIX 1 -LD (IX*),B 70DD 3 ZIX 1 -LD (IX*),C 71DD 3 ZIX 1 -LD (IX*),D 72DD 3 ZIX 1 -LD (IX*),E 73DD 3 ZIX 1 -LD (IX*),H 74DD 3 ZIX 1 -LD (IX*),L 75DD 3 ZIX 1 -LD (IX*),* 36DD 4 ZIX 1 -LD (IY*),A 77FD 3 ZIX 1 -LD (IY*),B 70FD 3 ZIX 1 -LD (IY*),C 71FD 3 ZIX 1 -LD (IY*),D 72FD 3 ZIX 1 -LD (IY*),E 73FD 3 ZIX 1 -LD (IY*),H 74FD 3 ZIX 1 -LD (IY*),L 75FD 3 ZIX 1 -LD (IY*),* 36FD 4 ZIX 1 -LD (*),A 32 3 NOP 1 -LD (*),BC 43ED 4 NOP 1 -LD (*),DE 53ED 4 NOP 1 -LD (*),HL 22 3 NOP 1 -LD (*),IX 22DD 4 NOP 1 -LD (*),IY 22FD 4 NOP 1 -LD (*),SP 73ED 4 NOP 1 -LD A,(BC) 0A 1 NOP 1 -LD A,(DE) 1A 1 NOP 1 -LD A,(HL) 7E 1 NOP 1 -LD A,(IX*) 7EDD 3 ZIX 1 -LD A,(IY*) 7EFD 3 ZIX 1 -LD A,A 7F 1 NOP 1 -LD A,B 78 1 NOP 1 -LD A,C 79 1 NOP 1 -LD A,D 7A 1 NOP 1 -LD A,E 7B 1 NOP 1 -LD A,H 7C 1 NOP 1 -LD A,I 57ED 2 NOP 1 -LD A,L 7D 1 NOP 1 -LD A,R 5FED 2 NOP 1 -LD A,(*) 3A 3 NOP 1 -LD A,* 3E 2 NOP 1 -LD B,(HL) 46 1 NOP 1 -LD B,(IX*) 46DD 3 ZIX 1 -LD B,(IY*) 46FD 3 ZIX 1 -LD B,A 47 1 NOP 1 -LD B,B 40 1 NOP 1 -LD B,C 41 1 NOP 1 -LD B,D 42 1 NOP 1 -LD B,E 43 1 NOP 1 -LD B,H 44 1 NOP 1 -LD B,L 45 1 NOP 1 -LD B,* 06 2 NOP 1 -LD BC,(*) 4BED 4 NOP 1 -LD BC,* 01 3 NOP 1 -LD C,(HL) 4E 1 NOP 1 -LD C,(IX*) 4EDD 3 ZIX 1 -LD C,(IY*) 4EFD 3 ZIX 1 -LD C,A 4F 1 NOP 1 -LD C,B 48 1 NOP 1 -LD C,C 49 1 NOP 1 -LD C,D 4A 1 NOP 1 -LD C,E 4B 1 NOP 1 -LD C,H 4C 1 NOP 1 -LD C,L 4D 1 NOP 1 -LD C,* 0E 2 NOP 1 -LD D,(HL) 56 1 NOP 1 -LD D,(IX*) 56DD 3 ZIX 1 -LD D,(IY*) 56FD 3 ZIX 1 -LD D,A 57 1 NOP 1 -LD D,B 50 1 NOP 1 -LD D,C 51 1 NOP 1 -LD D,D 52 1 NOP 1 -LD D,E 53 1 NOP 1 -LD D,H 54 1 NOP 1 -LD D,L 55 1 NOP 1 -LD D,* 16 2 NOP 1 -LD DE,(*) 5BED 4 NOP 1 -LD DE,* 11 3 NOP 1 -LD E,(HL) 5E 1 NOP 1 -LD E,(IX*) 5EDD 3 ZIX 1 -LD E,(IY*) 5EFD 3 ZIX 1 -LD E,A 5F 1 NOP 1 -LD E,B 58 1 NOP 1 -LD E,C 59 1 NOP 1 -LD E,D 5A 1 NOP 1 -LD E,E 5B 1 NOP 1 -LD E,H 5C 1 NOP 1 -LD E,L 5D 1 NOP 1 -LD E,* 1E 2 NOP 1 -LD H,(HL) 66 1 NOP 1 -LD H,(IX*) 66DD 3 ZIX 1 -LD H,(IY*) 66FD 3 ZIX 1 -LD H,A 67 1 NOP 1 -LD H,B 60 1 NOP 1 -LD H,C 61 1 NOP 1 -LD H,D 62 1 NOP 1 -LD H,E 63 1 NOP 1 -LD H,H 64 1 NOP 1 -LD H,L 65 1 NOP 1 -LD H,* 26 2 NOP 1 -LD HL,(*) 2A 3 NOP 1 -LD HL,* 21 3 NOP 1 -LD I,A 47ED 2 NOP 1 -LD IX,(*) 2ADD 4 NOP 1 -LD IX,* 21DD 4 NOP 1 -LD IY,(*) 2AFD 4 NOP 1 -LD IY,* 21FD 4 NOP 1 -LD L,(HL) 6E 1 NOP 1 -LD L,(IX*) 6EDD 3 ZIX 1 -LD L,(IY*) 6EFD 3 ZIX 1 -LD L,A 6F 1 NOP 1 -LD L,B 68 1 NOP 1 -LD L,C 69 1 NOP 1 -LD L,D 6A 1 NOP 1 -LD L,E 6B 1 NOP 1 -LD L,H 6C 1 NOP 1 -LD L,L 6D 1 NOP 1 -LD L,* 2E 2 NOP 1 -LD R,A 4FED 2 NOP 1 -LD SP,(*) 7BED 4 NOP 1 -LD SP,HL F9 1 NOP 1 -LD SP,IX F9DD 2 NOP 1 -LD SP,IY F9FD 2 NOP 1 -LD SP,* 31 3 NOP 1 -LDD "" A8ED 2 NOP 1 -LDDR "" B8ED 2 NOP 1 -LDI "" A0ED 2 NOP 1 -LDIR "" B0ED 2 NOP 1 -NEG "" 44ED 2 NOP 1 -NOP "" 00 1 NOP 1 - -MLT BC 4CED 2 NOP 2 -MLT DE 5CED 2 NOP 2 -MLT HL 6CED 2 NOP 2 -MLT SP 7CED 2 NOP 2 - -OR (HL) B6 1 NOP 1 -OR (IX*) B6DD 3 ZIX 1 -OR (IY*) B6FD 3 ZIX 1 -OR A B7 1 NOP 1 -OR B B0 1 NOP 1 -OR C B1 1 NOP 1 -OR D B2 1 NOP 1 -OR E B3 1 NOP 1 -OR H B4 1 NOP 1 -OR L B5 1 NOP 1 -OR * F6 2 NOP 1 - -OTDM "" 8BED 2 NOP 2 -OTDMR "" 9BED 2 NOP 2 -OTDR "" BBED 2 NOP 1 -OTIM "" 83ED 2 NOP 2 -OTIMR "" 93ED 2 NOP 2 -OTIR "" B3ED 2 NOP 1 - -OUT (C),A 79ED 2 NOP 1 -OUT (C),B 41ED 2 NOP 1 -OUT (C),C 49ED 2 NOP 1 -OUT (C),D 51ED 2 NOP 1 -OUT (C),E 59ED 2 NOP 1 -OUT (C),H 61ED 2 NOP 1 -OUT (C),L 69ED 2 NOP 1 -OUT (*),A D3 2 NOP 1 - -OUT0 (*),A 39ED 3 NOP 2 -OUT0 (*),B 01ED 3 NOP 2 -OUT0 (*),C 09ED 3 NOP 2 -OUT0 (*),D 11ED 3 NOP 2 -OUT0 (*),E 19ED 3 NOP 2 -OUT0 (*),H 21ED 3 NOP 2 -OUT0 (*),L 29ED 3 NOP 2 - -OUTD "" ABED 2 NOP 1 -OUTI "" A3ED 2 NOP 1 - -POP AF F1 1 NOP 1 -POP BC C1 1 NOP 1 -POP DE D1 1 NOP 1 -POP HL E1 1 NOP 1 -POP IX E1DD 2 NOP 1 -POP IY E1FD 2 NOP 1 - -PUSH AF F5 1 NOP 1 -PUSH BC C5 1 NOP 1 -PUSH DE D5 1 NOP 1 -PUSH HL E5 1 NOP 1 -PUSH IX E5DD 2 NOP 1 -PUSH IY E5FD 2 NOP 1 - -RES *,(HL) 86CB 2 ZBIT 1 -RES *,(IX*) CBDD 4 ZBIT 1 0 8600 -RES *,(IY*) CBFD 4 ZBIT 1 0 8600 -RES *,A 87CB 2 ZBIT 1 -RES *,B 80CB 2 ZBIT 1 -RES *,C 81CB 2 ZBIT 1 -RES *,D 82CB 2 ZBIT 1 -RES *,E 83CB 2 ZBIT 1 -RES *,H 84CB 2 ZBIT 1 -RES *,L 85CB 2 ZBIT 1 - -RET "" C9 1 NOP 1 -RET C D8 1 NOP 1 -RET M F8 1 NOP 1 -RET NC D0 1 NOP 1 -RET NZ C0 1 NOP 1 -RET P F0 1 NOP 1 -RET PE E8 1 NOP 1 -RET PO E0 1 NOP 1 -RET Z C8 1 NOP 1 -RETI "" 4DED 2 NOP 1 -RETN "" 45ED 2 NOP 1 - -RL (HL) 16CB 2 NOP 1 -RL (IX*) CBDD 4 ZIX 1 0 1600 -RL (IY*) CBFD 4 ZIX 1 0 1600 -RL A 17CB 2 NOP 1 -RL B 10CB 2 NOP 1 -RL C 11CB 2 NOP 1 -RL D 12CB 2 NOP 1 -RL E 13CB 2 NOP 1 -RL H 14CB 2 NOP 1 -RL L 15CB 2 NOP 1 -RLA "" 17 1 NOP 1 - -RLC (HL) 06CB 2 NOP 1 -RLC (IX*) CBDD 4 ZIX 1 0 0600 -RLC (IY*) CBFD 4 ZIX 1 0 0600 -RLC A 07CB 2 NOP 1 -RLC B 00CB 2 NOP 1 -RLC C 01CB 2 NOP 1 -RLC D 02CB 2 NOP 1 -RLC E 03CB 2 NOP 1 -RLC H 04CB 2 NOP 1 -RLC L 05CB 2 NOP 1 -RLCA "" 07 1 NOP 1 -RLD "" 6FED 2 NOP 1 - -RR (HL) 1ECB 2 NOP 1 -RR (IX*) CBDD 4 ZIX 1 0 1E00 -RR (IY*) CBFD 4 ZIX 1 0 1E00 -RR A 1FCB 2 NOP 1 -RR B 18CB 2 NOP 1 -RR C 19CB 2 NOP 1 -RR D 1ACB 2 NOP 1 -RR E 1BCB 2 NOP 1 -RR H 1CCB 2 NOP 1 -RR L 1DCB 2 NOP 1 -RRA "" 1F 1 NOP 1 -RRC (HL) 0ECB 2 NOP 1 -RRC (IX*) CBDD 4 ZIX 1 0 0E00 -RRC (IY*) CBFD 4 ZIX 1 0 0E00 -RRC A 0FCB 2 NOP 1 -RRC B 08CB 2 NOP 1 -RRC C 09CB 2 NOP 1 -RRC D 0ACB 2 NOP 1 -RRC E 0BCB 2 NOP 1 -RRC H 0CCB 2 NOP 1 -RRC L 0DCB 2 NOP 1 -RRCA "" 0F 1 NOP 1 -RRD "" 67ED 2 NOP 1 - -RST 00H C7 1 NOP 1 -RST 08H CF 1 NOP 1 -RST 10H D7 1 NOP 1 -RST 18H DF 1 NOP 1 -RST 20H E7 1 NOP 1 -RST 28H EF 1 NOP 1 -RST 30H F7 1 NOP 1 -RST 38H FF 1 NOP 1 - -/* Alternate form of above -RST 00 C7 1 NOP 1 -RST 08 CF 1 NOP 1 -RST 10 D7 1 NOP 1 -RST 18 DF 1 NOP 1 -RST 20 E7 1 NOP 1 -RST 28 EF 1 NOP 1 -RST 30 F7 1 NOP 1 -RST 38 FF 1 NOP 1 - -SBC A,(HL) 9E 1 NOP 1 -SBC A,(IX*) 9EDD 3 ZIX 1 -SBC A,(IY*) 9EFD 3 ZIX 1 -SBC A,A 9F 1 NOP 1 -SBC A,B 98 1 NOP 1 -SBC A,C 99 1 NOP 1 -SBC A,D 9A 1 NOP 1 -SBC A,E 9B 1 NOP 1 -SBC A,H 9C 1 NOP 1 -SBC A,L 9D 1 NOP 1 -SBC HL,BC 42ED 2 NOP 1 -SBC HL,DE 52ED 2 NOP 1 -SBC HL,HL 62ED 2 NOP 1 -SBC HL,SP 72ED 2 NOP 1 -SBC A,* DE 2 NOP 1 -SCF "" 37 1 NOP 1 - -SET *,(HL) C6CB 2 ZBIT 1 -SET *,(IX*) CBDD 4 ZBIT 1 0 C600 -SET *,(IY*) CBFD 4 ZBIT 1 0 C600 -SET *,A C7CB 2 ZBIT 1 -SET *,B C0CB 2 ZBIT 1 -SET *,C C1CB 2 ZBIT 1 -SET *,D C2CB 2 ZBIT 1 -SET *,E C3CB 2 ZBIT 1 -SET *,H C4CB 2 ZBIT 1 -SET *,L C5CB 2 ZBIT 1 - -SLA (HL) 26CB 2 NOP 1 -SLA (IX*) CBDD 4 ZIX 1 0 2600 -SLA (IY*) CBFD 4 ZIX 1 0 2600 -SLA A 27CB 2 NOP 1 -SLA B 20CB 2 NOP 1 -SLA C 21CB 2 NOP 1 -SLA D 22CB 2 NOP 1 -SLA E 23CB 2 NOP 1 -SLA H 24CB 2 NOP 1 -SLA L 25CB 2 NOP 1 - -SLP "" 76ED 2 NOP 2 - -SRA (HL) 2ECB 2 NOP 1 -SRA (IX*) CBDD 4 ZIX 1 0 2E00 -SRA (IY*) CBFD 4 ZIX 1 0 2E00 -SRA A 2FCB 2 NOP 1 -SRA B 28CB 2 NOP 1 -SRA C 29CB 2 NOP 1 -SRA D 2ACB 2 NOP 1 -SRA E 2BCB 2 NOP 1 -SRA H 2CCB 2 NOP 1 -SRA L 2DCB 2 NOP 1 - -SRL (HL) 3ECB 2 NOP 1 -SRL (IX*) CBDD 4 ZIX 1 0 3E00 -SRL (IY*) CBFD 4 ZIX 1 0 3E00 -SRL A 3FCB 2 NOP 1 -SRL B 38CB 2 NOP 1 -SRL C 39CB 2 NOP 1 -SRL D 3ACB 2 NOP 1 -SRL E 3BCB 2 NOP 1 -SRL H 3CCB 2 NOP 1 -SRL L 3DCB 2 NOP 1 - -SUB (HL) 96 1 NOP 1 -SUB (IX*) 96DD 3 ZIX 1 -SUB (IY*) 96FD 3 ZIX 1 -SUB A 97 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB * D6 2 NOP 1 - -TST A 3CED 2 NOP 2 -TST B 04ED 2 NOP 2 -TST C 0CED 2 NOP 2 -TST D 14ED 2 NOP 2 -TST E 1CED 2 NOP 2 -TST H 24ED 2 NOP 2 -TST L 2CED 2 NOP 2 -TST (HL) 34ED 2 NOP 2 -TST * 64ED 3 NOP 2 - -TSTIO * 74ED 3 NOP 2 - -XOR (HL) AE 1 NOP 1 -XOR (IX*) AEDD 3 ZIX 1 -XOR (IY*) AEFD 3 ZIX 1 -XOR A AF 1 NOP 1 -XOR B A8 1 NOP 1 -XOR C A9 1 NOP 1 -XOR D AA 1 NOP 1 -XOR E AB 1 NOP 1 -XOR H AC 1 NOP 1 -XOR L AD 1 NOP 1 -XOR * EE 2 NOP 1 diff --git a/branches/s100/LSource/bin/TASM85.TAB b/branches/s100/LSource/bin/TASM85.TAB deleted file mode 100644 index 83c866bb..00000000 --- a/branches/s100/LSource/bin/TASM85.TAB +++ /dev/null @@ -1,257 +0,0 @@ -"TASM 8085 Assembler. " -/**************************************************************************** -/* $Id: tasm85.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8085 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Gary Kirk Bach. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS */ -/*-----------------*/ -ACI * CE 2 NOP 1 -ADC B 88 1 NOP 1 -ADC C 89 1 NOP 1 -ADC D 8A 1 NOP 1 -ADC E 8B 1 NOP 1 -ADC H 8C 1 NOP 1 -ADC L 8D 1 NOP 1 -ADC M 8E 1 NOP 1 -ADC A 8F 1 NOP 1 -ADD B 80 1 NOP 1 -ADD C 81 1 NOP 1 -ADD D 82 1 NOP 1 -ADD E 83 1 NOP 1 -ADD H 84 1 NOP 1 -ADD L 85 1 NOP 1 -ADD M 86 1 NOP 1 -ADD A 87 1 NOP 1 -ADI * C6 2 NOP 1 -ANA B A0 1 NOP 1 -ANA C A1 1 NOP 1 -ANA D A2 1 NOP 1 -ANA E A3 1 NOP 1 -ANA H A4 1 NOP 1 -ANA L A5 1 NOP 1 -ANA M A6 1 NOP 1 -ANA A A7 1 NOP 1 -ANI * E6 2 NOP 1 -CALL * CD 3 NOP 1 -CC * DC 3 NOP 1 -CM * FC 3 NOP 1 -CMA "" 2F 1 NOP 1 -CMC "" 3F 1 NOP 1 -CMP B B8 1 NOP 1 -CMP C B9 1 NOP 1 -CMP D BA 1 NOP 1 -CMP E BB 1 NOP 1 -CMP H BC 1 NOP 1 -CMP L BD 1 NOP 1 -CMP M BE 1 NOP 1 -CMP A BF 1 NOP 1 -CNC * D4 3 NOP 1 -CNZ * C4 3 NOP 1 -CP * F4 3 NOP 1 -CPE * EC 3 NOP 1 -CPI * FE 2 NOP 1 -CPO * E4 3 NOP 1 -CZ * CC 3 NOP 1 -DAA "" 27 1 NOP 1 -DAD B 09 1 NOP 1 -DAD D 19 1 NOP 1 -DAD H 29 1 NOP 1 -DAD SP 39 1 NOP 1 -DCR B 05 1 NOP 1 -DCR C 0D 1 NOP 1 -DCR D 15 1 NOP 1 -DCR E 1D 1 NOP 1 -DCR H 25 1 NOP 1 -DCR L 2D 1 NOP 1 -DCR M 35 1 NOP 1 -DCR A 3D 1 NOP 1 -DCX B 0B 1 NOP 1 -DCX D 1B 1 NOP 1 -DCX H 2B 1 NOP 1 -DCX SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -EI "" FB 1 NOP 1 -HLT "" 76 1 NOP 1 -IN * DB 2 NOP 1 -INR B 04 1 NOP 1 -INR C 0C 1 NOP 1 -INR D 14 1 NOP 1 -INR E 1C 1 NOP 1 -INR H 24 1 NOP 1 -INR L 2C 1 NOP 1 -INR M 34 1 NOP 1 -INR A 3C 1 NOP 1 -INX B 03 1 NOP 1 -INX D 13 1 NOP 1 -INX H 23 1 NOP 1 -INX SP 33 1 NOP 1 -JC * DA 3 NOP 1 -JM * FA 3 NOP 1 -JMP * C3 3 NOP 1 -JNC * D2 3 NOP 1 -JNZ * C2 3 NOP 1 -JP * F2 3 NOP 1 -JPE * EA 3 NOP 1 -JPO * E2 3 NOP 1 -JZ * CA 3 NOP 1 -LDA * 3A 3 NOP 1 -LDAX B 0A 1 NOP 1 -LDAX D 1A 1 NOP 1 -LHLD * 2A 3 NOP 1 -LXI B,* 01 3 NOP 1 -LXI D,* 11 3 NOP 1 -LXI H,* 21 3 NOP 1 -LXI SP,* 31 3 NOP 1 -MOV B,B 40 1 NOP 1 -MOV B,C 41 1 NOP 1 -MOV B,D 42 1 NOP 1 -MOV B,E 43 1 NOP 1 -MOV B,H 44 1 NOP 1 -MOV B,L 45 1 NOP 1 -MOV B,M 46 1 NOP 1 -MOV B,A 47 1 NOP 1 -MOV C,B 48 1 NOP 1 -MOV C,C 49 1 NOP 1 -MOV C,D 4A 1 NOP 1 -MOV C,E 4B 1 NOP 1 -MOV C,H 4C 1 NOP 1 -MOV C,L 4D 1 NOP 1 -MOV C,M 4E 1 NOP 1 -MOV C,A 4F 1 NOP 1 -MOV D,B 50 1 NOP 1 -MOV D,C 51 1 NOP 1 -MOV D,D 52 1 NOP 1 -MOV D,E 53 1 NOP 1 -MOV D,H 54 1 NOP 1 -MOV D,L 55 1 NOP 1 -MOV D,M 56 1 NOP 1 -MOV D,A 57 1 NOP 1 -MOV E,B 58 1 NOP 1 -MOV E,C 59 1 NOP 1 -MOV E,D 5A 1 NOP 1 -MOV E,E 5B 1 NOP 1 -MOV E,H 5C 1 NOP 1 -MOV E,L 5D 1 NOP 1 -MOV E,M 5E 1 NOP 1 -MOV E,A 5F 1 NOP 1 -MOV H,B 60 1 NOP 1 -MOV H,C 61 1 NOP 1 -MOV H,D 62 1 NOP 1 -MOV H,E 63 1 NOP 1 -MOV H,H 64 1 NOP 1 -MOV H,L 65 1 NOP 1 -MOV H,M 66 1 NOP 1 -MOV H,A 67 1 NOP 1 -MOV L,B 68 1 NOP 1 -MOV L,C 69 1 NOP 1 -MOV L,D 6A 1 NOP 1 -MOV L,E 6B 1 NOP 1 -MOV L,H 6C 1 NOP 1 -MOV L,L 6D 1 NOP 1 -MOV L,M 6E 1 NOP 1 -MOV L,A 6F 1 NOP 1 -MOV M,B 70 1 NOP 1 -MOV M,C 71 1 NOP 1 -MOV M,D 72 1 NOP 1 -MOV M,E 73 1 NOP 1 -MOV M,H 74 1 NOP 1 -MOV M,L 75 1 NOP 1 -MOV M,A 77 1 NOP 1 -MOV A,B 78 1 NOP 1 -MOV A,C 79 1 NOP 1 -MOV A,D 7A 1 NOP 1 -MOV A,E 7B 1 NOP 1 -MOV A,H 7C 1 NOP 1 -MOV A,L 7D 1 NOP 1 -MOV A,M 7E 1 NOP 1 -MOV A,A 7F 1 NOP 1 -MVI B,* 06 2 NOP 1 -MVI C,* 0E 2 NOP 1 -MVI D,* 16 2 NOP 1 -MVI E,* 1E 2 NOP 1 -MVI H,* 26 2 NOP 1 -MVI L,* 2E 2 NOP 1 -MVI M,* 36 2 NOP 1 -MVI A,* 3E 2 NOP 1 -NOP "" 00 1 NOP 1 -ORA B B0 1 NOP 1 -ORA C B1 1 NOP 1 -ORA D B2 1 NOP 1 -ORA E B3 1 NOP 1 -ORA H B4 1 NOP 1 -ORA L B5 1 NOP 1 -ORA M B6 1 NOP 1 -ORA A B7 1 NOP 1 -ORI * F6 2 NOP 1 -OUT * D3 2 NOP 1 -PCHL "" E9 1 NOP 1 -POP B C1 1 NOP 1 -POP D D1 1 NOP 1 -POP H E1 1 NOP 1 -POP PSW F1 1 NOP 1 -PUSH B C5 1 NOP 1 -PUSH D D5 1 NOP 1 -PUSH H E5 1 NOP 1 -PUSH PSW F5 1 NOP 1 -RAL "" 17 1 NOP 1 -RAR "" 1F 1 NOP 1 -RC "" D8 1 NOP 1 -RET "" C9 1 NOP 1 -RIM "" 20 1 NOP 1 -RLC "" 07 1 NOP 1 -RM "" F8 1 NOP 1 -RNC "" D0 1 NOP 1 -RNZ "" C0 1 NOP 1 -RP "" F0 1 NOP 1 -RPE "" E8 1 NOP 1 -RPO "" E0 1 NOP 1 -RRC "" 0F 1 NOP 1 -RST 0 C7 1 NOP 1 -RST 1 CF 1 NOP 1 -RST 2 D7 1 NOP 1 -RST 3 DF 1 NOP 1 -RST 4 E7 1 NOP 1 -RST 5 EF 1 NOP 1 -RST 6 F7 1 NOP 1 -RST 7 FF 1 NOP 1 -RZ "" C8 1 NOP 1 -SBB B 98 1 NOP 1 -SBB C 99 1 NOP 1 -SBB D 9A 1 NOP 1 -SBB E 9B 1 NOP 1 -SBB H 9C 1 NOP 1 -SBB L 9D 1 NOP 1 -SBB M 9E 1 NOP 1 -SBB A 9F 1 NOP 1 -SBI * DE 2 NOP 1 -SHLD * 22 3 NOP 1 -SIM "" 30 1 NOP 1 -SPHL "" F9 1 NOP 1 -STA * 32 3 NOP 1 -STAX B 02 1 NOP 1 -STAX D 12 1 NOP 1 -STC "" 37 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB M 96 1 NOP 1 -SUB A 97 1 NOP 1 -SUI * D6 2 NOP 1 -XCHG "" EB 1 NOP 1 -XRA B A8 1 NOP 1 -XRA C A9 1 NOP 1 -XRA D AA 1 NOP 1 -XRA E AB 1 NOP 1 -XRA H AC 1 NOP 1 -XRA L AD 1 NOP 1 -XRA M AE 1 NOP 1 -XRA A AF 1 NOP 1 -XRI * EE 2 NOP 1 -XTHL "" E3 1 NOP 1 - diff --git a/branches/s100/LSource/bin/TASM96.TAB b/branches/s100/LSource/bin/TASM96.TAB deleted file mode 100644 index ca6669b6..00000000 --- a/branches/s100/LSource/bin/TASM96.TAB +++ /dev/null @@ -1,393 +0,0 @@ -"TASM 8096 Assembler." -/**************************************************************************** -/* $Id: tasm96.tab 1.5 1997/09/28 22:14:30 toma Exp $ -/**************************************************************************** -;* This is the instruction set definition table -;* for the 8096 version of TASM. -;* Thomas N. Anderson, Speech Technology Incorporated -;* -;* See TASM manual for info on table structure. -;* -;*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK -;*-------------------------------------------* -; Revisions: -; Added I7 rule for single arg direct/far (PUSH/POP) -; Changed ADDB *,*,*[*] entry from rule I1 to I6. -; -; Generate opcodes high byte first/ -.MSFIRST -.NOARGSHIFT -; -; Note: -; The I1 rule uses ARGVAL for arg validation. If the combined -; args AND ARGVAL is not equal to the combined args then an -; error message is generated. -; -; The I1 rule also uses ARGOR. The value of that mask is OR'd -; with the first byte of the args. -; -; ARGOR -; BYTES CLASS | -; | | | -;INST ARGS OP v RULE v v ARGVAL -;-----------------------------------------; -;OK ADD -ADD *,*,[*]+ 46 4 I1 1 01 00FeFeFe ; -ADD *,*,[*] 46 4 I1 1 00 00FeFeFe ; -ADD *,*,*[*] 47 6 I6 1 00 00FeFeFe ; -ADD *,*,#* 45 5 I1 1 00 FeFeFFFF ; -ADD *,[*]+ 66 3 I1 1 01 0000FFFe ; 1st arg must be even, make odd -ADD *,[*] 66 3 I1 1 00 0000FFFe ; 1st arg must be even -ADD *,*[*] 67 5 I6 1 00 00FFFFFF ; -ADD *,*,* 4701 6 I3 1 00 0000FeFe ; 3rd arg may be far -ADD *,#* 65 4 I1 1 00 00FeFFFF ; 1st arg must be even -ADD *,* 6701 5 I2 1 00 0000FeFe ; 2nd arg may be far - -;OK ADDB -ADDB *,*,[*]+ 56 4 I1 1 01 00000000 ; no validation yet -ADDB *,*,[*] 56 4 I1 1 00 00000000 ; no validation yet -ADDB *,*,*[*] 57 6 I6 1 00 00000000 ; no validation yet -ADDB *,*,#* 55 4 I1 1 00 00000000 ; no validation yet -ADDB *,[*]+ 76 3 I1 1 01 0000FFFe ; 1st arg must be even, make odd -ADDB *,[*] 76 3 I1 1 00 0000FFFe ; 1st arg must be even -ADDB *,*[*] 77 5 I6 1 00 00FeFFFe ; 1st,3rd must be even -ADDB *,*,* 5701 6 I3 1 00 00000000 ; 3rd arg may be far -ADDB *,#* 75 3 I1 1 00 00FFFFFF ; odd args ok for byte operations -ADDB *,* 7701 5 I2 1 00 00000000 ; 2nd arg may be far - -; No three arg forms for ADDC or ADDCB -ADDC *,[*]+ A6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ADDC *,[*] A6 3 I1 1 00 0000FFFe ;1st arg must be even -ADDC *,*[*] A7 5 I6 1 00 00FFFFFF ; -ADDC *,#* A5 4 I1 1 00 00FeFFFF ;1st arg must be even -ADDC *,* A701 5 I2 1 00 00000000 ;2nd arg may be far - -ADDCB *,[*]+ B6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ADDCB *,[*] B6 3 I1 1 00 0000FFFe ;1st arg must be even -ADDCB *,*[*] B7 5 I6 1 00 00FFFFFF ; -ADDCB *,#* B5 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ADDCB *,* B701 5 I2 1 00 00000000 ;2nd arg may be far - -; OK AND -AND *,*,[*]+ 42 4 I1 1 01 00000000 ;no validation yet -AND *,*,[*] 42 4 I1 1 00 00000000 ;no validation yet -AND *,*,*[*] 43 6 I6 1 00 00000000 ;no validation yet -AND *,*,#* 41 5 I1 1 00 00000000 ;no validation yet -AND *,[*]+ 62 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -AND *,[*] 62 3 I1 1 00 0000FFFe ;1st arg must be even -AND *,*[*] 63 5 I6 1 00 00FeFFFe ;1st,3rd must be even -AND *,*,* 4301 6 I3 1 00 00000000 ;3rd arg may be far -AND *,#* 61 4 I1 1 00 00FeFFFF ;1st arg must be even -AND *,* 6301 5 I2 1 00 00000000 ;2nd arg may be far - -ANDB *,*,[*]+ 52 4 I1 1 01 00000000 ;no validation yet -ANDB *,*,[*] 52 4 I1 1 00 00000000 ;no validation yet -ANDB *,*,*[*] 53 6 I6 1 00 00000000 ;no validation yet -ANDB *,*,#* 51 4 I1 1 00 00000000 ;no validation yet -ANDB *,[*]+ 72 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ANDB *,[*] 72 3 I1 1 00 0000FFFe ;1st arg must be even -ANDB *,*[*] 73 5 I6 1 00 00FFFFFF ; -ANDB *,*,* 5301 6 I3 1 00 00000000 ;3rd arg may be far -ANDB *,#* 71 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ANDB *,* 7301 5 I2 1 00 00000000 ;2nd arg may be far - -BMOV *,* C1 3 I1 2 00 0000FcFF ;long word ptr to two words -BMOVI *,* AD 3 I1 2 00 0000FcFF ;long word ptr to two words - -BR [*] E3 2 I1 1 00 00000000 ; -BR * 2000 2 I5 1 00 00000000 ; Same As SJMP - -CLR * 01 2 NOP 1 00 00000000 ; -CLRB * 11 2 NOP 1 00 00000000 ; -CLRC "" F8 1 NOP 1 00 00000000 ; -CLRVT "" FC 1 NOP 1 00 00000000 ; - -CMP *,[*]+ 8A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -CMP *,[*] 8A 3 I1 1 00 0000FFFe ;1st arg must be even -CMP *,*[*] 8B 5 I6 1 00 00FFFFFF ; -CMP *,#* 89 4 I1 1 00 00FeFFFF ;1st arg must be even -CMP *,* 8B01 5 I2 1 00 00000000 ;2nd arg may be far - -CMPB *,[*]+ 9A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -CMPB *,[*] 9A 3 I1 1 00 0000FFFe ;1st arg must be even -CMPB *,*[*] 9B 5 I6 1 00 00FFFFFF ; -CMPB *,#* 99 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -CMPB *,* 9B01 5 I2 1 00 00000000 ;2nd arg may be far - -CMPL *,* C5 3 I1 2 00 0000FcFc ;long align multiple of 4 - -DEC * 05 2 NOP 1 00 00000000 ; -DECB * 15 2 NOP 1 00 00000000 ; -DJNZ *,* E0 3 CREL 1 00 00000000 ; -DJNZW *,* E1 3 CREL 2 00 00000000 ; - -DI "" FA 1 NOP 1 00 00000000 ; - -DIVU *,[*]+ 8E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVU *,[*] 8E 3 I1 1 00 0000FFFe ;1st arg must be even -DIVU *,*[*] 8F 5 I6 1 00 0000FFFe ;1st arg must be even -DIVU *,#* 8D 4 I1 1 00 00FeFFFF ;1st arg must be even -DIVU *,* 8F01 5 I2 1 00 00000000 ;2nd arg may be far - -DIVUB *,[*]+ 9E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVUB *,[*] 9E 3 I1 1 00 0000FFFe ;1st arg must be even -DIVUB *,*[*] 9F 5 I6 1 00 0000FFFF ; -DIVUB *,#* 9D 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -DIVUB *,* 9F01 5 I2 1 00 00000000 ;2nd arg may be far - -DIV *,[*]+ FE8E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIV *,[*] FE8E 4 I1 1 00 0000FFFe ;1st arg must be even -DIV *,*[*] FE8F 6 I6 1 00 0000FFFe ;1st arg must be even -DIV *,#* FE8D 5 I1 1 00 00FeFFFF ;1st arg must be even -DIV *,* FE8F01 6 I2 1 00 00000000 ;2nd arg may be far - -DIVB *,[*]+ FE9E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVB *,[*] FE9E 4 I1 1 00 0000FFFe ;1st arg must be even -DIVB *,*[*] FE9F 6 I6 1 00 0000FFFF ; -DIVB *,#* FE9D 4 I1 1 00 00FFFFFF ;odd args ok for byte operations; -DIVB *,* FE9F01 6 I2 1 00 00000000 ;2nd arg may be far - -DPTS "" EC 1 NOP 2 00 00000000 ; -EPTS "" ED 1 NOP 2 00 00000000 ; - -EI "" FB 1 NOP 1 00 00000000 ; - -EXT * 06 2 NOP 1 00 00000000 ; -EXTB * 16 2 NOP 1 00 00000000 ; - -IDLPD #* F6 2 NOP 2 00 00000000 ; - -INC * 07 2 NOP 1 00 00000000 ; -INCB * 17 2 NOP 1 00 00000000 ; - -JC * DB 2 R1 1 00 00000000 -JNC * D3 2 R1 1 00 00000000 -JH * D9 2 R1 1 00 00000000 -JNH * D1 2 R1 1 00 00000000 -JE * DF 2 R1 1 00 00000000 -JNE * D7 2 R1 1 00 00000000 -JV * DD 2 R1 1 00 00000000 -JNV * D5 2 R1 1 00 00000000 -JGE * D6 2 R1 1 00 00000000 -JLT * DE 2 R1 1 00 00000000 -JVT * DC 2 R1 1 00 00000000 -JNVT * D4 2 R1 1 00 00000000 -JGT * D2 2 R1 1 00 00000000 -JLE * DA 2 R1 1 00 00000000 -JST * D8 2 R1 1 00 00000000 -JNST * D0 2 R1 1 00 00000000 - -JBC *,*,* 30 3 I4 1 00 00000000 -JBS *,*,* 38 3 I4 1 00 00000000 - -LJMP * E7 3 R2 1 00 00000000 -LCALL * EF 3 R2 1 00 00000000 - -LD *,[*]+ A2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LD *,[*] A2 3 I1 1 00 0000FFFe ;1st arg must be even -LD *,*[*] A3 5 I6 1 00 00FFFFFF ; -LD *,#* A1 4 I1 1 00 00FFFFFF ; -LD *,* A301 5 I2 1 00 00000000 ;2nd arg may be far - -LDB *,[*]+ B2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDB *,[*] B2 3 I1 1 00 0000FFFe ;1st arg must be even -LDB *,*[*] B3 5 I6 1 00 00FFFFFF ; -LDB *,#* B1 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDB *,* B301 5 I2 1 00 00000000 ;2nd arg may be far - -LDBSE *,[*]+ BE 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDBSE *,[*] BE 3 I1 1 00 0000FFFe ;1st arg must be even -LDBSE *,*[*] BF 5 I6 1 00 00FeFFFe ;1st,3rd must be even -LDBSE *,#* BD 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDBSE *,* BF01 5 I2 1 00 00000000 ;2nd arg may be far - -LDBZE *,[*]+ AE 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDBZE *,[*] AE 3 I1 1 00 0000FFFe ;1st arg must be even -LDBZE *,*[*] AF 5 I6 1 00 00FeFFFe ;1st,3rd must be even -LDBZE *,#* AD 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDBZE *,* AF01 5 I2 1 00 00000000 ;2nd arg may be far - -MULU *,*,[*]+ 4E 4 I1 1 01 00000000 ;no validation yet -MULU *,*,[*] 4E 4 I1 1 00 00000000 ;no validation yet -MULU *,*,*[*] 4F 6 I6 1 00 00000000 ;no validation yet -MULU *,*,#* 4D 5 I1 1 00 00000000 ;no validation yet -MULU *,[*]+ 6E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULU *,[*] 6E 3 I1 1 00 0000FFFe ;1st arg must be even -MULU *,*[*] 6F 5 I6 1 00 00FeFFFe ;1st,3rd must be even -MULU *,*,* 4F01 6 I3 1 00 00000000 ;3rd arg may be far -MULU *,#* 6D 4 I1 1 00 00FeFFFF ;1st arg must be even -MULU *,* 6F01 5 I2 1 00 00000000 ;2nd arg may be far - - -MULUB *,*,[*]+ 5E 4 I1 1 01 00000000 ;no validation yet -MULUB *,*,[*] 5E 4 I1 1 00 00000000 ;no validation yet -MULUB *,*,*[*] 5F 6 I6 1 00 00000000 ;no validation yet -MULUB *,*,#* 5D 4 I1 1 00 00000000 ;no validation yet -MULUB *,[*]+ 7E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULUB *,[*] 7E 3 I1 1 00 0000FFFe ;1st arg must be even -MULUB *,*[*] 7F 5 I6 1 00 00FFFFFF ; -MULUB *,*,* 5F01 6 I3 1 00 00000000 ;3rd arg may be far -MULUB *,#* 7D 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -MULUB *,* 7F01 5 I2 1 00 00000000 ;2nd arg may be far - -MUL *,*,[*]+ FE4E 5 I1 1 01 00000000 ;no validation yet -MUL *,*,[*] FE4E 5 I1 1 00 00000000 ;no validation yet -MUL *,*,*[*] FE4F 7 I6 1 00 00000000 ;no validation yet -MUL *,*,#* FE4D 6 I1 1 00 00000000 ;no validation yet -MUL *,[*]+ FE6E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -MUL *,[*] FE6E 4 I1 1 00 0000FFFe ;1st arg must be even -MUL *,*[*] FE6F 6 I6 1 00 00FeFFFe ;1st,3rd must be even -MUL *,*,* FE4F01 7 I3 1 00 00000000 ;3rd arg may be far -MUL *,#* FE6D 5 I1 1 00 00FFFFFF ;odd args ok for byte operations -MUL *,* FE6F01 6 I2 1 00 00000000 ;2nd arg may be far - -MULB *,*,[*]+ FE5E 5 I1 1 01 00000000 ;no validation yet -MULB *,*,[*] FE5E 5 I1 1 00 00000000 ;no validation yet -MULB *,*,*[*] FE5F 7 I6 1 00 00000000 ;no validation yet -MULB *,*,#* FE5D 5 I1 1 00 00000000 ;no validation yet -MULB *,[*]+ FE7E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULB *,[*] FE7E 4 I1 1 00 0000FFFe ;1st arg must be even -MULB *,*[*] FE7F 6 I6 1 00 00FFFFFF ; -MULB *,*,* FE5F01 7 I3 1 00 00000000 ;3rd arg may be far -MULB *,#* FE7D 4 I1 1 00 00FFFFFF ;odd args ok for byte operations -MULB *,* FE7F01 6 I2 1 00 00000000 ;2nd arg may be far - -NEG * 03 2 I1 1 00 000000FE ;arg must be even -NEGB * 13 2 I1 1 00 000000FF ; - -NOP "" FD 1 NOP 1 00 00000000 ; - -NORML *,* 0F 3 I1 1 00 0000FFFF ;long align - -NOT * 02 2 NOP 1 00 00000000 ; -NOTB * 12 2 NOP 1 00 00000000 ; - -OR *,[*]+ 82 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -OR *,[*] 82 3 I1 1 00 0000FFFe ;1st arg must be even -OR *,*[*] 83 5 I6 1 00 00FeFFFe ;1st,3rd must be even -OR *,#* 81 4 I1 1 00 00FeFFFF ;1st arg must be even -OR *,* 8301 5 I2 1 00 00000000 ;2nd arg may be far - -ORB *,[*]+ 92 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ORB *,[*] 92 3 I1 1 00 0000FFFe ;1st arg must be even -ORB *,*[*] 93 5 I6 1 00 00FFFFFF ; -ORB *,#* 91 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ORB *,* 9301 5 I2 1 00 00000000 ;2nd arg may be far - -PUSH #* C9 3 I1 1 00 00000000 ; -PUSH [*]+ CA 2 I1 1 01 000000Fe ;arg must be even -PUSH [*] CA 2 I1 1 00 000000Fe ;arg must be even -PUSH *[*] CB 4 I6 1 00 00FFFFFe ;arg must be even -PUSH * CB01 4 I7 1 00 0000FFFe ;arg must be even - -PUSHF "" F2 1 NOP 1 00 00000000 ; -PUSHA "" F4 1 NOP 1 00 00000000 ; - -POP [*]+ CE 2 I1 1 01 000000Fe ;arg must be even -POP [*] CE 2 I1 1 00 000000Fe ;arg must be even -POP *[*] CF 4 I6 1 00 00FFFFFE ; -POP * CF01 4 I7 1 00 0000FFFe ;arg must be even - -POPF "" F3 1 NOP 1 00 00000000 ; -POPA "" F5 1 NOP 1 00 00000000 ; - -RET "" F0 1 NOP 1 00 00000000 ; -RST "" FF 1 NOP 1 00 00000000 ; - -SJMP * 2000 2 I5 1 00 00000000 -SCALL * 2800 2 I5 1 00 00000000 - -SUB *,*,[*]+ 4A 4 I1 1 01 00000000 ;no validation yet -SUB *,*,[*] 4A 4 I1 1 00 00000000 ;no validation yet -SUB *,*,*[*] 4B 6 I6 1 00 00000000 ;no validation yet -SUB *,*,#* 49 5 I1 1 00 00000000 ;no validation yet -SUB *,[*]+ 6A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUB *,[*] 6A 3 I1 1 00 0000FFFe ;1st arg must be even -SUB *,*[*] 6B 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUB *,*,* 4B01 6 I3 1 00 00000000 ;3rd arg may be far -SUB *,#* 69 4 I1 1 00 00FeFFFF ;1st arg must be even -SUB *,* 6B01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBB *,*,[*]+ 5A 4 I1 1 01 00000000 ;no validation yet -SUBB *,*,[*] 5A 4 I1 1 00 00000000 ;no validation yet -SUBB *,*,*[*] 5B 6 I6 1 00 00000000 ;no validation yet -SUBB *,*,#* 59 4 I1 1 00 00000000 ;no validation yet -SUBB *,[*]+ 7A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBB *,[*] 7A 3 I1 1 00 0000FFFe ;1st arg must be even -SUBB *,*[*] 7B 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBB *,*,* 5B01 6 I3 1 00 00000000 ;3rd arg may be far -SUBB *,#* 79 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -SUBB *,* 7B01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBC *,[*]+ AA 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBC *,[*] AA 3 I1 1 00 0000FFFe ;1st arg must be even -SUBC *,*[*] AB 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBC *,#* A9 4 I1 1 00 00FeFFFF ;1st arg must be even -SUBC *,* AB01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBCB *,[*]+ BA 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBCB *,[*] BA 3 I1 1 00 0000FFFe ;1st arg must be even -SUBCB *,*[*] BB 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBCB *,#* B9 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -SUBCB *,* BB01 5 I2 1 00 00000000 ;2nd arg may be far - -SHL *,#* 09 3 I1 1 00 0000FE0F ; F -SHL *,* 09 3 I1 1 00 0000FEFF ; -SHLB *,#* 19 3 I1 1 00 0000FF0F ; -SHLB *,* 19 3 I1 1 00 0000FFFF ; -SHLL *,#* 0D 3 I1 1 00 0000FF0F ; -SHLL *,* 0D 3 I1 1 00 0000FFFF ; - -SHR *,#* 08 3 I1 1 00 0000FF0F ;word align -SHR *,* 08 3 I1 1 00 0000FFFF ;word align -SHRB *,#* 18 3 I1 1 00 0000FF0F ;byte align -SHRB *,* 18 3 I1 1 00 0000FFFF ;byte align -SHRL *,#* 0C 3 I1 1 00 0000FF0F ;long align -SHRL *,* 0C 3 I1 1 00 0000FFFF ;long align - -SHRA *,#* 0A 3 I1 1 00 0000FF0F ;word align -SHRA *,* 0A 3 I1 1 00 0000FFFF ;word align -SHRAB *,#* 1A 3 I1 1 00 0000FF0F ;byte align -SHRAB *,* 1A 3 I1 1 00 0000FFFF ;byte align -SHRAL *,#* 0E 3 I1 1 00 0000FF0F ;long align -SHRAL *,* 0E 3 I1 1 00 0000FFFF ;long align - -SETC "" F9 1 NOP 1 00 00000000 ; - - -SKIP "" 0000 2 NOP 1 00 00000000 ; -SKIP * 00 2 I1 1 00 00000000 ; - -ST *,[*]+ C2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ST *,[*] C2 3 I1 1 00 0000FFFe ;1st arg must be even -ST *,*[*] C3 5 I6 1 00 FFFFFFFe ;1st,3rd must be even -ST *,* C301 5 I2 1 00 00000000 ;2nd arg may be far - -STB *,[*]+ C6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -STB *,[*] C6 3 I1 1 00 0000FFFe ;1st arg must be even -STB *,*[*] C7 5 I6 1 00 FFFFFFFe ;1st,3rd must be even -STB *,* C701 5 I2 1 00 00000000 ;2nd arg may be far - -TRAP "" F7 1 NOP 1 00 00000000 ; - -TIJMP *,[*],#* E2 4 I8 2 00 00FEFEFF ; - -XCH *,*[*] 0B 5 I6 2 00 00FeFFFe ;1st,3rd must be even -XCH *,* 0B01 5 I2 2 0C 00000000 ;2nd arg may be far - -XCHB *,*[*] 1B 5 I6 2 00 00FFFFFF ; -XCHB *,* 1B01 5 I2 2 0C 00000000 ;2nd arg may be far - -XOR *,[*]+ 86 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -XOR *,[*] 86 3 I1 1 00 0000FFFe ;1st arg must be even -XOR *,*[*] 87 5 I6 1 00 00FeFFFe ;1st,3rd must be even -XOR *,#* 85 4 I1 1 00 00FeFFFF ;1st arg must be even -XOR *,* 8701 5 I2 1 00 00000000 ;2nd arg may be far - -XORB *,[*]+ 96 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -XORB *,[*] 96 3 I1 1 00 0000FFFe ;1st arg must be even -XORB *,*[*] 97 5 I6 1 00 00FFFFFF ; -XORB *,#* 95 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -XORB *,* 9701 5 I2 1 00 00000000 ;2nd arg may be far - - diff --git a/branches/s100/LSource/bin/tasm180.tab b/branches/s100/LSource/bin/tasm180.tab deleted file mode 100644 index a3dd5839..00000000 --- a/branches/s100/LSource/bin/tasm180.tab +++ /dev/null @@ -1,594 +0,0 @@ -"TASM Z180 Assembler. " -/**************************************************************************** -/* $Id: tasm80.tab 1.2 1998/02/28 14:31:22 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the Z80 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Carl A. Wall, VE3APY. -/* -/* Class bits assigned as follows: -/* Bit-0 = Z80 (base instruction set) -/* Bit-1 = HD64180 (extended instructions) -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OP BYTES RULE CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC A,(HL) 8E 1 NOP 1 -ADC A,(IX*) 8EDD 3 ZIX 1 -ADC A,(IY*) 8EFD 3 ZIX 1 -ADC A,A 8F 1 NOP 1 -ADC A,B 88 1 NOP 1 -ADC A,C 89 1 NOP 1 -ADC A,D 8A 1 NOP 1 -ADC A,E 8B 1 NOP 1 -ADC A,H 8C 1 NOP 1 -ADC A,L 8D 1 NOP 1 -ADC A,* CE 2 NOP 1 -ADC HL,BC 4AED 2 NOP 1 -ADC HL,DE 5AED 2 NOP 1 -ADC HL,HL 6AED 2 NOP 1 -ADC HL,SP 7AED 2 NOP 1 - -ADD A,(HL) 86 1 NOP 1 -ADD A,(IX*) 86DD 3 ZIX 1 -ADD A,(IY*) 86FD 3 ZIX 1 -ADD A,A 87 1 NOP 1 -ADD A,B 80 1 NOP 1 -ADD A,C 81 1 NOP 1 -ADD A,D 82 1 NOP 1 -ADD A,E 83 1 NOP 1 -ADD A,H 84 1 NOP 1 -ADD A,L 85 1 NOP 1 -ADD A,* C6 2 NOP 1 -ADD HL,BC 09 1 NOP 1 -ADD HL,DE 19 1 NOP 1 -ADD HL,HL 29 1 NOP 1 -ADD HL,SP 39 1 NOP 1 -ADD IX,BC 09DD 2 NOP 1 -ADD IX,DE 19DD 2 NOP 1 -ADD IX,IX 29DD 2 NOP 1 -ADD IX,SP 39DD 2 NOP 1 -ADD IY,BC 09FD 2 NOP 1 -ADD IY,DE 19FD 2 NOP 1 -ADD IY,IY 29FD 2 NOP 1 -ADD IY,SP 39FD 2 NOP 1 - -AND (HL) A6 1 NOP 1 -AND (IX*) A6DD 3 ZIX 1 -AND (IY*) A6FD 3 ZIX 1 -AND A A7 1 NOP 1 -AND B A0 1 NOP 1 -AND C A1 1 NOP 1 -AND D A2 1 NOP 1 -AND E A3 1 NOP 1 -AND H A4 1 NOP 1 -AND L A5 1 NOP 1 -AND * E6 2 NOP 1 - -BIT *,(HL) 46CB 2 ZBIT 1 -BIT *,(IX*) CBDD 4 ZBIT 1 0 4600 -BIT *,(IY*) CBFD 4 ZBIT 1 0 4600 -BIT *,A 47CB 2 ZBIT 1 -BIT *,B 40CB 2 ZBIT 1 -BIT *,C 41CB 2 ZBIT 1 -BIT *,D 42CB 2 ZBIT 1 -BIT *,E 43CB 2 ZBIT 1 -BIT *,H 44CB 2 ZBIT 1 -BIT *,L 45CB 2 ZBIT 1 - -CALL C,* DC 3 NOP 1 -CALL M,* FC 3 NOP 1 -CALL NC,* D4 3 NOP 1 -CALL NZ,* C4 3 NOP 1 -CALL P,* F4 3 NOP 1 -CALL PE,* EC 3 NOP 1 -CALL PO,* E4 3 NOP 1 -CALL Z,* CC 3 NOP 1 -CALL * CD 3 NOP 1 - -CCF "" 3F 1 NOP 1 - -CP (HL) BE 1 NOP 1 -CP (IX*) BEDD 3 ZIX 1 -CP (IY*) BEFD 3 ZIX 1 -CP A BF 1 NOP 1 -CP B B8 1 NOP 1 -CP C B9 1 NOP 1 -CP D BA 1 NOP 1 -CP E BB 1 NOP 1 -CP H BC 1 NOP 1 -CP L BD 1 NOP 1 -CP * FE 2 NOP 1 -CPD "" A9ED 2 NOP 1 -CPDR "" B9ED 2 NOP 1 -CPIR "" B1ED 2 NOP 1 -CPI "" A1ED 2 NOP 1 -CPL "" 2F 1 NOP 1 - -DAA "" 27 1 NOP 1 - -DEC (HL) 35 1 NOP 1 -DEC (IX*) 35DD 3 ZIX 1 -DEC (IY*) 35FD 3 ZIX 1 -DEC A 3D 1 NOP 1 -DEC B 05 1 NOP 1 -DEC BC 0B 1 NOP 1 -DEC C 0D 1 NOP 1 -DEC D 15 1 NOP 1 -DEC DE 1B 1 NOP 1 -DEC E 1D 1 NOP 1 -DEC H 25 1 NOP 1 -DEC HL 2B 1 NOP 1 -DEC IX 2BDD 2 NOP 1 -DEC IY 2BFD 2 NOP 1 -DEC L 2D 1 NOP 1 -DEC SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -DJNZ * 10 2 R1 1 - -EI "" FB 1 NOP 1 -EX (SP),HL E3 1 NOP 1 -EX (SP),IX E3DD 2 NOP 1 -EX (SP),IY E3FD 2 NOP 1 -EX AF,AF' 08 1 NOP 1 -EX DE,HL EB 1 NOP 1 -EXX "" D9 1 NOP 1 -HALT "" 76 1 NOP 1 - -IM 0 46ED 2 NOP 1 -IM 1 56ED 2 NOP 1 -IM 2 5EED 2 NOP 1 - -/* Alternate form of above -IM0 46ED 2 NOP 1 -IM1 56ED 2 NOP 1 -IM2 5EED 2 NOP 1 - -IN A,(C) 78ED 2 NOP 1 -IN B,(C) 40ED 2 NOP 1 -IN C,(C) 48ED 2 NOP 1 -IN D,(C) 50ED 2 NOP 1 -IN E,(C) 58ED 2 NOP 1 -IN H,(C) 60ED 2 NOP 1 -IN L,(C) 68ED 2 NOP 1 - -IN A,(*) DB 2 NOP 1 - -IN0 A,(*) 38ED 3 NOP 1 -IN0 B,(*) 00ED 3 NOP 1 -IN0 C,(*) 08ED 3 NOP 1 -IN0 D,(*) 10ED 3 NOP 1 -IN0 E,(*) 18ED 3 NOP 1 -IN0 H,(*) 20ED 3 NOP 1 -IN0 L,(*) 28ED 3 NOP 1 - -INC (HL) 34 1 NOP 1 -INC (IX*) 34DD 3 ZIX 1 -INC (IY*) 34FD 3 ZIX 1 -INC A 3C 1 NOP 1 -INC B 04 1 NOP 1 -INC BC 03 1 NOP 1 -INC C 0C 1 NOP 1 -INC D 14 1 NOP 1 -INC DE 13 1 NOP 1 -INC E 1C 1 NOP 1 -INC H 24 1 NOP 1 -INC HL 23 1 NOP 1 -INC IX 23DD 2 NOP 1 -INC IY 23FD 2 NOP 1 -INC L 2C 1 NOP 1 -INC SP 33 1 NOP 1 - - -IND "" AAED 2 NOP 1 -INDR "" BAED 2 NOP 1 -INI "" A2ED 2 NOP 1 -INIR "" B2ED 2 NOP 1 - -JP (HL) E9 1 NOP 1 -JP (IX) E9DD 2 NOP 1 -JP (IY) E9FD 2 NOP 1 -JP C,* DA 3 NOP 1 -JP M,* FA 3 NOP 1 -JP NC,* D2 3 NOP 1 -JP NZ,* C2 3 NOP 1 -JP P,* F2 3 NOP 1 -JP PE,* EA 3 NOP 1 -JP PO,* E2 3 NOP 1 -JP Z,* CA 3 NOP 1 -JP * C3 3 NOP 1 - -JR C,* 38 2 R1 1 -JR NC,* 30 2 R1 1 -JR NZ,* 20 2 R1 1 -JR Z,* 28 2 R1 1 -JR * 18 2 R1 1 - -LD (BC),A 02 1 NOP 1 -LD (DE),A 12 1 NOP 1 -LD (HL),A 77 1 NOP 1 -LD (HL),B 70 1 NOP 1 -LD (HL),C 71 1 NOP 1 -LD (HL),D 72 1 NOP 1 -LD (HL),E 73 1 NOP 1 -LD (HL),H 74 1 NOP 1 -LD (HL),L 75 1 NOP 1 -LD (HL),* 36 2 NOP 1 -LD (IX*),A 77DD 3 ZIX 1 -LD (IX*),B 70DD 3 ZIX 1 -LD (IX*),C 71DD 3 ZIX 1 -LD (IX*),D 72DD 3 ZIX 1 -LD (IX*),E 73DD 3 ZIX 1 -LD (IX*),H 74DD 3 ZIX 1 -LD (IX*),L 75DD 3 ZIX 1 -LD (IX*),* 36DD 4 ZIX 1 -LD (IY*),A 77FD 3 ZIX 1 -LD (IY*),B 70FD 3 ZIX 1 -LD (IY*),C 71FD 3 ZIX 1 -LD (IY*),D 72FD 3 ZIX 1 -LD (IY*),E 73FD 3 ZIX 1 -LD (IY*),H 74FD 3 ZIX 1 -LD (IY*),L 75FD 3 ZIX 1 -LD (IY*),* 36FD 4 ZIX 1 -LD (*),A 32 3 NOP 1 -LD (*),BC 43ED 4 NOP 1 -LD (*),DE 53ED 4 NOP 1 -LD (*),HL 22 3 NOP 1 -LD (*),IX 22DD 4 NOP 1 -LD (*),IY 22FD 4 NOP 1 -LD (*),SP 73ED 4 NOP 1 -LD A,(BC) 0A 1 NOP 1 -LD A,(DE) 1A 1 NOP 1 -LD A,(HL) 7E 1 NOP 1 -LD A,(IX*) 7EDD 3 ZIX 1 -LD A,(IY*) 7EFD 3 ZIX 1 -LD A,A 7F 1 NOP 1 -LD A,B 78 1 NOP 1 -LD A,C 79 1 NOP 1 -LD A,D 7A 1 NOP 1 -LD A,E 7B 1 NOP 1 -LD A,H 7C 1 NOP 1 -LD A,I 57ED 2 NOP 1 -LD A,L 7D 1 NOP 1 -LD A,R 5FED 2 NOP 1 -LD A,(*) 3A 3 NOP 1 -LD A,* 3E 2 NOP 1 -LD B,(HL) 46 1 NOP 1 -LD B,(IX*) 46DD 3 ZIX 1 -LD B,(IY*) 46FD 3 ZIX 1 -LD B,A 47 1 NOP 1 -LD B,B 40 1 NOP 1 -LD B,C 41 1 NOP 1 -LD B,D 42 1 NOP 1 -LD B,E 43 1 NOP 1 -LD B,H 44 1 NOP 1 -LD B,L 45 1 NOP 1 -LD B,* 06 2 NOP 1 -LD BC,(*) 4BED 4 NOP 1 -LD BC,* 01 3 NOP 1 -LD C,(HL) 4E 1 NOP 1 -LD C,(IX*) 4EDD 3 ZIX 1 -LD C,(IY*) 4EFD 3 ZIX 1 -LD C,A 4F 1 NOP 1 -LD C,B 48 1 NOP 1 -LD C,C 49 1 NOP 1 -LD C,D 4A 1 NOP 1 -LD C,E 4B 1 NOP 1 -LD C,H 4C 1 NOP 1 -LD C,L 4D 1 NOP 1 -LD C,* 0E 2 NOP 1 -LD D,(HL) 56 1 NOP 1 -LD D,(IX*) 56DD 3 ZIX 1 -LD D,(IY*) 56FD 3 ZIX 1 -LD D,A 57 1 NOP 1 -LD D,B 50 1 NOP 1 -LD D,C 51 1 NOP 1 -LD D,D 52 1 NOP 1 -LD D,E 53 1 NOP 1 -LD D,H 54 1 NOP 1 -LD D,L 55 1 NOP 1 -LD D,* 16 2 NOP 1 -LD DE,(*) 5BED 4 NOP 1 -LD DE,* 11 3 NOP 1 -LD E,(HL) 5E 1 NOP 1 -LD E,(IX*) 5EDD 3 ZIX 1 -LD E,(IY*) 5EFD 3 ZIX 1 -LD E,A 5F 1 NOP 1 -LD E,B 58 1 NOP 1 -LD E,C 59 1 NOP 1 -LD E,D 5A 1 NOP 1 -LD E,E 5B 1 NOP 1 -LD E,H 5C 1 NOP 1 -LD E,L 5D 1 NOP 1 -LD E,* 1E 2 NOP 1 -LD H,(HL) 66 1 NOP 1 -LD H,(IX*) 66DD 3 ZIX 1 -LD H,(IY*) 66FD 3 ZIX 1 -LD H,A 67 1 NOP 1 -LD H,B 60 1 NOP 1 -LD H,C 61 1 NOP 1 -LD H,D 62 1 NOP 1 -LD H,E 63 1 NOP 1 -LD H,H 64 1 NOP 1 -LD H,L 65 1 NOP 1 -LD H,* 26 2 NOP 1 -LD HL,(*) 2A 3 NOP 1 -LD HL,* 21 3 NOP 1 -LD I,A 47ED 2 NOP 1 -LD IX,(*) 2ADD 4 NOP 1 -LD IX,* 21DD 4 NOP 1 -LD IY,(*) 2AFD 4 NOP 1 -LD IY,* 21FD 4 NOP 1 -LD L,(HL) 6E 1 NOP 1 -LD L,(IX*) 6EDD 3 ZIX 1 -LD L,(IY*) 6EFD 3 ZIX 1 -LD L,A 6F 1 NOP 1 -LD L,B 68 1 NOP 1 -LD L,C 69 1 NOP 1 -LD L,D 6A 1 NOP 1 -LD L,E 6B 1 NOP 1 -LD L,H 6C 1 NOP 1 -LD L,L 6D 1 NOP 1 -LD L,* 2E 2 NOP 1 -LD R,A 4FED 2 NOP 1 -LD SP,(*) 7BED 4 NOP 1 -LD SP,HL F9 1 NOP 1 -LD SP,IX F9DD 2 NOP 1 -LD SP,IY F9FD 2 NOP 1 -LD SP,* 31 3 NOP 1 -LDD "" A8ED 2 NOP 1 -LDDR "" B8ED 2 NOP 1 -LDI "" A0ED 2 NOP 1 -LDIR "" B0ED 2 NOP 1 -NEG "" 44ED 2 NOP 1 -NOP "" 00 1 NOP 1 - -MLT BC 4CED 2 NOP 1 -MLT DE 5CED 2 NOP 1 -MLT HL 6CED 2 NOP 1 -MLT SP 7CED 2 NOP 1 - -OR (HL) B6 1 NOP 1 -OR (IX*) B6DD 3 ZIX 1 -OR (IY*) B6FD 3 ZIX 1 -OR A B7 1 NOP 1 -OR B B0 1 NOP 1 -OR C B1 1 NOP 1 -OR D B2 1 NOP 1 -OR E B3 1 NOP 1 -OR H B4 1 NOP 1 -OR L B5 1 NOP 1 -OR * F6 2 NOP 1 - -OTDM "" 8BED 2 NOP 1 -OTDMR "" 9BED 2 NOP 1 -OTDR "" BBED 2 NOP 1 -OTIM "" 83ED 2 NOP 1 -OTIMR "" 93ED 2 NOP 1 -OTIR "" B3ED 2 NOP 1 - -OUT (C),A 79ED 2 NOP 1 -OUT (C),B 41ED 2 NOP 1 -OUT (C),C 49ED 2 NOP 1 -OUT (C),D 51ED 2 NOP 1 -OUT (C),E 59ED 2 NOP 1 -OUT (C),H 61ED 2 NOP 1 -OUT (C),L 69ED 2 NOP 1 -OUT (*),A D3 2 NOP 1 - -OUT0 (*),A 39ED 3 NOP 1 -OUT0 (*),B 01ED 3 NOP 1 -OUT0 (*),C 09ED 3 NOP 1 -OUT0 (*),D 11ED 3 NOP 1 -OUT0 (*),E 19ED 3 NOP 1 -OUT0 (*),H 21ED 3 NOP 1 -OUT0 (*),L 29ED 3 NOP 1 - -OUTD "" ABED 2 NOP 1 -OUTI "" A3ED 2 NOP 1 - -POP AF F1 1 NOP 1 -POP BC C1 1 NOP 1 -POP DE D1 1 NOP 1 -POP HL E1 1 NOP 1 -POP IX E1DD 2 NOP 1 -POP IY E1FD 2 NOP 1 - -PUSH AF F5 1 NOP 1 -PUSH BC C5 1 NOP 1 -PUSH DE D5 1 NOP 1 -PUSH HL E5 1 NOP 1 -PUSH IX E5DD 2 NOP 1 -PUSH IY E5FD 2 NOP 1 - -RES *,(HL) 86CB 2 ZBIT 1 -RES *,(IX*) CBDD 4 ZBIT 1 0 8600 -RES *,(IY*) CBFD 4 ZBIT 1 0 8600 -RES *,A 87CB 2 ZBIT 1 -RES *,B 80CB 2 ZBIT 1 -RES *,C 81CB 2 ZBIT 1 -RES *,D 82CB 2 ZBIT 1 -RES *,E 83CB 2 ZBIT 1 -RES *,H 84CB 2 ZBIT 1 -RES *,L 85CB 2 ZBIT 1 - -RET "" C9 1 NOP 1 -RET C D8 1 NOP 1 -RET M F8 1 NOP 1 -RET NC D0 1 NOP 1 -RET NZ C0 1 NOP 1 -RET P F0 1 NOP 1 -RET PE E8 1 NOP 1 -RET PO E0 1 NOP 1 -RET Z C8 1 NOP 1 -RETI "" 4DED 2 NOP 1 -RETN "" 45ED 2 NOP 1 - -RL (HL) 16CB 2 NOP 1 -RL (IX*) CBDD 4 ZIX 1 0 1600 -RL (IY*) CBFD 4 ZIX 1 0 1600 -RL A 17CB 2 NOP 1 -RL B 10CB 2 NOP 1 -RL C 11CB 2 NOP 1 -RL D 12CB 2 NOP 1 -RL E 13CB 2 NOP 1 -RL H 14CB 2 NOP 1 -RL L 15CB 2 NOP 1 -RLA "" 17 1 NOP 1 - -RLC (HL) 06CB 2 NOP 1 -RLC (IX*) CBDD 4 ZIX 1 0 0600 -RLC (IY*) CBFD 4 ZIX 1 0 0600 -RLC A 07CB 2 NOP 1 -RLC B 00CB 2 NOP 1 -RLC C 01CB 2 NOP 1 -RLC D 02CB 2 NOP 1 -RLC E 03CB 2 NOP 1 -RLC H 04CB 2 NOP 1 -RLC L 05CB 2 NOP 1 -RLCA "" 07 1 NOP 1 -RLD "" 6FED 2 NOP 1 - -RR (HL) 1ECB 2 NOP 1 -RR (IX*) CBDD 4 ZIX 1 0 1E00 -RR (IY*) CBFD 4 ZIX 1 0 1E00 -RR A 1FCB 2 NOP 1 -RR B 18CB 2 NOP 1 -RR C 19CB 2 NOP 1 -RR D 1ACB 2 NOP 1 -RR E 1BCB 2 NOP 1 -RR H 1CCB 2 NOP 1 -RR L 1DCB 2 NOP 1 -RRA "" 1F 1 NOP 1 -RRC (HL) 0ECB 2 NOP 1 -RRC (IX*) CBDD 4 ZIX 1 0 0E00 -RRC (IY*) CBFD 4 ZIX 1 0 0E00 -RRC A 0FCB 2 NOP 1 -RRC B 08CB 2 NOP 1 -RRC C 09CB 2 NOP 1 -RRC D 0ACB 2 NOP 1 -RRC E 0BCB 2 NOP 1 -RRC H 0CCB 2 NOP 1 -RRC L 0DCB 2 NOP 1 -RRCA "" 0F 1 NOP 1 -RRD "" 67ED 2 NOP 1 - -RST 00H C7 1 NOP 1 -RST 08H CF 1 NOP 1 -RST 10H D7 1 NOP 1 -RST 18H DF 1 NOP 1 -RST 20H E7 1 NOP 1 -RST 28H EF 1 NOP 1 -RST 30H F7 1 NOP 1 -RST 38H FF 1 NOP 1 - -/* Alternate form of above -RST 00 C7 1 NOP 1 -RST 08 CF 1 NOP 1 -RST 10 D7 1 NOP 1 -RST 18 DF 1 NOP 1 -RST 20 E7 1 NOP 1 -RST 28 EF 1 NOP 1 -RST 30 F7 1 NOP 1 -RST 38 FF 1 NOP 1 - -SBC A,(HL) 9E 1 NOP 1 -SBC A,(IX*) 9EDD 3 ZIX 1 -SBC A,(IY*) 9EFD 3 ZIX 1 -SBC A,A 9F 1 NOP 1 -SBC A,B 98 1 NOP 1 -SBC A,C 99 1 NOP 1 -SBC A,D 9A 1 NOP 1 -SBC A,E 9B 1 NOP 1 -SBC A,H 9C 1 NOP 1 -SBC A,L 9D 1 NOP 1 -SBC HL,BC 42ED 2 NOP 1 -SBC HL,DE 52ED 2 NOP 1 -SBC HL,HL 62ED 2 NOP 1 -SBC HL,SP 72ED 2 NOP 1 -SBC A,* DE 2 NOP 1 -SCF "" 37 1 NOP 1 - -SET *,(HL) C6CB 2 ZBIT 1 -SET *,(IX*) CBDD 4 ZBIT 1 0 C600 -SET *,(IY*) CBFD 4 ZBIT 1 0 C600 -SET *,A C7CB 2 ZBIT 1 -SET *,B C0CB 2 ZBIT 1 -SET *,C C1CB 2 ZBIT 1 -SET *,D C2CB 2 ZBIT 1 -SET *,E C3CB 2 ZBIT 1 -SET *,H C4CB 2 ZBIT 1 -SET *,L C5CB 2 ZBIT 1 - -SLA (HL) 26CB 2 NOP 1 -SLA (IX*) CBDD 4 ZIX 1 0 2600 -SLA (IY*) CBFD 4 ZIX 1 0 2600 -SLA A 27CB 2 NOP 1 -SLA B 20CB 2 NOP 1 -SLA C 21CB 2 NOP 1 -SLA D 22CB 2 NOP 1 -SLA E 23CB 2 NOP 1 -SLA H 24CB 2 NOP 1 -SLA L 25CB 2 NOP 1 - -SLP "" 76ED 2 NOP 1 - -SRA (HL) 2ECB 2 NOP 1 -SRA (IX*) CBDD 4 ZIX 1 0 2E00 -SRA (IY*) CBFD 4 ZIX 1 0 2E00 -SRA A 2FCB 2 NOP 1 -SRA B 28CB 2 NOP 1 -SRA C 29CB 2 NOP 1 -SRA D 2ACB 2 NOP 1 -SRA E 2BCB 2 NOP 1 -SRA H 2CCB 2 NOP 1 -SRA L 2DCB 2 NOP 1 - -SRL (HL) 3ECB 2 NOP 1 -SRL (IX*) CBDD 4 ZIX 1 0 3E00 -SRL (IY*) CBFD 4 ZIX 1 0 3E00 -SRL A 3FCB 2 NOP 1 -SRL B 38CB 2 NOP 1 -SRL C 39CB 2 NOP 1 -SRL D 3ACB 2 NOP 1 -SRL E 3BCB 2 NOP 1 -SRL H 3CCB 2 NOP 1 -SRL L 3DCB 2 NOP 1 - -SUB (HL) 96 1 NOP 1 -SUB (IX*) 96DD 3 ZIX 1 -SUB (IY*) 96FD 3 ZIX 1 -SUB A 97 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB * D6 2 NOP 1 - -TST A 3CED 2 NOP 1 -TST B 04ED 2 NOP 1 -TST C 0CED 2 NOP 1 -TST D 14ED 2 NOP 1 -TST E 1CED 2 NOP 1 -TST H 24ED 2 NOP 1 -TST L 2CED 2 NOP 1 -TST (HL) 34ED 2 NOP 1 -TST * 64ED 3 NOP 1 - -TSTIO * 74ED 3 NOP 1 - -XOR (HL) AE 1 NOP 1 -XOR (IX*) AEDD 3 ZIX 1 -XOR (IY*) AEFD 3 ZIX 1 -XOR A AF 1 NOP 1 -XOR B A8 1 NOP 1 -XOR C A9 1 NOP 1 -XOR D AA 1 NOP 1 -XOR E AB 1 NOP 1 -XOR H AC 1 NOP 1 -XOR L AD 1 NOP 1 -XOR * EE 2 NOP 1 diff --git a/branches/s100/Make.cmd b/branches/s100/Make.cmd deleted file mode 100644 index 666aa393..00000000 --- a/branches/s100/Make.cmd +++ /dev/null @@ -1,4 +0,0 @@ -@echo off -pushd Source -call .\Make.cmd %* -popd \ No newline at end of file diff --git a/branches/s100/ReadMe.txt b/branches/s100/ReadMe.txt deleted file mode 100644 index ffc207bf..00000000 --- a/branches/s100/ReadMe.txt +++ /dev/null @@ -1,127 +0,0 @@ -************************************************************ -*** R o m W B W *** -*** *** -*** System Software for N8VEM Z80 Projects *** -************************************************************ - -Builders: Wayne Warthen (wwarthen@gmail.com) - Douglas Goodall (douglas_goodall@mac.com) - David Giles (vk5dg@internode.on.net) - -Updated: 2012-08-28 -Version: 2.1.1 - -This is an adaptation of CP/M-80 2.2 and ZSDOS/ZCPR -targeting ROMs for all N8VEM Z80 hardware variations -including SBC, Zeta, and N8. - -NOTE: This is very much a work-in-progress. It is -severely lacking appropriate documentation. I am -happy to answer questions and provide support though. - -Acknowledgements ----------------- - -While I have heavily modified much of the code, I want -to acknowledge that much of this is derived or -copied from the work of others in the N8VEM -project including Andrew Lynch, Dan Werner, Max Scane, -David Giles, John Coffman, and probably many others -I am not clearly aware of. - -I especially want to credit Douglas Goodall for -contributing code, time, testing, and advice. -He has created an entire suite of application -programs that substantially enhance this ROM. Everything -in the Apps folder of the distribution came directly -from Douglas and the list includes cpmname, writesys, -assign, slices, termtype, drives, and others. - -David Giles has contributed support for building the -ROM under Linux and the CSIO support in the SD Card driver. - -Usage Instructions ------------------- - -The distribution includes many pre-built ROM -images in the Output directory. The simplest way of -using this ROM is to simply pick the pre-built ROM -that most closely matches your preferences, burn it, -and use it. - -Refer to the file called RomList.txt for a complete -list of the ROMs that are included and the required -hardware configuration that they support. - -CPU Speed & Baud Rate ---------------------- - -The startup serial port baud rate in all pre-built -RomWBW variants is 38.4Kbps. While this speed is -nice in that it provides great display and file -transfer performance, it does push the limits of -slower hardware. Specifically, XModem v12.5 (the -default XM.COM) on the distribution is unable to -service the serial port fast enough if the CPU is -running at 4MHz. Your options are to 1) use the -old version of XModem (XM5.COM), put a faster CPU -oscillator in your system (6MHz or above), or -3) decrease the baud rate by building a custom -ROM. - -CP/M vs. ZSystem ----------------- - -There are two OS variants included in this distribution -and you may choose which one you prefer to use. - -The traditional Digital Research (DRI) CP/M code is the first -choice. The ROM images that DO NOT end in "_z" are built -with the traditional CP/M components from DRI. The Doc -directory contains a manual for CP/M usage (cpm22-m.pdf). -If you are new to the N8VEM systems, I would currently -recommend using the CP/M ROMs to start with simply -because they have gone through more testing and you -are less likely to encounter problems. - -The other choice is to use the most popular non-DRI -CP/M "clone" which is generally referred to as -ZSystem. The ROM images with a "_z" suffix are built -using the ZSystem components (specifically ZSDOS 1.2 -and ZCPR 1.0). These are intended to be -functionally equivalent to CP/M and should run all -CP/M 2.2 code. They are optimized for the Z80 CPU -(as opposed to 8080 for CP/M) and have some potentially -useful improvements. Please refer to the Doc directory -and look at the files for zsdos and zcpr (zsdos.pdf & -zcpr.doc as well as ZSystem.txt). - -ZSystem builds contain ZSDOS specific files in the -ROM Disk. - -Building a Custom ROM ---------------------- - -I strongly suggest you start with burning one of the -pre-built ROMs and making sure that works first. Once -you have gotten past that hurdle, you should consider -building a custom ROM. It is very easy and the -distribution comes with everything that is needed to -run a build on a Windows 32 bit or 64 bit system -- -basically Windows XP or above. There is also a -Linux build now available. - -Creating a custom ROM allows you to customize a lot -of useful stuff like adding support for a DSKY if -you have one. - -Please refer to the Build.txt file in the Doc directory -for detailed instructions for building a custom ROM. If -you are using Linux, also read the LinuxBuild.txt file. - -Notes ------ - -I realize these instructions are very minimal. I am happy to answer -questions. You will find the Google Group 'N8VEM' to be a great -source of information as well. \ No newline at end of file diff --git a/branches/s100/RomDsk/CPM_1024KB/ASM.COM b/branches/s100/RomDsk/CPM_1024KB/ASM.COM deleted file mode 100644 index a63e5aec..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/ASM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/CLRDIR.COM b/branches/s100/RomDsk/CPM_1024KB/CLRDIR.COM deleted file mode 100644 index d1f2a7d6..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/CLRDIR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/CR.COM b/branches/s100/RomDsk/CPM_1024KB/CR.COM deleted file mode 100644 index 8a824bcc..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/CR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/DDT.COM b/branches/s100/RomDsk/CPM_1024KB/DDT.COM deleted file mode 100644 index 83f8603f..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/DDT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/DDTZ.COM b/branches/s100/RomDsk/CPM_1024KB/DDTZ.COM deleted file mode 100644 index e30a34c0..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/DDTZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/DDTZ.DOC b/branches/s100/RomDsk/CPM_1024KB/DDTZ.DOC deleted file mode 100644 index e4470528..00000000 --- a/branches/s100/RomDsk/CPM_1024KB/DDTZ.DOC +++ /dev/null @@ -1,564 +0,0 @@ - - DDTZ v2.7 - by C.B. Falconer - edited by George A. Havach - -Introduction: -============ -DDTZ v2.7 is a complete replacement for DDT, Digital Research's -famous Dynamic Debugging Tool, with improved functionality, bug -extermination, and full Z80 support. In general, DDTZ is fully -compatible with the original utility, but it has extra and -extended commands and many fewer quirks. All Z80-specific -instructions can be (dis)assembled, though in Intel rather then -Zilog format. Furthermore, DDTZ will correctly trace ('T' and 'U' -commands) both 8080 and Z80 instructions, depending on which CPU -is operating. On startup, the program announces which CPU it is -running on. - -DDTZ v2.7 now handles the 64180 added opcodes. It does NOT test -for a 64180 CPU, since this cannot be done without executing -illegal Z80 instructions, which in turn will crash some -simulators. However v2.7 does not execute any 64180 instructions -internally, only in the subject program. - -This issue supplies the "M" version assembled, to avoid errors -when switching between MSDOS and CPM systems. The command table -is updated accordingly. Most CPM users are also MSDOS users, but -not vice-versa. - -The program is invoked by typing - - ddtz -or - ddtz [d:]filespec - -In the second form, DDTZ will load the specified file into -memory starting at 0100H, unless it's a .HEX file that sets its -own load address. Besides reporting the NEXT free address and -the PC (program counter) after a successful load, DDTZ also shows -the number of memory pages needed for a SAVE. Instead of having -to write all this down, just use the 'X' command at any time to -redisplay these three values for the current application. - -NOTE: loading more code above the NEXT pointer revises these - values. - -As in DDT, when a program is loaded above the area holding the -'A' and 'U' (and now 'W') command code, these commands are -disabled, and the extra memory is released to the user. Thus, -DDTZ can occupy as little as 3K total memory space. Unlike DDT, -however, DDTZ will not overwrite itself or the system on program -loads (except .HEX files). - -At initialization, the stack pointer (SP) points to a return to -DDTZ, just like for the CCP. Thus, programs that normally return -to the CCP will be returned to DDTZ. The 'B' command -reinitializes this condition. - - -The intercept vector copies the BDOS version number, etc., so -an object program does not know that DDTZ is running (except -for BIOS-BDOS vector size). Thus, programs that check the version -number should execute correctly under DDTZ. - -All input parameters can now be entered in any of three formats: - - (1) hexadecimal (as in DDT), - (2) decimal, by adding a leading '#' character, - (3) ASCII, by enclosing between either single or double - quotes; either one or two characters are allowed. - -Leading blanks in command lines and parameters are absorbed. -Either a comma or a (single) space is a valid delimiter. -Either uppercase or lowercase input is accepted. - -The default command (for anything not otherwise recognizable) -is 'H'. This allows convenient calculation, along with the other -features described below. So, to convert a number, just enter -it! - -As in DDT, the prompt character is '-', and the only error -message is the query ('?'), which generally kicks you back to -command mode. - -New Commands (Over DDT): -======================= - -NOTE: letters in parenthesis, e.g. "(U)", show the equivalent - command for DDTZM version (compatible with MSDOS debug). - - @ Sets or shows (with no parameter) the internally stored - "base" value. Also used with the 'S' and 'D' commands as - an optional parameter (though without the '@') to display - memory from an arbitrary base marker (offset). When set to - zero (the default), it does not affect any screen displays. - - B B)egin: resets the USER stack pointer to its initial value, - such that any program that exits by an RET will return to - DDTZ. DDTZ provides a default stack space of - approximately 24 bytes for user programs. - - C C)ompare first_address,last_address,against_address: shows - all the byte differences between two memory areas, in the - format - - XXXX aa YYYY bb - - where XXXX and YYYY are the comparative memory addresses, - and aa and bb are the corresponding byte values. Can be - used to verify the identity of two files by first - loading them into different memory areas with the 'R' - command (see below). - - - W Write: stores the modified memory area to disk under the - (K) filename specified by the 'I' command, overwriting the - original file from which it was loaded (the user is queried - before doing so). By default, the image of memory from - 0100H through the "NEXT" value -1 is saved. "K first_addr, - last_address" overrides this and allows writing ANY memory - area to a file. Almost a necessity for CPM 3.0 (no SAVE!). - K)eep on DDTZ - - X eXamine: redisplays the "NEXT PC SAVE" report at any time. - (Q) Q)uery size on DDTZ. - - S S)earch first_address, last_addr, value: searches the - (W) specified memory area for the value (a 16-bit word, not a - byte) and shows the locations of all such. Very useful for - finding CALL's or JMP's to a particular address, etc. - W)here on DDTZ - - Y Y)our_option parm1,parm2,address: executes an arbitrary - routine at the specified address, with the BC and DE - registers set to parm1 and parm2, respectively. - - Z Displays (but does not alter) the Z80's alternate register - set, including the index registers (disabled if running on - an 8080). On Z80's, automatically included as the last - part of the display by the 'X' command. - - -Based (Offset) Displays: -======================= - -The 'D' and 'E' commands can use a stored base value (offset), -as set by the '@' command. The current @ value may be -overridden for a single execution of these commands by adding the -base as an extra parameter in the command line. The effect is -to add this value to the first/last address and display -accordingly. The address listing on the left becomes XXXX:YYYY, -where XXXX is the offset address and YYYY is the actual memory -address being displayed. For example, if you have a data area -located at 42B7H and wish to preserve easy access, just enter -"@42b7". Now, "d0,3f" will dump memory starting at 4237H. - - -Further Changes from DDT: -======================== - - A A)ssemble now accepts the full Z80 as well as 8080 - instruction set, although it expects them in Intel rather - than Zilog format (see notes below under the 'L' - command). When in doubt, see the mnemnonic list below. - - D D)isplay or D)ump will accept an optional third parameter - to set the base value for a single execution only. Format - has been cleaned up. - - H H)ex_arithmetic on two values also shows their - difference in decimal. With only one value, converts to - hexadecimal, decimal, and ASCII (low-order byte only). - - - N N)ame now allows drive specification (d:...) and sets up - (I) the complete command line, including both FCB's (at - addresses 005CH and 006CH). The tail (stored at 0081H up) - is NOT upshifted. - I)nput on DDTZ - - U U)nassemble now displays the raw hexcode, especially handy - (L) when examining non-code areas. Intel (8080 style) mnemonics - are used, so some disassembled instructions may look - strange. E.g., the Z80's 'IN B,(C)' and 'OUT (C),B' become - 'INP B' and 'OUTP B', respectively; 'LD (nnnn),BC' becomes - 'SBCD nnnn', 'ADD IX, BC' becomes 'DADX B', and 'JP (IX)' - becomes 'PCIX'. - L)ist on DDTZ - - L L)oad now permits loading a file into memory with an - (R) offset, which is added to the default load address of - 0100H. When reading in a .HEX file with a preset bias, - the 'R' command will not transfer control to an invalid - execution point. Another execution of the 'R' command will - reread the input file, e.g.: - - n blah - l - ...modify the code and generally mess about... - l - - The original file is reloaded, and the modifications are - removed. - R)ead on DDTZ - - E E)nter, like D)isplay, now accepts an optional second - (S) parameter to set the base value for a single execution - only. - S)ubstitute or S)et on DDTZ - - T T)rap/trace on termination now shows the complete CPU - state. Traps and traces no longer lock up when a user RST - 7 instruction is executed. Tracing of BDOS/BIOS calls is - heavily trun cated, avoiding clutter and preventing system - crashes. - -NOTE: Most of the UNDOCUMENTED Z80 op-codes are handled. Others - can crash the system. - - R R)egisters also shows what two-byte values the HL and SP - (X) registers are actually pointing to. On Z80's, displays the - alternate register set. - eX)amine on DDTZ - -NOTE: Any use of the 'W' or 'L' command resets the system DMA - transfer address to the standard default value of 0080H. - - -; This is the output of DDTZ when disassembling OPTYPE.TRY -NOP LDA 06A4 MOV M,H -LXI B,06A4 DCX SP MOV M,L -STAX B INR A HLT -INX B DCR A MOV M,A -INR B MVI A,20 MOV A,B -DCR B CMC MOV A,C -MVI B,20 MOV B,B MOV A,D -RLC MOV B,C MOV A,E -EXAF MOV B,D MOV A,H -DAD B MOV B,E MOV A,L -LDAX B MOV B,H MOV A,M -DCX B MOV B,L MOV A,A -INR C MOV B,M ADD B -DCR C MOV B,A ADD C -MVI C,20 MOV C,B ADD D -RRC MOV C,C ADD E -DJNZ 0134 MOV C,D ADD H -LXI D,06A4 MOV C,E ADD L -STAX D MOV C,H ADD M -INX D MOV C,L ADD A -INR D MOV C,M ADC B -DCR D MOV C,A ADC C -MVI D,20 MOV D,B ADC D -RAL MOV D,C ADC E -JR 0134 MOV D,D ADC H -DAD D MOV D,E ADC L -LDAX D MOV D,H ADC M -DCX D MOV D,L ADC A -INR E MOV D,M SUB B -DCR E MOV D,A SUB C -MVI E,20 MOV E,B SUB D -RAR MOV E,C SUB E -JRNZ 0134 MOV E,D SUB H -LXI H,06A4 MOV E,E SUB L -SHLD 06A4 MOV E,H SUB M -INX H MOV E,L SUB A -INR H MOV E,M SBB B -DCR H MOV E,A SBB C -MVI H,20 MOV H,B SBB D -DAA MOV H,C SBB E -JRZ 0134 MOV H,D SBB H -DAD H MOV H,E SBB L -LHLD 06A4 MOV H,H SBB M -DCX H MOV H,L SBB A -INR L MOV H,M ANA B -DCR L MOV H,A ANA C -MVI L,20 MOV L,B ANA D -CMA MOV L,C ANA E -JRNC 0134 MOV L,D ANA H -LXI SP,06A4 MOV L,E ANA L -STA 06A4 MOV L,H ANA M -INX SP MOV L,L ANA A -INR M MOV L,M XRA B -DCR M MOV L,A XRA C -MVI M,20 MOV M,B XRA D -STC MOV M,C XRA E -JRC 0134 MOV M,D XRA H -DAD SP MOV M,E XRA L - - -XRA M JPE 06A4 SLAR M -XRA A XCHG SLAR A -ORA B CPE 06A4 SRAR B -ORA C XRI 20 SRAR C -ORA D RST 5 SRAR D -ORA E RP SRAR E -ORA H POP PSW SRAR H -ORA L JP 06A4 SRAR L -ORA M DI SRAR M -ORA A CP 06A4 SRAR A -CMP B PUSH PSW SLLR B -CMP C ORI 20 SLLR C -CMP D RST 6 SLLR D -CMP E RM SLLR E -CMP H SPHL SLLR H -CMP L JM 06A4 SLLR L -CMP M EI SLLR M -CMP A CM 06A4 SLLR A -RNZ CPI 20 SRLR B -POP B RST 7 SRLR C -JNZ 06A4 RLCR B SRLR D -JMP 06A4 RLCR C SRLR E -CNZ 06A4 RLCR D SRLR H -PUSH B RLCR E SRLR L -ADI 20 RLCR H SRLR M -RST 0 RLCR L SRLR A -RZ RLCR M BIT 0,B -RET RLCR A BIT 0,C -JZ 06A4 RRCR B BIT 0,D -CZ 06A4 RRCR C BIT 0,E -CALL 06A4 RRCR D BIT 0,H -ACI 20 RRCR E BIT 0,L -RST 1 RRCR H BIT 0,M -RNC RRCR L BIT 0,A -POP D RRCR M BIT 1,B -JNC 06A4 RRCR A BIT 1,C -OUT 20 RALR B BIT 1,D -CNC 06A4 RALR C BIT 1,E -PUSH D RALR D BIT 1,H -SUI 20 RALR E BIT 1,L -RST 2 RALR H BIT 1,M -RC RALR L BIT 1,A -EXX RALR M BIT 2,B -JC 06A4 RALR A BIT 2,C -IN 20 RARR B BIT 2,D -CC 06A4 RARR C BIT 2,E -SBI 20 RARR D BIT 2,H -RST 3 RARR E BIT 2,L -RPO RARR H BIT 2,M -POP H RARR L BIT 2,A -JPO 06A4 RARR M BIT 3,B -XTHL RARR A BIT 3,C -CPO 06A4 SLAR B BIT 3,D -PUSH H SLAR C BIT 3,E -ANI 20 SLAR D BIT 3,H -RST 4 SLAR E BIT 3,L -RPE SLAR H BIT 3,M -PCHL SLAR L BIT 3,A - - -BIT 4,B RES 3,D SET 2,H -BIT 4,C RES 3,E SET 2,L -BIT 4,D RES 3,H SET 2,M -BIT 4,E RES 3,L SET 2,A -BIT 4,H RES 3,M SET 3,B -BIT 4,L RES 3,A SET 3,C -BIT 4,M RES 4,B SET 3,D -BIT 4,A RES 4,C SET 3,E -BIT 5,B RES 4,D SET 3,H -BIT 5,C RES 4,E SET 3,L -BIT 5,D RES 4,H SET 3,M -BIT 5,E RES 4,L SET 3,A -BIT 5,H RES 4,M SET 4,B -BIT 5,L RES 4,A SET 4,C -BIT 5,M RES 5,B SET 4,D -BIT 5,A RES 5,C SET 4,E -BIT 6,B RES 5,D SET 4,H -BIT 6,C RES 5,E SET 4,L -BIT 6,D RES 5,H SET 4,M -BIT 6,E RES 5,L SET 4,A -BIT 6,H RES 5,M SET 5,B -BIT 6,L RES 5,A SET 5,C -BIT 6,M RES 6,B SET 5,D -BIT 6,A RES 6,C SET 5,E -BIT 7,B RES 6,D SET 5,H -BIT 7,C RES 6,E SET 5,L -BIT 7,D RES 6,H SET 5,M -BIT 7,E RES 6,L SET 5,A -BIT 7,H RES 6,M SET 6,B -BIT 7,L RES 6,A SET 6,C -BIT 7,M RES 7,B SET 6,D -BIT 7,A RES 7,C SET 6,E -RES 0,B RES 7,D SET 6,H -RES 0,C RES 7,E SET 6,L -RES 0,D RES 7,H SET 6,M -RES 0,E RES 7,L SET 6,A -RES 0,H RES 7,M SET 7,B -RES 0,L RES 7,A SET 7,C -RES 0,M SET 0,B SET 7,D -RES 0,A SET 0,C SET 7,E -RES 1,B SET 0,D SET 7,H -RES 1,C SET 0,E SET 7,L -RES 1,D SET 0,H SET 7,M -RES 1,E SET 0,L SET 7,A -RES 1,H SET 0,M DADX B -RES 1,L SET 0,A DADX D -RES 1,M SET 1,B LXI X,06A4 -RES 1,A SET 1,C SIXD 06A4 -RES 2,B SET 1,D INX X -RES 2,C SET 1,E DADX X -RES 2,D SET 1,H LIXD 06A4 -RES 2,E SET 1,L DCX X -RES 2,H SET 1,M INR [X+05] -RES 2,L SET 1,A DCR [X+05] -RES 2,M SET 2,B MVI [X+05],20 -RES 2,A SET 2,C DADX SP -RES 3,B SET 2,D MOV B,[X+05] -RES 3,C SET 2,E MOV C,[X+05] - - -MOV D,[X+05] DSBC B DADY B -MOV E,[X+05] SBCD 06A4 DADY D -MOV H,[X+05] NEG LXI Y,06A4 -MOV L,[X+05] RETN SIYD 06A4 -MOV [X+05],B IM0 INX Y -MOV [X+05],C LDIA DADY Y -MOV [X+05],D INP C LIYD 06A4 -MOV [X+05],E OUTP C DCX Y -MOV [X+05],H DADC B INR [Y+05] -MOV [X+05],L LBCD 06A4 DCR [Y+05] -MOV [X+05],A RETI MVI [Y+05],2 -MOV A,[X+05] LDRA DADY SP -ADD [X+05] INP D MOV B,[Y+05] -ADC [X+05] OUTP D MOV C,[Y+05] -SUB [X+05] DSBC D MOV D,[Y+05] -SBB [X+05] SDED 06A4 MOV E,[Y+05] -ANA [X+05] IM1 MOV H,[Y+05] -XRA [X+05] LDAI MOV L,[Y+05] -ORA [X+05] INP E MOV [Y+05],B -CMP [X+05] OUTP E MOV [Y+05],C -POP X DADC D MOV [Y+05],D -XTIX LDED 06A4 MOV [Y+05],E -PUSH X IM2 MOV [Y+05],H -PCIX LDAR MOV [Y+05],L -SPIX INP H MOV [Y+05],A -RLCR [X+05] OUTP H MOV A,[Y+05] -RRCR [X+05] DSBC H ADD [Y+05] -RALR [X+05] shld 06A4 ADC [Y+05] -RARR [X+05] RRD SUB [Y+05] -SLAR [X+05] INP L SBB [Y+05] -SRAR [X+05] OUTP L ANA [Y+05] -SRLR [X+05] DADC H XRA [Y+05] -BIT 0,[X+05] lhld 06A4 ORA [Y+05] -BIT 1,[X+05] RLD CMP [Y+05] -BIT 2,[X+05] INP M POP Y -BIT 3,[X+05] OUTP M XTIY -BIT 4,[X+05] DSBC SP PUSH Y -BIT 5,[X+05] SSPD 06A4 PCIY -BIT 6,[X+05] INP A SPIY -BIT 7,[X+05] OUTP A RLCR [Y+05] -RES 0,[X+05] DADC SP RRCR [Y+05] -RES 1,[X+05] LSPD 06A4 RALR [Y+05] -RES 2,[X+05] LDI RARR [Y+05] -RES 3,[X+05] CCI SLAR [Y+05] -RES 4,[X+05] INI SRAR [Y+05] -RES 5,[X+05] OTI SRLR [Y+05] -RES 6,[X+05] LDD BIT 0,[Y+05] -RES 7,[X+05] CCD BIT 1,[Y+05] -SET 0,[X+05] IND BIT 2,[Y+05] -SET 1,[X+05] OTD BIT 3,[Y+05] -SET 2,[X+05] LDIR BIT 4,[Y+05] -SET 3,[X+05] CCIR BIT 5,[Y+05] -SET 4,[X+05] INIR BIT 6,[Y+05] -SET 5,[X+05] OTIR BIT 7,[Y+05] -SET 6,[X+05] LDDR RES 0,[Y+05] -SET 7,[X+05] CCDR RES 1,[Y+05] -INP B INDR RES 2,[Y+05] -OUTP B OTDR RES 3,[Y+05] - - -RES 4,[Y+05] SET 0,[Y+05] SET 4,[Y+05] -RES 5,[Y+05] SET 1,[Y+05] SET 5,[Y+05] -RES 6,[Y+05] SET 2,[Y+05] SET 6,[Y+05] -RES 7,[Y+05] SET 3,[Y+05] SET 7,[Y+05] - -; These are the result of disassembling 64180OPS.TRY -; These opcodes are available ONLY on the 64180 CPU -; DDTZ will both assemble and disassemble these. -IN0 B,20 TST E MLT B -OUT0 20,B IN0 H,20 MLT D -TST B OUT0 20,H TSTI 20 -IN0 C,20 TST H MLT H -OUT0 20,C IN0 L,20 TSIO 20 -TST C OUT0 20,L SLP -IN0 D,20 TST L MLT SP -OUT0 20,D TST M OTIM -TST D IN0 A,20 OTDM -IN0 E,20 OUT0 20,A OIMR -OUT0 20,E TST A ODMR - -; The following are UNDOCUMENTED z80 opcodes from XTDOPS.TRY. -; DDTZ will disassemble these, but will not assemble them. -; They use xh/xl (or yh/yl) as separate byte registers. -; Use these at your own risk. -INRX H ACXR H MOVY H,B -DCRX H ACXR L MOVY H,C -MVIX H,20 SUXR H MOVY H,D -INRX L SUXR L MOVY H,E -DCRX L SBXR H MOVY H,A -MVIX L,20 SBXR L MOVY L,B -MOVX B,H NDXR H MOVY L,C -MOVX B,L NDXR L MOVY L,D -MOVX C,H XRXR H MOVY L,E -MOVX C,L XRXR L MOVY L,A -MOVX D,H ORXR H MOVY A,H -MOVX D,L ORXR L MOVY A,L -MOVX E,H CPXR H ADYR H -MOVX E,L CPXR L ADYR L -MOVX H,B INRY H ACYR H -MOVX H,C DCRY H ACYR L -MOVX H,D MVIY H,20 SUYR H -MOVX H,E INRY L SUYR L -MOVX H,A DCRY L SBYR H -MOVX L,B MVIY L,20 SBYR L -MOVX L,C MOVY B,H NDYR H -MOVX L,D MOVY B,L NDYR L -MOVX L,E MOVY C,H XRYR H -MOVX L,A MOVY C,L XRYR L -MOVX A,H MOVY D,H ORYR H -MOVX A,L MOVY D,L ORYR L -ADXR H MOVY E,H CPYR H -ADXR L MOVY E,L CPYR L - - -Command Summary: -=============== - -DDTZM command DDTZ command -============= ============ -@ (base) -A)ssemble first_address A -B)egin {i.e., initialize stack and return} B -C)ompare first_address,last_address,against_address C -D)ump first_address[,last_address[,base]] D -E)nter_in_memory first_address[,base] S)ubstitute -F)ill first_address,last_address,value F -G)o_to [address][,trap1[,trap2]] G -H)ex_arithmetic value1(,value2) H -L)oad_file (offset) R)ead -M)ove first_address,last_address,destination M -N)nput FCBs_command_line I)nput -Q)uit (not avail) -R)egister examine/change [register|flag] X)amine -S)earch first_address,last_address,word W)hereis -T)race_execution [count] T - Untrace_execution [count] (i.e. do count instr) U)ntrace -U)nassemble_code first_address[,last_address] L)ist code -W)rite [first_address,last_address] K)eep -X)amine {i.e. display memory parameters for application} Q)uery -Y)our_option BC:=parm1,DE:=parm2,call_address Y -Z)80_register_display Z - - -If you find this program useful, contributions will be gratefully -accepted and will encourage further development and release of -useful CPM programs. My practice is to include source. - -C.B. Falconer -680 Hartford Turnpike, -Hamden, Conn. 06517 (203) 281-1438 - -DDTZ and its associated documentation and other files are -copyright (c) 1980-1988 by C.B. Falconer. They may be freely -copied and used for non-commercial purposes ONLY. - diff --git a/branches/s100/RomDsk/CPM_1024KB/DIF.COM b/branches/s100/RomDsk/CPM_1024KB/DIF.COM deleted file mode 100644 index 87b89d75..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/DIF.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/DIRX.COM b/branches/s100/RomDsk/CPM_1024KB/DIRX.COM deleted file mode 100644 index 413bceca..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/DIRX.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/DUMP.COM b/branches/s100/RomDsk/CPM_1024KB/DUMP.COM deleted file mode 100644 index 03a77c3c..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/DUMP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/ED.COM b/branches/s100/RomDsk/CPM_1024KB/ED.COM deleted file mode 100644 index a0f0f541..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/ED.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/FLASH.MAN b/branches/s100/RomDsk/CPM_1024KB/FLASH.MAN deleted file mode 100644 index e57de5c2..00000000 --- a/branches/s100/RomDsk/CPM_1024KB/FLASH.MAN +++ /dev/null @@ -1,35 +0,0 @@ -NAME - flash - in-situ 29F040 flash ROM programmer for N8VEM, Zeta and N8 computers -SYNOPSIS - flashz - flashn8 -DESCRIPTION - The flashz and flashn8 erase and program the FLASH ROM chip from an - image file. flashz is used for the N8VEM Z80-SBC and Zeta computers. - flashn8 is used with the N8 home computer. Both function the same - except in the way memory is addressed. - - flash expects a 512k file in the same directory containing the image - that will be programmed into the ROM. This file must have the - unimaginative filename of ROM.IMG. The whole process of erasing and - programming the ROM takes less than a minute - far less than the time - taken to upload your new image. - - This program is only suitable for 29F040 512k FLASH ROMs. - - Assemble with TASM using the command - tasm -t80 -g3 flashz.asm flashz.com - tasm -t80 -g3 flashn8.asm flashn8.com - -JUMPERS - The following jumpers must be in place on the boards to allow the - 29F040 to be programmed. - For the N8VEM Z8-SBC MK-II: K1 1-2, K6 2-3, K8 2-3 - For the N8: K3 1-2, K4 2-3, K5 2-3 - For the Zeta, no jumpers need (or can) be set. - -AUTHOR - Written by David Giles so he doesn't have to open the box his Zeta - lives in so often. Reports to N8VEM group or vk5dg@internode.on.net - - diff --git a/branches/s100/RomDsk/CPM_1024KB/LBREXT.COM b/branches/s100/RomDsk/CPM_1024KB/LBREXT.COM deleted file mode 100644 index c0c950e3..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/LBREXT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/LIB.COM b/branches/s100/RomDsk/CPM_1024KB/LIB.COM deleted file mode 100644 index 45d7fb21..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/LIB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/LINK.COM b/branches/s100/RomDsk/CPM_1024KB/LINK.COM deleted file mode 100644 index e188fb92..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/LINK.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/LOAD.COM b/branches/s100/RomDsk/CPM_1024KB/LOAD.COM deleted file mode 100644 index b9601e00..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/LOAD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/MAC.COM b/branches/s100/RomDsk/CPM_1024KB/MAC.COM deleted file mode 100644 index f49e835a..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/MAC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/MBASIC.COM b/branches/s100/RomDsk/CPM_1024KB/MBASIC.COM deleted file mode 100644 index c9ec3cd3..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/MBASIC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/NULU.COM b/branches/s100/RomDsk/CPM_1024KB/NULU.COM deleted file mode 100644 index fc5594b1..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/NULU.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/PIP.COM b/branches/s100/RomDsk/CPM_1024KB/PIP.COM deleted file mode 100644 index 4b2ce4b6..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/PIP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/RMAC.COM b/branches/s100/RomDsk/CPM_1024KB/RMAC.COM deleted file mode 100644 index 9ab7206b..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/RMAC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/SID.COM b/branches/s100/RomDsk/CPM_1024KB/SID.COM deleted file mode 100644 index 3b073ba5..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/SID.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/STAT.COM b/branches/s100/RomDsk/CPM_1024KB/STAT.COM deleted file mode 100644 index 1de359f2..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/STAT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/SUBMIT.COM b/branches/s100/RomDsk/CPM_1024KB/SUBMIT.COM deleted file mode 100644 index 2e788827..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/SUBMIT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/SUPERSUB.COM b/branches/s100/RomDsk/CPM_1024KB/SUPERSUB.COM deleted file mode 100644 index a25d60a6..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/SUPERSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/UNARC.COM b/branches/s100/RomDsk/CPM_1024KB/UNARC.COM deleted file mode 100644 index 8cc90746..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/UNARC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/UNCR.COM b/branches/s100/RomDsk/CPM_1024KB/UNCR.COM deleted file mode 100644 index 42385ddd..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/UNCR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/UNZIP.COM b/branches/s100/RomDsk/CPM_1024KB/UNZIP.COM deleted file mode 100644 index afde7204..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/UNZIP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/VIDATT.Z80 b/branches/s100/RomDsk/CPM_1024KB/VIDATT.Z80 deleted file mode 100644 index 073bb84f..00000000 --- a/branches/s100/RomDsk/CPM_1024KB/VIDATT.Z80 +++ /dev/null @@ -1,69 +0,0 @@ - title WordStar 4.0 Video Attributes Driver - -strngout equ 0283h - -esc equ 1bh -dim equ 1 -blink equ 2 -invert equ 4 -uline equ 8 - - aseg - org 03c1h - -vidatt: - xor a - ld hl,funtbl - ld b,8 -getloop: - rr c - jr nc,getnext - or a,(hl) -getnext: - inc hl - djnz getloop -; - ld hl,string+2 ; attribute #1 on/off indicator - push hl - ld b,4 - ld de,'?!' ; ? = attribute off, ! = attribute on -setloop: - rra - jr nc,attroff - ld (hl),e ; attribute on - jr setnext -attroff: - ld (hl),d ; attribute off -setnext: - inc hl - inc hl - inc hl ; advance to next on/off indicator - djnz setloop -; - pop hl ; hl --> dim on/off - ld a,d ; attribute off - cp (hl) ; dim off? - jr nz,setdim - ld a,e ; attribute on -setdim: - ld (hl),a - ld hl,string - jp strngout ; ws string routine -; -; -funtbl: - defb dim ; strike out - defb invert or blink ; warnings & errors - defb invert ; block - defb uline ; underline - defb blink ; subscript - defb blink or uline ; superscript - defb invert ; menu, headline, bold, double - defb invert or uline ; italics, RET, backspace -; -string: - defb 12,esc,' 2',esc,' 3',esc,' 4',esc,' 5' -; -finis equ $ - end - \ No newline at end of file diff --git a/branches/s100/RomDsk/CPM_1024KB/WS.COM b/branches/s100/RomDsk/CPM_1024KB/WS.COM deleted file mode 100644 index aa028bc3..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WS.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WS.OVR b/branches/s100/RomDsk/CPM_1024KB/WS.OVR deleted file mode 100644 index 5e3c8773..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WS.OVR and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSCHANGE.COM b/branches/s100/RomDsk/CPM_1024KB/WSCHANGE.COM deleted file mode 100644 index bc85c1fc..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSCHANGE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSCHANGE.OVR b/branches/s100/RomDsk/CPM_1024KB/WSCHANGE.OVR deleted file mode 100644 index 4f707c63..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSCHANGE.OVR and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSCHHELP.OVR b/branches/s100/RomDsk/CPM_1024KB/WSCHHELP.OVR deleted file mode 100644 index 49becf77..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSCHHELP.OVR and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSHELP.OVR b/branches/s100/RomDsk/CPM_1024KB/WSHELP.OVR deleted file mode 100644 index 02634675..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSHELP.OVR and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSMSGS.OVR b/branches/s100/RomDsk/CPM_1024KB/WSMSGS.OVR deleted file mode 100644 index 84625d8e..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSMSGS.OVR and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSPRINT.OVR b/branches/s100/RomDsk/CPM_1024KB/WSPRINT.OVR deleted file mode 100644 index 83bef6ea..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSPRINT.OVR and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSREADME.TXT b/branches/s100/RomDsk/CPM_1024KB/WSREADME.TXT deleted file mode 100644 index 7a75b22c..00000000 --- a/branches/s100/RomDsk/CPM_1024KB/WSREADME.TXT +++ /dev/null @@ -1,880 +0,0 @@ - --THE README FILE-- - ------------------------ - -README contains late-breaking news and tips about WordStar, -and information about printers. - - -THE DISKS THAT CAME IN YOUR PACKAGE ------------------------------------ - -The file HOMONYMS.TXT is included on the Speller disk -contrary to what is listed in Appendix D. - - -INSTALLATION ------------- - -WINSTALL and WSCHANGE - - WordStar has two installation programs: - - o WINSTALL contains the basic choices to install WordStar. - It is recommended for all users. - - Be sure and install your valid disk drives since WordStar - running under CP/M cannot recover from attempts to access non- - existent disk drives. - - o WSCHANGE contains every installation and customization - choice. It is designed for advanced users and users who - want to customize WordStar after they're familiar with it. - Use the menu listing below for a directory of the menus - in WSCHANGE. - -Directory of WSCHANGE Menus - - The chart below shows the organization of menus in WSCHANGE. - Print it out and refer to it as you customize WordStar. - - Main Installation Menu - - A Console - A Monitor - A Monitor selection - B Monitor name - C Screen sizing - B Function keys - C Monitor patches - A Special characters - B Cursor control - C Screen control - D Keyboard patches - A Function keys - B Save function keys - E Interface patches - A Console busy handshaking - B Special I/O subroutines - B Printer - A Printer choices - A Printer selection - B Printer name - C Default printer driver - B Printer driver library - A Select library file - B Create smaller library - C Add new printer driver - D Change printer driver data - C WS printer patches - A Custom print controls, printer initialization - - NOTE: Disregard the "CUSTOM & SIMPLE Controls Save CUSTOM/SIMPLE - Controls" option shown. This is not available from this menu. - - D Printing defaults - E Printer interface - A Printer port selection - B Printer busy handshaking - C Printer subroutines - C Computer - A Disk drives - A Valid disk drives - B Maximum valid user number - C Delay disk access if typing - B Operating system - A Single-user system - B Multi-user MP/M - C Multi-user Turbo DOS - D ZCPR3 - C Memory usage - D WordStar files - E Directory display - F Computer patches - D WordStar - A Page layout - A Page sizing & margins - B Headers & footers - C Tabs - B Editing settings - A Edit screen & help level - B Typing - C Paragraph alignment - D Blocks - E Erase & unerase - F Lines & characters - G Find & replace - H WordStar 3.3 compatibility - I Printing defaults - C Other features - A Spelling checks - B Nondocument mode - C Indexing - D Shorthand (key macros) - E Merge printing - F Miscellaneous - E Patching - A Auto patcher - B Save settings - C Reset all settings - -MEMORY USAGE ------------- - - WordStar requires a minimum TPA size of 50 kbytes to run - using the factory defaults. The TPA is the amount of memory - available in your computer for use by programs that have a - file type of COM. To see how big the TPA is in your computer, - press the question mark key (?) at the Opening Menu. - - The amount of memory required by WordStar can be reduced by - approximately 3 kbytes if necessary. Use the WSCHANGE program - to select the minimum memory configuration option. The menu - will show you what capabilities are being reduced. - - WordStar uses a general-purpose buffer for a variety of - tasks. WordStar allocates memory to this buffer for editing, - for merge printing, and at the Opening Menu (see BFSIZE in - PATCH.LST). The buffer used for editing is usually the most - sensitive to a reduced TPA size. (You may be able to use the - Opening Menu and print, but there may be insufficient memory - for editing.) - - The merge print buffer is used only to hold merge print - variable names and data. Increase it if you run out of memory - while merge printing. - - The Opening Menu buffer is used primarily to hold the file - directory, and for miscellaneous tasks. - - -LOW-MEMORY INDICATOR IN STATUS LINE ------------------------------------ - - If the Low-Memory indicator appears in the status line, it - means that WordStar was unable to complete some function. - The most common symptoms are: the line number in the - status line is wrong, or a paragraph alignment could not be - completed. You may correct the line counter by saving your - file, exiting WordStar, and re-loading your file. To correct - the paragraph alignment, move your cursor to the point where - paragraph alignment stopped, and then press ^B again. - - The reason this comes up is that WordStar was not able to fit - a big enough chunk of text into memory at one time. - - When you first begin editing, WordStar uses the value from - EDSIZE in the user area to determine the minimum amount - of memory required for a page of text. The default - is set for approximately a 55 line by 66 column page. If - your page size is routinely larger than this, you may want - to increase EDSIZE. Multiply the number of lines by the - number of columns, and divide by 128. - - If the Low-Memory indicator comes on while printing, it is due - to either the same reasons as for editing, or there is - insufficient memory to print the text proportionally spaced. - The amount of memory required depends on which printer - driver you are using. If you aren't using the .PS ON dot - command to turn proportional spacing on in your document, - low memory won't be a problem. Also, WordStar uses more - memory for merge printing than it does for regular printing - (around 2.5 kbytes more). - - The Low-Memory indicator will also appear when a full disk error - is encountered during editing. Treat the disk-full error as you - would normally. - - -RAM-RESIDENT PROGRAMS ---------------------- - - RAM-resident programs, such as SmartKey, reduce the amount of - working memory (TPA) that WordStar can use. The new features in - WordStar, such as shorthand, may reduce the need for these - RAM-resident programs, thus freeing memory for WordStar. - - -ZCPR3 SUPPORT -------------- - - In order to enable the ZCPR facilities within WordStar, the user - must use the Z3INS utility provided with ZCPR to install the - address of the ZCPR "environment" into WordStar. The environment - contains information that WordStar uses to support ZCPR-specific - functions. - - Generally, the user should log onto the drive containing the file - WS.COM, and issue the command: - - Z3INS SYS.ENV WS.COM - - The user should also run either WINSTALL or WSCHANGE to further - install WordStar for ZCPR. However, this is not mandatory because - the only thing that happens is that the WordStar sign-on says - "ZCPR3," and the LGLUSR location in the user area is changed for a - maximum user number of 31. (The normal default for LGLUSR is 15.) - - Once the user has installed WordStar for use with ZCPR, the user - will be able to use the following ZCPR features: - - - A named directory may be used when logging onto a new drive/user. - - - A named directory may be used instead of a drive/user as part - of any file name. - - - The drive/user always appears above file directories. (For CP/M - only the drive letter is shown if the user number is zero.) - - - The directory name also appears above the directory if one has - been defined for the currently logged drive/user. - - - If WordStar does not find its OVR files on the current drive and - user, it will search the drives and user numbers in the ZCPR - search path rather than using its standard search pattern. - - - WordStar installs itself as a ZCPR "shell" process which lets the - user enter any legal ZCPR command when running a program. (CP/M - can only run programs that are COM files.) - - -OSBORNE USERS -------------- - - The command to change a hard carriage return to a soft carriage - return (document mode) or to turn Auto-indent ON (nondocument - mode) does not function on the Osborne because of a limitation - in its BIOS. The following patch can be applied to change the - command from ^^ to ^- (Ctrl-Hyphen): - - Using DDT or SID in the file WSMSGS.OVR: - - At 02DA replace 1E with a 1D - At 02EF replace 1E with a 1D - At 0359 replace 1E with a 1D - At 06B2 replace 1E with a 1D - At 06C9 replace 1E with a 1D - - At the system prompt type SAVE 53 WSMSGS.OVR - - For more information on how to use SID or DDT, see your CP/M - reference guide. As always, be sure and apply the patch to a - COPY of the file. - - -INSTRUCTIONS FOR TWO FLOPPY DISK COMPUTERS ------------------------------------------- - - Do not remove the Program disk while you are using WordStar. - - The Printer Driver Library file (WSPRINT.OVR) on the WordStar - program disk is much smaller than the Printer Driver Library - file contained on the disk labeled PRINTER. Be sure to read the - section in "Starting" that discusses the printer library file. - - -RUN A PROGRAM -------------- - - Once you press R you can type the drive and user number for the - program you want to run. You may run only .COM files. CCP commands, - such as DIR cannot be used. - - -INDEXING --------- - -Using StarIndex - - StarIndex 1.01 works with files created with this release of - WordStar. - -"Can't Use That Printer" Message - - When WordStar creates an index or table of contents, it uses - the printer drivers $INDEX and $TOC. If you created a smaller - WSPRINT.OVR file, you may have left these drivers out. To - return them to the file, copy the original WSPRINT.OVR file - onto your disk. When you create a smaller file again, be sure - to save these drivers. See Appendix C in the WordStar manual - for a list of other drivers to save. - - -SPELL CHECKING --------------- - - Dual floppy disk users: - - Unless you have sufficient room on your working WordStar program - disk for the files TW.COM, SPELL.COM, MARKFIX.COM, REVIEW.COM and - MAINDICT.CMP you will not be able to run a spell check from the - Opening Menu. You will need to exit WordStar and replace the - working WordStar program disk with the dictionary disk you created - during installation. This disk should contain the files listed - above. Make sure the disk in drive B has the file you want to - spell-check. - - Follow the directions for running a spell check in The WORD Plus - manual. - - -UPGRADING FROM A PREVIOUS RELEASE ---------------------------------- - - This release of WordStar contains many new features and commands. - See the "What's New" booklet for a complete list. The following - changes came in too late to be included in the documentation. - -Printer Patches - - Previous versions of WordStar treat most dot matrix printers - and other non-daisy wheel printers as a DRAFT printer with a - few patchable items. Because of this, many users have used - these patches to be able to use certain features of their - printers. Sometimes the patches have been quite extensive, and - some users have many files that count on them. - - The printer drivers of WordStar Release 4, on the other hand, - are very powerful. Almost every driver recognizes all the print - controls and all the dot commands. In fact, if a document is - written to be printed on one kind of printer, it is likely that - it will also print fine on some other printer. - - However, if you want to use your existing files with WordStar - 4, and those files rely on the user area being patched in a - special way, you can probably do so by moving the patches into - WordStar 4, and using the CUSTOM or SIMPLE printer driver. - - On the INSTALL disk is a program called MOVEPRN.COM that - copies the printer driver portion of the previous release's - user area into files that can be installed into Release 4 with - the "auto patcher" feature. - - Copy the program MOVEPRN.COM onto the disk containing the - WS.COM file for the previous version. Type - - MOVEPRN WS.COM FILE1.PAT FILE2.PAT - - MOVEPRN extracts the proper portions of the user area and - writes them into two files that may then be used with the "auto - patcher" feature of WSCHANGE. - - FILE1.PAT is to be used with the general patching menu - (Choose E "Patching" on the WSCHANGE Main Menu, then A "Auto - Patcher"). FILE2.PAT should be used to install strings first - into the SIMPLE driver, and then into the CUSTOM driver (choose - B "Printer" on the WSCHANGE Main Menu, then B "Printer driver - library", D "Change printer driver data" and D "Driver auto - patcher"). - - Test print your document first with the SIMPLE driver, and then - with the CUSTOM driver to see which one produces the most - satisfactory results. - - Also read Appendix C for more information on using the Auto - Patcher. - - -Hanging Indents - - For WordStar Professional Release 4, MailMerge reformats indented - text created with ^OG to the current margins. If you want the text - to remain indented, use embedded ruler lines or the .RM, .LM, - and .PM commands. See the "Reference Guide" for more information. - - Pressing ^OG to wrap back to the first tab on the ruler line after - having reached the last tab works the same way it did in previous - versions of WordStar, contrary to what is stated in the manual. - - -TERMINALS ---------- - - WordStar comes installed for an "idealized" special terminal. - WINSTALL and WSCHANGE allow you to install many terminals by - name, thus allowing WordStar to take advantage of the special - features that the terminal might support, such as underlining - or the function keys. - - Use either WINSTALL or WSCHANGE to pick your specific terminal - or computer screen from the Monitor menu. If your terminal - isn't on the menu, it probably emulates one of those that is - there. Look in your terminal documentation to find out. - - After you install WordStar for the proper terminal, run - WordStar and open the file PRINT.TST to see which attributes - (such as bold and underline) work on your screen. - WordStar will highlight the following in some way... - - Bold (^PB) - Underline (^PS) - Strike-out (^PX) - Subscript (^PV) - Superscript (^PT) - Doublestrike (^PD) - Italics (^PY) - Blocks (^KB, ^KK) - Error messages - - Most of the time, normal text will be shown in dim intensity, - and highlighted text will be shown in bright intensity. You - may have to use a brightness and/or contrast knob to adjust - your screen the first time you use WordStar this way. - - If your dim intensity is too dim to see well, and you can't - adjust it, you can change the BRITE flag to ON using WSCHANGE. - This will invert bright and dim in your text, so that regular - text is displayed bright, and highlighted text will be - displayed as dim. However, text in the menus is not affected. - - -DISPLAY PROBLEMS WITH TERMINALS -------------------------------- - - Once you have installed WordStar for the proper terminal, you - may still experience display problems. - - If text from the previous screen remains after WordStar - displays a new screenful of text, the most likely cause is - cursor wrap. Basically, WordStar must know what happens to the - cursor when a character is displayed at the rightmost position - of the screen. It can either remain at the right edge, or it - can wrap to the beginning of the next line. The WRAP flag in - WordStar must be set either on or off to correspond to the - way the terminal works. (It is generally set for the - terminal's factory default, but the default can usually be - changed using the terminal's setup mode.) - - Another possible cause for display problems is your terminal's - incomplete emulation of some other terminal. The most - common differences are... - - Line insert (LININS), line delete (LINDEL), - Erase to end of screen (ERAEOS), - Erase to end of line (ERAEOL), - And, erase screen (ERASCR). - - Look in the manual for your terminal and use WSCHANGE to see - if the control sequences match. - - -PRINTERS --------- - -WHAT'S IN THIS SECTION - - This section contains the following information: - - Choosing a Printer - Setting Up Your Printer - Printer Drivers - Proportional Printing - Laser Printers - Information on Specific Printers - -CHOOSING A PRINTER - - WordStar is ready to work with over 100 printers. The printer you - choose during installation becomes your default printer. However, - when you print a document, you can choose any other printer. To - choose a default printer, follow these steps: - - 1. Look at the Printer Information brochure that came in your - package. The first chart shows the printers listed on the - Printer Selection Menus. If your printer is on the menu, - simply choose it during installation. - - 2. If your printer isn't listed on the menu, it may work like a - printer that is. Refer to the second chart in the Printer - Information brochure for a list of printers that work like - printers on the menu. When WordStar asks you to choose a - printer, choose the printer that works like yours. - - 3. If neither chart lists your printer, choose Typewriter Printer - (if your printer can backspace) or Draft Printer (if it can't). - These choices may not take advantage of all your printer's - features, but they will work with almost any printer. - - Note: If you choose Draft or Typewriter, you can modify custom - print controls and printer initialization. - - If you want to make more modifications to take advantage of your - printer's feature, choose the Custom or Simple drivers, then use - the WS Printer Patches section of WSCHANGE to tell WordStar the - codes for your printer. Refer to your printer manual for these - codes. Some printers work better with the Custom driver and some - with the Simple driver. Try using both and see which works better - with your printer. See the "Reference Guide" for more information. - -SETTING UP YOUR PRINTER - -Choosing a Printer Port - - Each printer is connected to a printer port at the back of - the computer. WordStar looks for printers on the LST: port. - If your printer is connected to a different port, use - WSCHANGE to tell WordStar the correct port. - -Testing Your Printer Connection - - At the operating system prompt, type "PIP LST:=READ.ME." This - file should be printed by your printer. If it is not, your printer - may be connected to a different port. See your computer reference - manual, and the section on the STAT command in your CP/M - reference manual for more information. - - -PRINTER DRIVERS - - The WSPRINT.OVR file on the Printers disk contains a printer - driver for each printer on the Printer Selection Menu. The printer - driver for a printer contains all the codes WordStar needs to work - with that printer. - - Each printer driver has a short name. If you choose a printer when - you print a document, you see the names of the printer drivers, not - the names of the printers. - -PROPORTIONAL PRINTING - - WordStar supports proportional printing on a number of printers. - To turn on proportional printing, either install WordStar to - default to proportional printing, or place a ".PS on" command - in your document. At print time, WordStar selects the - appropriate proportional font based on the character width - (.CW) currently in effect. - - The specific printer descriptions later in this section show - recommended character widths for proportional typefaces. - These widths are for a normal mix of upper- and lowercase - letters. If you have many words or phrases all in uppercase - or if you want your text less densely printed, choose a larger - character width. - - While WordStar mostly sets character widths based on the - proportional-width table in the driver, on the more advanced - daisy wheel printers, WordStar uses the printer's proportional- - spacing mode. WordStar determines how much white space is needed - to right-justify the line based on its own proportional width - tables. If the table values don't match the wheel installed, - WordStar won't be able to justify the line correctly. - - WordStar sends standard ASCII characters; if a proportional wheel - uses a different spoke mapping, set up the printer to handle this. - -LASER PRINTERS - - WordStar supports laser printer features such as font changes - and proportional spacing. - - WordStar supports several laser printers: the Canon LPB-8 A1 & A2; - the Hewlett-Packard LaserJet, LaserJet+, and LaserJet 500+; - and the Ricoh LP4080. Refer to the "Specific Printer - Information" section of this file for information on these - printers. General notes about using laser printers are given below. - -Paper Size and Margins - - Laser printers come with preset page margins. You need to - compensate for these margins by changing page length in your - WordStar documents. The chart below shows the recommended - settings for 8 1/2 X 11 inch paper for both portrait and landscape - orientations. These settings allow 55 lines of text for portrait - orientation and 40 lines of text for landscape orientation (at 6 - lines per inch). They also allow for a footer of up to 3 lines - and a one-line header. If you use multiple-line headers, adjust - the top margin accordingly. - - Dot Default Portrait Landscape - Setting Command Value Orientation Orientation - ------- ------- ------- ----------- ----------- - page length .PL 66 62 47 - top margin .MT 3 2 2 - bottom margin .MB 8 5 5 - header margin .HM 2 1 1 - footer margin .FM 2 2 2 - - If the laser printer is your primary printer, you can use WSCHANGE - to make these settings the defaults. - - Because laser printers leave small margins at the left and right - sides of the page, you may want to use a smaller page offset - setting (the default is .PO 8). - -Form Feeds - - When you print with a laser printer, answer Y for yes to the "Use - form feeds (Y/N)?" prompt at print time. (The default is NO.) If - the laser printer is your primary printer, you can use WSCHANGE to - change the default to yes. - -WordStar Commands for Font Selection - - The WordStar dot commands and print control commands listed below - determine the fonts used for printing a document. - - .PR .PR OR=L selects landscape orientation; .PR OR=P (or just - .PR OR) selects portrait orientation (the default). If - either of these commands appears after the first printing - line on a page, the orientation will not change until the - following page. - - .PS .PS ON selects proportionally spaced characters; .PS OFF - (the default) selects fixed-spaced characters. - - .CW The character-width setting (.CW followed by the width in - 120ths of an inch) determines the character pitch and font - selected for fixed-width printing. For proportional fonts, it - determines the point size and proportional-width table - selected. - - .LQ .LQ ON selects near letter quality print (if supported by - your printer). LQ OFF selects draft quality print. Default - is ON. - - ^PY The italic print control toggles between normal and italic - characters when the appropriate italic font is available. - - ^PB The boldface print control toggles between normal and bold - characters when the appropriate bold font is available. - - ^PD The double strike print control used with the laser printers - toggles overprinting with a horizontal offset of 1/120" - between the two character images. This allows a bold effect - where no bold font is available. - - ^PA ^PA turns alternate pitch on. Use .CW to assign different - character widths to normal pitch (see ^PN below) and alternate - pitch so that each pitch accesses a different font. You can - then change fonts by switching between the two pitches. This - is the only way to use two fonts on the same line. - (See "Character width" and "Pitch" in the "Reference Guide.") - - ^PN ^PN turns normal pitch on. You can use it with ^PA as - described above. - - ^P@ When working with columns, if you use alternate and normal - pitch for two fonts, or if you use proportional spacing, you - may need to use ^P@ to make sure the columns line up. - Remember that the column position set with ^P@ is determined - by the normal pitch character width. (See "Columns" and - "Proportional spacing" in the "Reference Guide." - -INFORMATION ON SPECIFIC PRINTERS - - This section describes the capabilities of each printer listed on - the Printer Selection Menu. The printers are listed in alphabetical - order (except for the generic printers such as "Draft," - "Typewriter," "Custom," "Simple," and the various print-to-disk - options, which are listed first). - - There is a chart for each printer explaining how features work and - listing any special notes about the printer. Each printer is - described in the following format: - -PRINTER NAME ----- Driver: (short name) - - ^PY Effect of italics/ribbon color print control - ^PT/V Subscript/superscript information - .CW Information on available character widths and fonts. The - chart shows the .CW, .LQ, and .PS settings required to use - different fonts. - - .LQ OFF .LQ ON .PS ON Font Name - ------- ------ ------ --------- - .cw val .cw val recommended value (range) font 1 - .cw val .cw val recommended value (range) font 2 - - .UL Continuous-underline information (if restrictions) - .UJ Microspace-justification information (if restrictions) - - N/A means a command has no effect on this printer. - - NOTES Switch settings, special features, anomalies. - -DRAFT PRINTER (nonbackspacing) ----- Driver: DRAFT - - ^PD Overprints the line twice - ^PB Overprints the line three times - ^PS Overprints the underscore character in a separate pass - ^PT/V Prints super/subscripts with a full line between - super/subscript and text - .LH Sets line height only in multiples of full lines - .CW N/A - .PS N/A - .LQ N/A - .UJ N/A - - NOTES This driver works with any printer that doesn't automatically - perform a line feed when it receives a carriage return command. All - overprinting is done by returning the carriage and passing over the - line again. - -TYPEWRITER PRINTER (backspacing) ----- Driver: TYPEWR - - ^PD Backspaces and overprints each character twice - ^PB Backspaces and overprints each character three times - ^PS Backspaces and overprints the underscore character - ^PT/V Prints super/subscripts with a full line between - super/subscript and text - .LH Sets line height only in multiples of full lines - .CW N/A - .PS N/A - .LQ N/A - .UJ N/A - - NOTES This driver works with any printer that doesn't automatically - perform a line feed when a it receives a carriage return command, - and responds to a backspace character. Overprinting is done by - backspacing. - -AUTO LINE FEED PRINTER (backspacing) ----- Driver: AUTOLF - - ^PD Backspaces and overprints each character twice - ^PB Backspaces and overprints each character three times - ^PS Backspaces and overprints the underscore character - ^PT/V Prints super/subscripts with a full line between - super/subscript and text - .LH Sets line height only in multiples of full lines - .CW N/A - .PS N/A - .LQ N/A - .UJ N/A - - NOTES This driver works with any printer that automatically - performs a line feed when it receives a carriage return character, - and responds to a backspace command. Overprinting is done by - backspacing. - -SIMPLE CUSTOMIZABLE PRINTERS ----- Driver: SIMPLE - - All print controls cause control strings (on and off) in - the user area to be sent to the printer. These strings - are used by both the SIMPLE and CUSTOM drivers. They can - be installed with the WSCHANGE program. - - .LQ Controlled by user area strings - .PS Controlled by user area strings - .CW N/A - .UJ N/A - .LH N/A - - NOTES This printer driver prints the line in one pass, sending - control strings from the user area to select print enhancements. - -CUSTOMIZABLE PRINTERS ----- Driver: CUSTOM - - All print controls cause control strings (on and off) in - the user area to be sent to the printer. These strings - are used by both the SIMPLE and CUSTOM drivers. They can - be installed with the WSCHANGE program. - - .LQ ON/OFF controlled by user area strings - .PS ON/OFF controlled by user area strings - .LH Sets line height only in multiples of full lines - .UJ N/A - .CW N/A - - NOTES This driver prints the line in multiple passes, sending - control strings from the user area to select print enhancements. - -PREVIEW TO DISK ----- Driver: PRVIEW - - This driver prints documents to the PREVIEW.WS file to allow - you to preview the format and appearance of a document before - printing. Headers, footers, and pagination are shown correctly - and print controls remain in the file to display onscreen - attributes. Dot commands are not printed. - -PRINT TO DISK WITHOUT PRINT CONTROLS ----- Driver: ASCII - - This driver prints to the ASCII.WS file, stripping headers and - footers, high bits, and print controls. - -PRINT TO DISK WITHOUT HEADERS AND FOOTERS ----- Driver: XTRACT - - This driver prints to the XTRACT.WS disk file, stripping headers - and footers, but preserving high bits and print controls. - -ANADEX 9500A, 9500B ----- Driver: 9500 - - ^PY N/A - ^PT/V Even superscript roll - - .CW .CW Font name - --- --------- - 9 13.3 cpi - 10 12 cpi - 12 10 cpi - 18 6.7 cpi - 20 6 cpi - 24 5 cpi - - .LH 1/24" resolution, use even values - .UJ This printer has no incremental horizontal positioning - .PS N/A - .LQ N/A - -ANADEX 9501B, INTEQ 5100B ----- Driver: 9501B - - ^PY N/A - ^PT/V Even superscript roll - - .CW .CW Font name - --- --------- - 7 16.7 cpi - 8 15 cpi - 10 12.5 cpi - 12 10 cpi - 14 8.3 cpi - 16 7.5 cpi - 20 6.2 cpi - 24 5 cpi - - .LH 1/24" resolution, use even values - .UJ This printer has no incremental horizontal positioning - .PS N/A - .LQ N/A - -C. ITOH STARWRITER 1550 AND 8510 ----- Driver: C1550 - - ^PY N/A - ^PT/V Prints full-size characters with roll - - .CW .CW Font Name - --- --------- - 7 compressed - 10 elite - 12 pica - 14 expanded compressed - 20 expanded elite - 24 expanded pica - - .LQ N/A - .PS N/A - .UL Continuous underlining suppresses microspace justification - -C. ITOH F10 STARWRITER ----- Driver: QUME - - See Diablo 630, 1610, 1620 Daisy Wheel. - - Note: Proportional printing was tested with a Theme 10 wheel. - -CANON LBP-8A1 AND LBP-8A2 LASER PRINTER ----- Driver: LBP8 - - ^PY Selects italics if appropriate font installed - ^PT/V Prints full-size characters with roll - .PS .PS - .CW OFF ON Font Name - --- -- --------- - 6 - 20 cpi - 8 - 15 cpi - 9 - 13.3 cpi - 10 - 12 cpi (elite) - 12 - 10 cpi - 20 - 6 cpi - 24 - 5 cpi - 16 - 7.5 cpi - - 7 (0-8) Garland 8 point - - 10 (9-11) Garland 12 point - - 14 (12-17) Expanded 8 point - - 20 (18-30) Expand \ No newline at end of file diff --git a/branches/s100/RomDsk/CPM_1024KB/WSSHORT.OVR b/branches/s100/RomDsk/CPM_1024KB/WSSHORT.OVR deleted file mode 100644 index b44f1480..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSSHORT.OVR and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/WSU.COM b/branches/s100/RomDsk/CPM_1024KB/WSU.COM deleted file mode 100644 index 39830fdf..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/WSU.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/XSUB.COM b/branches/s100/RomDsk/CPM_1024KB/XSUB.COM deleted file mode 100644 index 15e86abf..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/XSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/ZAP.COM b/branches/s100/RomDsk/CPM_1024KB/ZAP.COM deleted file mode 100644 index 47ffcbb8..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/ZAP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/ZDE.COM b/branches/s100/RomDsk/CPM_1024KB/ZDE.COM deleted file mode 100644 index 8814a523..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/ZDE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_1024KB/ZDENST.COM b/branches/s100/RomDsk/CPM_1024KB/ZDENST.COM deleted file mode 100644 index 8ccc9767..00000000 Binary files a/branches/s100/RomDsk/CPM_1024KB/ZDENST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/ASM.COM b/branches/s100/RomDsk/CPM_512KB/ASM.COM deleted file mode 100644 index a63e5aec..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/ASM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/CLRDIR.COM b/branches/s100/RomDsk/CPM_512KB/CLRDIR.COM deleted file mode 100644 index d1f2a7d6..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/CLRDIR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/CR.COM b/branches/s100/RomDsk/CPM_512KB/CR.COM deleted file mode 100644 index 8a824bcc..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/CR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/DDT.COM b/branches/s100/RomDsk/CPM_512KB/DDT.COM deleted file mode 100644 index 83f8603f..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/DDT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/DDTZ.COM b/branches/s100/RomDsk/CPM_512KB/DDTZ.COM deleted file mode 100644 index e30a34c0..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/DDTZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/DIF.COM b/branches/s100/RomDsk/CPM_512KB/DIF.COM deleted file mode 100644 index 87b89d75..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/DIF.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/DIRX.COM b/branches/s100/RomDsk/CPM_512KB/DIRX.COM deleted file mode 100644 index 413bceca..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/DIRX.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/DUMP.COM b/branches/s100/RomDsk/CPM_512KB/DUMP.COM deleted file mode 100644 index 03a77c3c..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/DUMP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/ED.COM b/branches/s100/RomDsk/CPM_512KB/ED.COM deleted file mode 100644 index a0f0f541..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/ED.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/FLASH.MAN b/branches/s100/RomDsk/CPM_512KB/FLASH.MAN deleted file mode 100644 index e57de5c2..00000000 --- a/branches/s100/RomDsk/CPM_512KB/FLASH.MAN +++ /dev/null @@ -1,35 +0,0 @@ -NAME - flash - in-situ 29F040 flash ROM programmer for N8VEM, Zeta and N8 computers -SYNOPSIS - flashz - flashn8 -DESCRIPTION - The flashz and flashn8 erase and program the FLASH ROM chip from an - image file. flashz is used for the N8VEM Z80-SBC and Zeta computers. - flashn8 is used with the N8 home computer. Both function the same - except in the way memory is addressed. - - flash expects a 512k file in the same directory containing the image - that will be programmed into the ROM. This file must have the - unimaginative filename of ROM.IMG. The whole process of erasing and - programming the ROM takes less than a minute - far less than the time - taken to upload your new image. - - This program is only suitable for 29F040 512k FLASH ROMs. - - Assemble with TASM using the command - tasm -t80 -g3 flashz.asm flashz.com - tasm -t80 -g3 flashn8.asm flashn8.com - -JUMPERS - The following jumpers must be in place on the boards to allow the - 29F040 to be programmed. - For the N8VEM Z8-SBC MK-II: K1 1-2, K6 2-3, K8 2-3 - For the N8: K3 1-2, K4 2-3, K5 2-3 - For the Zeta, no jumpers need (or can) be set. - -AUTHOR - Written by David Giles so he doesn't have to open the box his Zeta - lives in so often. Reports to N8VEM group or vk5dg@internode.on.net - - diff --git a/branches/s100/RomDsk/CPM_512KB/LBREXT.COM b/branches/s100/RomDsk/CPM_512KB/LBREXT.COM deleted file mode 100644 index c0c950e3..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/LBREXT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/LIB.COM b/branches/s100/RomDsk/CPM_512KB/LIB.COM deleted file mode 100644 index 45d7fb21..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/LIB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/LINK.COM b/branches/s100/RomDsk/CPM_512KB/LINK.COM deleted file mode 100644 index e188fb92..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/LINK.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/LOAD.COM b/branches/s100/RomDsk/CPM_512KB/LOAD.COM deleted file mode 100644 index b9601e00..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/LOAD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/MBASIC.COM b/branches/s100/RomDsk/CPM_512KB/MBASIC.COM deleted file mode 100644 index c9ec3cd3..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/MBASIC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/NULU.COM b/branches/s100/RomDsk/CPM_512KB/NULU.COM deleted file mode 100644 index fc5594b1..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/NULU.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/PIP.COM b/branches/s100/RomDsk/CPM_512KB/PIP.COM deleted file mode 100644 index 4b2ce4b6..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/PIP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/RMAC.COM b/branches/s100/RomDsk/CPM_512KB/RMAC.COM deleted file mode 100644 index 9ab7206b..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/RMAC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/SID.COM b/branches/s100/RomDsk/CPM_512KB/SID.COM deleted file mode 100644 index 3b073ba5..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/SID.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/STAT.COM b/branches/s100/RomDsk/CPM_512KB/STAT.COM deleted file mode 100644 index 1de359f2..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/STAT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/SUBMIT.COM b/branches/s100/RomDsk/CPM_512KB/SUBMIT.COM deleted file mode 100644 index 2e788827..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/SUBMIT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/SUPERSUB.COM b/branches/s100/RomDsk/CPM_512KB/SUPERSUB.COM deleted file mode 100644 index a25d60a6..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/SUPERSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/UNARC.COM b/branches/s100/RomDsk/CPM_512KB/UNARC.COM deleted file mode 100644 index 8cc90746..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/UNARC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/UNCR.COM b/branches/s100/RomDsk/CPM_512KB/UNCR.COM deleted file mode 100644 index 42385ddd..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/UNCR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/UNZIP.COM b/branches/s100/RomDsk/CPM_512KB/UNZIP.COM deleted file mode 100644 index afde7204..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/UNZIP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/XSUB.COM b/branches/s100/RomDsk/CPM_512KB/XSUB.COM deleted file mode 100644 index 15e86abf..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/XSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/ZAP.COM b/branches/s100/RomDsk/CPM_512KB/ZAP.COM deleted file mode 100644 index 47ffcbb8..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/ZAP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/ZDE.COM b/branches/s100/RomDsk/CPM_512KB/ZDE.COM deleted file mode 100644 index 8814a523..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/ZDE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/CPM_512KB/ZDENST.COM b/branches/s100/RomDsk/CPM_512KB/ZDENST.COM deleted file mode 100644 index 8ccc9767..00000000 Binary files a/branches/s100/RomDsk/CPM_512KB/ZDENST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ReadMe.txt b/branches/s100/RomDsk/ReadMe.txt deleted file mode 100644 index 0a74378c..00000000 --- a/branches/s100/RomDsk/ReadMe.txt +++ /dev/null @@ -1,32 +0,0 @@ -This is the parent directory for all files to -be included in the rom disk when the ROM is built. - -When constructing the ROM disk as part of a build, -the build process first grabs all of the "standard" -files for the size of ROM being built and the type -of the OS being used. So, if you are building a -ZSystem, 1MB ROM, all of the files in zsys_1024KB -will be pulled in. If you are building a CP/M -512KB ROM, then all the files in cpm_512KB will -be pulled in. - -After adding all of the standard files for the -size of ROM being built, the build process will -add the files from the appropriate configuration -directory. So, if you are building the "zeta" -configuration, all of the files in the cfg_zeta -directory will be added. - -Finally, the build process will gather all of the -custom applications created by Douglas in the -Apps directory and add those. - -If you are building your own ROM, you will need to -add a new directory of the name cfg_xxx where xxx -is the name of your configuration that matches the -config_xxx.asm file in the Source directory. You -will want to add any specific files you want added -to your ROM build to this directory. Note that the -build will complain if there are no files in your -custom configuration directory, but it is not a -real problem (error can be ignored). \ No newline at end of file diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ASM.COM b/branches/s100/RomDsk/ZSYS_1024KB/ASM.COM deleted file mode 100644 index a63e5aec..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ASM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/CLOCKS.DAT b/branches/s100/RomDsk/ZSYS_1024KB/CLOCKS.DAT deleted file mode 100644 index f44fa3c0..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/CLOCKS.DAT and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/CLRDIR.COM b/branches/s100/RomDsk/ZSYS_1024KB/CLRDIR.COM deleted file mode 100644 index d1f2a7d6..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/CLRDIR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/COPY.CFG b/branches/s100/RomDsk/ZSYS_1024KB/COPY.CFG deleted file mode 100644 index 3d5310ac..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/COPY.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/COPY.COM b/branches/s100/RomDsk/ZSYS_1024KB/COPY.COM deleted file mode 100644 index 87c0c2fb..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/COPY.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/COPY.UPD b/branches/s100/RomDsk/ZSYS_1024KB/COPY.UPD deleted file mode 100644 index 3725b0e8..00000000 --- a/branches/s100/RomDsk/ZSYS_1024KB/COPY.UPD +++ /dev/null @@ -1,43 +0,0 @@ - 11 Dec 88 - -Some changes have been made to COPY since the manual was written. -Comparison of dates with Existence testing ON has been changed to -use the Creation date when no Modified date exists, and print -"Undated" when neither exists, yet both source and destination -disks support file date stamping. Additionally, the /X option -has been re-defined, and a new /R option has been added to -Version 1.4. Please replace Paragraph 4.1.2.9 on page 55 of your -ZSDOS manual with the following two paragraphs describing the new -options. - - -4.1.2.9.1 ERASE SOURCE FILE AFTER COPY. - -When you want to "move" a file from one area to another, the "X" -option may be used. This option causes a file or group of files -to be copied in the manner described by the default or specified -options, but after the copy and optional verify, the source file -or files are erased. You will be notified that the file has been -erased by the status "(X)" being printed on your console. To -minimize the possibility of deleting a good file when errors -exist in the copy, the Verify option should always be active, -either by default, or specified. When Verify is active, any -errors detected will disable the "X" option for that file so that -a good source file will not be deleted. The "X" option has no -configurable value, and is always assumed to be "Off" requiring -the option in the command line list to be effective. - - -4.1.2.9.2 COPY ONLY FILES WHICH EXIST (REPLACE). - -Occasionally, you may wish to update selected files to a destina- -tion in a simpler manner than naming each file, or using the -Inspect option. The "R" (Replace) option, when active, tells -COPY to transfer only files which exist on the destination direc- -tory. If the Archive option (A) is added in conjunction with the -Replace option, only files which have not been archived, AND -already exist on the destination will be archived. It should be -noted that the No Replacement (N) option is incompatible with -both the Replace and Archive options, and is disabled when either -"R" or "A" are active. - \ No newline at end of file diff --git a/branches/s100/RomDsk/ZSYS_1024KB/CR.COM b/branches/s100/RomDsk/ZSYS_1024KB/CR.COM deleted file mode 100644 index 8a824bcc..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/CR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/DATSWEEP.COM b/branches/s100/RomDsk/ZSYS_1024KB/DATSWEEP.COM deleted file mode 100644 index 5d298c0b..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/DATSWEEP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/DDT.COM b/branches/s100/RomDsk/ZSYS_1024KB/DDT.COM deleted file mode 100644 index 83f8603f..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/DDT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/DDTZ.COM b/branches/s100/RomDsk/ZSYS_1024KB/DDTZ.COM deleted file mode 100644 index e30a34c0..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/DDTZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/DDTZ.DOC b/branches/s100/RomDsk/ZSYS_1024KB/DDTZ.DOC deleted file mode 100644 index e4470528..00000000 --- a/branches/s100/RomDsk/ZSYS_1024KB/DDTZ.DOC +++ /dev/null @@ -1,564 +0,0 @@ - - DDTZ v2.7 - by C.B. Falconer - edited by George A. Havach - -Introduction: -============ -DDTZ v2.7 is a complete replacement for DDT, Digital Research's -famous Dynamic Debugging Tool, with improved functionality, bug -extermination, and full Z80 support. In general, DDTZ is fully -compatible with the original utility, but it has extra and -extended commands and many fewer quirks. All Z80-specific -instructions can be (dis)assembled, though in Intel rather then -Zilog format. Furthermore, DDTZ will correctly trace ('T' and 'U' -commands) both 8080 and Z80 instructions, depending on which CPU -is operating. On startup, the program announces which CPU it is -running on. - -DDTZ v2.7 now handles the 64180 added opcodes. It does NOT test -for a 64180 CPU, since this cannot be done without executing -illegal Z80 instructions, which in turn will crash some -simulators. However v2.7 does not execute any 64180 instructions -internally, only in the subject program. - -This issue supplies the "M" version assembled, to avoid errors -when switching between MSDOS and CPM systems. The command table -is updated accordingly. Most CPM users are also MSDOS users, but -not vice-versa. - -The program is invoked by typing - - ddtz -or - ddtz [d:]filespec - -In the second form, DDTZ will load the specified file into -memory starting at 0100H, unless it's a .HEX file that sets its -own load address. Besides reporting the NEXT free address and -the PC (program counter) after a successful load, DDTZ also shows -the number of memory pages needed for a SAVE. Instead of having -to write all this down, just use the 'X' command at any time to -redisplay these three values for the current application. - -NOTE: loading more code above the NEXT pointer revises these - values. - -As in DDT, when a program is loaded above the area holding the -'A' and 'U' (and now 'W') command code, these commands are -disabled, and the extra memory is released to the user. Thus, -DDTZ can occupy as little as 3K total memory space. Unlike DDT, -however, DDTZ will not overwrite itself or the system on program -loads (except .HEX files). - -At initialization, the stack pointer (SP) points to a return to -DDTZ, just like for the CCP. Thus, programs that normally return -to the CCP will be returned to DDTZ. The 'B' command -reinitializes this condition. - - -The intercept vector copies the BDOS version number, etc., so -an object program does not know that DDTZ is running (except -for BIOS-BDOS vector size). Thus, programs that check the version -number should execute correctly under DDTZ. - -All input parameters can now be entered in any of three formats: - - (1) hexadecimal (as in DDT), - (2) decimal, by adding a leading '#' character, - (3) ASCII, by enclosing between either single or double - quotes; either one or two characters are allowed. - -Leading blanks in command lines and parameters are absorbed. -Either a comma or a (single) space is a valid delimiter. -Either uppercase or lowercase input is accepted. - -The default command (for anything not otherwise recognizable) -is 'H'. This allows convenient calculation, along with the other -features described below. So, to convert a number, just enter -it! - -As in DDT, the prompt character is '-', and the only error -message is the query ('?'), which generally kicks you back to -command mode. - -New Commands (Over DDT): -======================= - -NOTE: letters in parenthesis, e.g. "(U)", show the equivalent - command for DDTZM version (compatible with MSDOS debug). - - @ Sets or shows (with no parameter) the internally stored - "base" value. Also used with the 'S' and 'D' commands as - an optional parameter (though without the '@') to display - memory from an arbitrary base marker (offset). When set to - zero (the default), it does not affect any screen displays. - - B B)egin: resets the USER stack pointer to its initial value, - such that any program that exits by an RET will return to - DDTZ. DDTZ provides a default stack space of - approximately 24 bytes for user programs. - - C C)ompare first_address,last_address,against_address: shows - all the byte differences between two memory areas, in the - format - - XXXX aa YYYY bb - - where XXXX and YYYY are the comparative memory addresses, - and aa and bb are the corresponding byte values. Can be - used to verify the identity of two files by first - loading them into different memory areas with the 'R' - command (see below). - - - W Write: stores the modified memory area to disk under the - (K) filename specified by the 'I' command, overwriting the - original file from which it was loaded (the user is queried - before doing so). By default, the image of memory from - 0100H through the "NEXT" value -1 is saved. "K first_addr, - last_address" overrides this and allows writing ANY memory - area to a file. Almost a necessity for CPM 3.0 (no SAVE!). - K)eep on DDTZ - - X eXamine: redisplays the "NEXT PC SAVE" report at any time. - (Q) Q)uery size on DDTZ. - - S S)earch first_address, last_addr, value: searches the - (W) specified memory area for the value (a 16-bit word, not a - byte) and shows the locations of all such. Very useful for - finding CALL's or JMP's to a particular address, etc. - W)here on DDTZ - - Y Y)our_option parm1,parm2,address: executes an arbitrary - routine at the specified address, with the BC and DE - registers set to parm1 and parm2, respectively. - - Z Displays (but does not alter) the Z80's alternate register - set, including the index registers (disabled if running on - an 8080). On Z80's, automatically included as the last - part of the display by the 'X' command. - - -Based (Offset) Displays: -======================= - -The 'D' and 'E' commands can use a stored base value (offset), -as set by the '@' command. The current @ value may be -overridden for a single execution of these commands by adding the -base as an extra parameter in the command line. The effect is -to add this value to the first/last address and display -accordingly. The address listing on the left becomes XXXX:YYYY, -where XXXX is the offset address and YYYY is the actual memory -address being displayed. For example, if you have a data area -located at 42B7H and wish to preserve easy access, just enter -"@42b7". Now, "d0,3f" will dump memory starting at 4237H. - - -Further Changes from DDT: -======================== - - A A)ssemble now accepts the full Z80 as well as 8080 - instruction set, although it expects them in Intel rather - than Zilog format (see notes below under the 'L' - command). When in doubt, see the mnemnonic list below. - - D D)isplay or D)ump will accept an optional third parameter - to set the base value for a single execution only. Format - has been cleaned up. - - H H)ex_arithmetic on two values also shows their - difference in decimal. With only one value, converts to - hexadecimal, decimal, and ASCII (low-order byte only). - - - N N)ame now allows drive specification (d:...) and sets up - (I) the complete command line, including both FCB's (at - addresses 005CH and 006CH). The tail (stored at 0081H up) - is NOT upshifted. - I)nput on DDTZ - - U U)nassemble now displays the raw hexcode, especially handy - (L) when examining non-code areas. Intel (8080 style) mnemonics - are used, so some disassembled instructions may look - strange. E.g., the Z80's 'IN B,(C)' and 'OUT (C),B' become - 'INP B' and 'OUTP B', respectively; 'LD (nnnn),BC' becomes - 'SBCD nnnn', 'ADD IX, BC' becomes 'DADX B', and 'JP (IX)' - becomes 'PCIX'. - L)ist on DDTZ - - L L)oad now permits loading a file into memory with an - (R) offset, which is added to the default load address of - 0100H. When reading in a .HEX file with a preset bias, - the 'R' command will not transfer control to an invalid - execution point. Another execution of the 'R' command will - reread the input file, e.g.: - - n blah - l - ...modify the code and generally mess about... - l - - The original file is reloaded, and the modifications are - removed. - R)ead on DDTZ - - E E)nter, like D)isplay, now accepts an optional second - (S) parameter to set the base value for a single execution - only. - S)ubstitute or S)et on DDTZ - - T T)rap/trace on termination now shows the complete CPU - state. Traps and traces no longer lock up when a user RST - 7 instruction is executed. Tracing of BDOS/BIOS calls is - heavily trun cated, avoiding clutter and preventing system - crashes. - -NOTE: Most of the UNDOCUMENTED Z80 op-codes are handled. Others - can crash the system. - - R R)egisters also shows what two-byte values the HL and SP - (X) registers are actually pointing to. On Z80's, displays the - alternate register set. - eX)amine on DDTZ - -NOTE: Any use of the 'W' or 'L' command resets the system DMA - transfer address to the standard default value of 0080H. - - -; This is the output of DDTZ when disassembling OPTYPE.TRY -NOP LDA 06A4 MOV M,H -LXI B,06A4 DCX SP MOV M,L -STAX B INR A HLT -INX B DCR A MOV M,A -INR B MVI A,20 MOV A,B -DCR B CMC MOV A,C -MVI B,20 MOV B,B MOV A,D -RLC MOV B,C MOV A,E -EXAF MOV B,D MOV A,H -DAD B MOV B,E MOV A,L -LDAX B MOV B,H MOV A,M -DCX B MOV B,L MOV A,A -INR C MOV B,M ADD B -DCR C MOV B,A ADD C -MVI C,20 MOV C,B ADD D -RRC MOV C,C ADD E -DJNZ 0134 MOV C,D ADD H -LXI D,06A4 MOV C,E ADD L -STAX D MOV C,H ADD M -INX D MOV C,L ADD A -INR D MOV C,M ADC B -DCR D MOV C,A ADC C -MVI D,20 MOV D,B ADC D -RAL MOV D,C ADC E -JR 0134 MOV D,D ADC H -DAD D MOV D,E ADC L -LDAX D MOV D,H ADC M -DCX D MOV D,L ADC A -INR E MOV D,M SUB B -DCR E MOV D,A SUB C -MVI E,20 MOV E,B SUB D -RAR MOV E,C SUB E -JRNZ 0134 MOV E,D SUB H -LXI H,06A4 MOV E,E SUB L -SHLD 06A4 MOV E,H SUB M -INX H MOV E,L SUB A -INR H MOV E,M SBB B -DCR H MOV E,A SBB C -MVI H,20 MOV H,B SBB D -DAA MOV H,C SBB E -JRZ 0134 MOV H,D SBB H -DAD H MOV H,E SBB L -LHLD 06A4 MOV H,H SBB M -DCX H MOV H,L SBB A -INR L MOV H,M ANA B -DCR L MOV H,A ANA C -MVI L,20 MOV L,B ANA D -CMA MOV L,C ANA E -JRNC 0134 MOV L,D ANA H -LXI SP,06A4 MOV L,E ANA L -STA 06A4 MOV L,H ANA M -INX SP MOV L,L ANA A -INR M MOV L,M XRA B -DCR M MOV L,A XRA C -MVI M,20 MOV M,B XRA D -STC MOV M,C XRA E -JRC 0134 MOV M,D XRA H -DAD SP MOV M,E XRA L - - -XRA M JPE 06A4 SLAR M -XRA A XCHG SLAR A -ORA B CPE 06A4 SRAR B -ORA C XRI 20 SRAR C -ORA D RST 5 SRAR D -ORA E RP SRAR E -ORA H POP PSW SRAR H -ORA L JP 06A4 SRAR L -ORA M DI SRAR M -ORA A CP 06A4 SRAR A -CMP B PUSH PSW SLLR B -CMP C ORI 20 SLLR C -CMP D RST 6 SLLR D -CMP E RM SLLR E -CMP H SPHL SLLR H -CMP L JM 06A4 SLLR L -CMP M EI SLLR M -CMP A CM 06A4 SLLR A -RNZ CPI 20 SRLR B -POP B RST 7 SRLR C -JNZ 06A4 RLCR B SRLR D -JMP 06A4 RLCR C SRLR E -CNZ 06A4 RLCR D SRLR H -PUSH B RLCR E SRLR L -ADI 20 RLCR H SRLR M -RST 0 RLCR L SRLR A -RZ RLCR M BIT 0,B -RET RLCR A BIT 0,C -JZ 06A4 RRCR B BIT 0,D -CZ 06A4 RRCR C BIT 0,E -CALL 06A4 RRCR D BIT 0,H -ACI 20 RRCR E BIT 0,L -RST 1 RRCR H BIT 0,M -RNC RRCR L BIT 0,A -POP D RRCR M BIT 1,B -JNC 06A4 RRCR A BIT 1,C -OUT 20 RALR B BIT 1,D -CNC 06A4 RALR C BIT 1,E -PUSH D RALR D BIT 1,H -SUI 20 RALR E BIT 1,L -RST 2 RALR H BIT 1,M -RC RALR L BIT 1,A -EXX RALR M BIT 2,B -JC 06A4 RALR A BIT 2,C -IN 20 RARR B BIT 2,D -CC 06A4 RARR C BIT 2,E -SBI 20 RARR D BIT 2,H -RST 3 RARR E BIT 2,L -RPO RARR H BIT 2,M -POP H RARR L BIT 2,A -JPO 06A4 RARR M BIT 3,B -XTHL RARR A BIT 3,C -CPO 06A4 SLAR B BIT 3,D -PUSH H SLAR C BIT 3,E -ANI 20 SLAR D BIT 3,H -RST 4 SLAR E BIT 3,L -RPE SLAR H BIT 3,M -PCHL SLAR L BIT 3,A - - -BIT 4,B RES 3,D SET 2,H -BIT 4,C RES 3,E SET 2,L -BIT 4,D RES 3,H SET 2,M -BIT 4,E RES 3,L SET 2,A -BIT 4,H RES 3,M SET 3,B -BIT 4,L RES 3,A SET 3,C -BIT 4,M RES 4,B SET 3,D -BIT 4,A RES 4,C SET 3,E -BIT 5,B RES 4,D SET 3,H -BIT 5,C RES 4,E SET 3,L -BIT 5,D RES 4,H SET 3,M -BIT 5,E RES 4,L SET 3,A -BIT 5,H RES 4,M SET 4,B -BIT 5,L RES 4,A SET 4,C -BIT 5,M RES 5,B SET 4,D -BIT 5,A RES 5,C SET 4,E -BIT 6,B RES 5,D SET 4,H -BIT 6,C RES 5,E SET 4,L -BIT 6,D RES 5,H SET 4,M -BIT 6,E RES 5,L SET 4,A -BIT 6,H RES 5,M SET 5,B -BIT 6,L RES 5,A SET 5,C -BIT 6,M RES 6,B SET 5,D -BIT 6,A RES 6,C SET 5,E -BIT 7,B RES 6,D SET 5,H -BIT 7,C RES 6,E SET 5,L -BIT 7,D RES 6,H SET 5,M -BIT 7,E RES 6,L SET 5,A -BIT 7,H RES 6,M SET 6,B -BIT 7,L RES 6,A SET 6,C -BIT 7,M RES 7,B SET 6,D -BIT 7,A RES 7,C SET 6,E -RES 0,B RES 7,D SET 6,H -RES 0,C RES 7,E SET 6,L -RES 0,D RES 7,H SET 6,M -RES 0,E RES 7,L SET 6,A -RES 0,H RES 7,M SET 7,B -RES 0,L RES 7,A SET 7,C -RES 0,M SET 0,B SET 7,D -RES 0,A SET 0,C SET 7,E -RES 1,B SET 0,D SET 7,H -RES 1,C SET 0,E SET 7,L -RES 1,D SET 0,H SET 7,M -RES 1,E SET 0,L SET 7,A -RES 1,H SET 0,M DADX B -RES 1,L SET 0,A DADX D -RES 1,M SET 1,B LXI X,06A4 -RES 1,A SET 1,C SIXD 06A4 -RES 2,B SET 1,D INX X -RES 2,C SET 1,E DADX X -RES 2,D SET 1,H LIXD 06A4 -RES 2,E SET 1,L DCX X -RES 2,H SET 1,M INR [X+05] -RES 2,L SET 1,A DCR [X+05] -RES 2,M SET 2,B MVI [X+05],20 -RES 2,A SET 2,C DADX SP -RES 3,B SET 2,D MOV B,[X+05] -RES 3,C SET 2,E MOV C,[X+05] - - -MOV D,[X+05] DSBC B DADY B -MOV E,[X+05] SBCD 06A4 DADY D -MOV H,[X+05] NEG LXI Y,06A4 -MOV L,[X+05] RETN SIYD 06A4 -MOV [X+05],B IM0 INX Y -MOV [X+05],C LDIA DADY Y -MOV [X+05],D INP C LIYD 06A4 -MOV [X+05],E OUTP C DCX Y -MOV [X+05],H DADC B INR [Y+05] -MOV [X+05],L LBCD 06A4 DCR [Y+05] -MOV [X+05],A RETI MVI [Y+05],2 -MOV A,[X+05] LDRA DADY SP -ADD [X+05] INP D MOV B,[Y+05] -ADC [X+05] OUTP D MOV C,[Y+05] -SUB [X+05] DSBC D MOV D,[Y+05] -SBB [X+05] SDED 06A4 MOV E,[Y+05] -ANA [X+05] IM1 MOV H,[Y+05] -XRA [X+05] LDAI MOV L,[Y+05] -ORA [X+05] INP E MOV [Y+05],B -CMP [X+05] OUTP E MOV [Y+05],C -POP X DADC D MOV [Y+05],D -XTIX LDED 06A4 MOV [Y+05],E -PUSH X IM2 MOV [Y+05],H -PCIX LDAR MOV [Y+05],L -SPIX INP H MOV [Y+05],A -RLCR [X+05] OUTP H MOV A,[Y+05] -RRCR [X+05] DSBC H ADD [Y+05] -RALR [X+05] shld 06A4 ADC [Y+05] -RARR [X+05] RRD SUB [Y+05] -SLAR [X+05] INP L SBB [Y+05] -SRAR [X+05] OUTP L ANA [Y+05] -SRLR [X+05] DADC H XRA [Y+05] -BIT 0,[X+05] lhld 06A4 ORA [Y+05] -BIT 1,[X+05] RLD CMP [Y+05] -BIT 2,[X+05] INP M POP Y -BIT 3,[X+05] OUTP M XTIY -BIT 4,[X+05] DSBC SP PUSH Y -BIT 5,[X+05] SSPD 06A4 PCIY -BIT 6,[X+05] INP A SPIY -BIT 7,[X+05] OUTP A RLCR [Y+05] -RES 0,[X+05] DADC SP RRCR [Y+05] -RES 1,[X+05] LSPD 06A4 RALR [Y+05] -RES 2,[X+05] LDI RARR [Y+05] -RES 3,[X+05] CCI SLAR [Y+05] -RES 4,[X+05] INI SRAR [Y+05] -RES 5,[X+05] OTI SRLR [Y+05] -RES 6,[X+05] LDD BIT 0,[Y+05] -RES 7,[X+05] CCD BIT 1,[Y+05] -SET 0,[X+05] IND BIT 2,[Y+05] -SET 1,[X+05] OTD BIT 3,[Y+05] -SET 2,[X+05] LDIR BIT 4,[Y+05] -SET 3,[X+05] CCIR BIT 5,[Y+05] -SET 4,[X+05] INIR BIT 6,[Y+05] -SET 5,[X+05] OTIR BIT 7,[Y+05] -SET 6,[X+05] LDDR RES 0,[Y+05] -SET 7,[X+05] CCDR RES 1,[Y+05] -INP B INDR RES 2,[Y+05] -OUTP B OTDR RES 3,[Y+05] - - -RES 4,[Y+05] SET 0,[Y+05] SET 4,[Y+05] -RES 5,[Y+05] SET 1,[Y+05] SET 5,[Y+05] -RES 6,[Y+05] SET 2,[Y+05] SET 6,[Y+05] -RES 7,[Y+05] SET 3,[Y+05] SET 7,[Y+05] - -; These are the result of disassembling 64180OPS.TRY -; These opcodes are available ONLY on the 64180 CPU -; DDTZ will both assemble and disassemble these. -IN0 B,20 TST E MLT B -OUT0 20,B IN0 H,20 MLT D -TST B OUT0 20,H TSTI 20 -IN0 C,20 TST H MLT H -OUT0 20,C IN0 L,20 TSIO 20 -TST C OUT0 20,L SLP -IN0 D,20 TST L MLT SP -OUT0 20,D TST M OTIM -TST D IN0 A,20 OTDM -IN0 E,20 OUT0 20,A OIMR -OUT0 20,E TST A ODMR - -; The following are UNDOCUMENTED z80 opcodes from XTDOPS.TRY. -; DDTZ will disassemble these, but will not assemble them. -; They use xh/xl (or yh/yl) as separate byte registers. -; Use these at your own risk. -INRX H ACXR H MOVY H,B -DCRX H ACXR L MOVY H,C -MVIX H,20 SUXR H MOVY H,D -INRX L SUXR L MOVY H,E -DCRX L SBXR H MOVY H,A -MVIX L,20 SBXR L MOVY L,B -MOVX B,H NDXR H MOVY L,C -MOVX B,L NDXR L MOVY L,D -MOVX C,H XRXR H MOVY L,E -MOVX C,L XRXR L MOVY L,A -MOVX D,H ORXR H MOVY A,H -MOVX D,L ORXR L MOVY A,L -MOVX E,H CPXR H ADYR H -MOVX E,L CPXR L ADYR L -MOVX H,B INRY H ACYR H -MOVX H,C DCRY H ACYR L -MOVX H,D MVIY H,20 SUYR H -MOVX H,E INRY L SUYR L -MOVX H,A DCRY L SBYR H -MOVX L,B MVIY L,20 SBYR L -MOVX L,C MOVY B,H NDYR H -MOVX L,D MOVY B,L NDYR L -MOVX L,E MOVY C,H XRYR H -MOVX L,A MOVY C,L XRYR L -MOVX A,H MOVY D,H ORYR H -MOVX A,L MOVY D,L ORYR L -ADXR H MOVY E,H CPYR H -ADXR L MOVY E,L CPYR L - - -Command Summary: -=============== - -DDTZM command DDTZ command -============= ============ -@ (base) -A)ssemble first_address A -B)egin {i.e., initialize stack and return} B -C)ompare first_address,last_address,against_address C -D)ump first_address[,last_address[,base]] D -E)nter_in_memory first_address[,base] S)ubstitute -F)ill first_address,last_address,value F -G)o_to [address][,trap1[,trap2]] G -H)ex_arithmetic value1(,value2) H -L)oad_file (offset) R)ead -M)ove first_address,last_address,destination M -N)nput FCBs_command_line I)nput -Q)uit (not avail) -R)egister examine/change [register|flag] X)amine -S)earch first_address,last_address,word W)hereis -T)race_execution [count] T - Untrace_execution [count] (i.e. do count instr) U)ntrace -U)nassemble_code first_address[,last_address] L)ist code -W)rite [first_address,last_address] K)eep -X)amine {i.e. display memory parameters for application} Q)uery -Y)our_option BC:=parm1,DE:=parm2,call_address Y -Z)80_register_display Z - - -If you find this program useful, contributions will be gratefully -accepted and will encourage further development and release of -useful CPM programs. My practice is to include source. - -C.B. Falconer -680 Hartford Turnpike, -Hamden, Conn. 06517 (203) 281-1438 - -DDTZ and its associated documentation and other files are -copyright (c) 1980-1988 by C.B. Falconer. They may be freely -copied and used for non-commercial purposes ONLY. - diff --git a/branches/s100/RomDsk/ZSYS_1024KB/DIF.COM b/branches/s100/RomDsk/ZSYS_1024KB/DIF.COM deleted file mode 100644 index 87b89d75..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/DIF.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/DSCONFIG.COM b/branches/s100/RomDsk/ZSYS_1024KB/DSCONFIG.COM deleted file mode 100644 index b77dd008..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/DSCONFIG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/DUMP.COM b/branches/s100/RomDsk/ZSYS_1024KB/DUMP.COM deleted file mode 100644 index 03a77c3c..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/DUMP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ED.COM b/branches/s100/RomDsk/ZSYS_1024KB/ED.COM deleted file mode 100644 index a0f0f541..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ED.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FA16.CFG b/branches/s100/RomDsk/ZSYS_1024KB/FA16.CFG deleted file mode 100644 index b7974d36..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/FA16.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FA16.DOC b/branches/s100/RomDsk/ZSYS_1024KB/FA16.DOC deleted file mode 100644 index 08b46875..00000000 --- a/branches/s100/RomDsk/ZSYS_1024KB/FA16.DOC +++ /dev/null @@ -1,264 +0,0 @@ - - FILEATTR - Version 1.6 - - Gene Pizzetta - January 18, 1992 - A ZSDOS utility, copyright (c) 1988 by Carson Wilson. - - -FILEATTR (FA) is a utility that allows rapid settin, resetting, -or displaying of file attributes under ZSDOS, ZRDOS, and CP/M -2.2. Several additional features are available under ZCPR3, -including error flag setting, error handler invocation, an -enhanced display, and better error detection. - -FA will not run under CP/M 3.0 or Z3PLUS. - -USAGE: - - FILEATTR {dir:}{afn} {{/}options} - -If a DIR or DU specification is not given, the current directory -is assumed (under vanilla CP/M only the drive is significant). -If no ambiguous or unambiguous filename is given, all files -("*.*") are matched. - -If no attribute options are given, FILEATTR merely displays the -current state of each file's attributes. Files are displayed in -the order that they appear in the directory. - -Once operation begins, FA cannot be aborted by the user. If a ^C -is entered at the keyboard, all screen output stops, but file -attribute operations continue to completion. If that was not the -case, attributes might be set on some entries for a file and not -on others. Nevertheless, suppressing screen output speeds things -up a bit. - -OPTIONS: A leading slash is required unless the option list is -the second parameter on the command line. Options may be -separated by spaces, commas, or nothing at all. - -ATTRIBUTE OPTIONS: These options set (turn on) corresponding -attributes on files matching the file specification. Attributes -not specified by an attribute option remain unchanged. - -If the option is preceded by a minus ("-") or by an "N", the -corresponding attribute is reset (turned off). - - 1 F1. This is a user attribute which has no predefined - meaning. - - P Public (f2). Under ZSDOS, when this attribute is set, - a file is available from any user area of the disk on - which it resides. A file cannot be made public if - another file with the same name exists in any other - user area on that drive. In that case FA will issue an - error message and leave the attribute off. - - D Inhibit access datestamp (f3). Under ZSDOS, when this - attribute is set, the file's access datestamp will not - be updated, which may speed file access slightly. If - the attribute is turned off, normal access datestamping - resumes. - - 4 F4. This is a user attribute which has no predefined - meaning. - - W Wheel protect (f8). Under ZSDOS, when this attribute - is set, the file becomes read-only when the wheel byte - is off and cannot be erased. If the wheel byte is on, - the file can be erased normally. - - R Read only (t1). When this attribute is set, the file - cannot be erased or modified by most programs. - - S System (t2). When this attribute is set, the file - becomes a "hidden" file that will not be found by most - directory programs or by most well-behaved utilities - that accept ambiguous filenames. (FA must find system - files, of course.) - - A Archive (t3). When this attribute is set, it signals - some archival programs that the file has not been - modified since it was last backed up. If a file is - modified, ZSDOS and ZRDOS turn this attribute off. - CP/M does not fully support this attribute, however. - -OTHER OPTIONS: These options affect only the screen display. - - Q Quiet mode. Console output is suppressed unless there - is an error. All other operations are performed - normally. - - X Screen paging off. With this option, screen paging is - turned off. The screen can still be paused by pressing - any key except ^C. - -ERRORS: Under ZCPR3, errors will cause FA to set the program -error flag and to invoke the error handler. The error flag will -be set to the following values: - 2 invalid directory specification - 4 miscellaneous (conflicting file, no files on disk) - 10 no matching files found (no error handler) - 18 Disk read-only - 19 Invalid option - -For error code 10 (no matching files found), the error flag is -set, but the error handler is not called. - -In addition, under ZCPR 3.3 and above, an invalid directory -specification will abort FA to the error handler, but no message -is printed. - -The following error messages may be seen: - -Conflicting entry, can't set public attribute - If there are files with the same name in other user areas of - the disk, the public attribute cannot be set. - -No files on disk - The disk directory is empty. - -Bad Option: /o - The command line option shown is unknown to FILEATTR. - -Drive R/O - The drive is set to read-only by the operating system and - attributes cannot be changed. - -CP/M version 2.x required - FILEATTR will not run on this system. - -BIOS write error near directory sector n - An error occurred at or near the given directory sector, - which is expressed as a decimal offset from the beginning of - the directory. - -BIOS set track detected - FA aborting - A background program is attempting to modify the current - track setting. The background program must be removeed - before running FA again. - -Not Wheel - Under ZCPR3 the wheel byte must be set before FILEATTR can - be run. - -CONFIGURATION: While no installation is necessary, all options -can be set as defaults, if you prefer, using ZCNFG. The -configuration options are fully explained on the ZCNFG help -screens. - -It is best not to change the name of the configuration file. Its -special name assures that ZCNFG will always find the correct CFG -file, even if the name of FA has been changed or if more than one -version of FA is online. - -HISTORY: - -Version 1.6 -- April 14, 1991 -- Gene Pizzetta - Now displays target DU and directory name in summary. Fixed - bug that caused "GO" to be displayed as program name, if it - was re-invoked with the GO command. - -Version 1.5 -- March 27, 1991 -- Gene Pizzetta - Now calls CP/M version checking routine (it was there, but - it wasn't called). Changed error codes: 10, no matching - files found. "No files on disk" error now gets - miscellaneous error code (4). Error 10 does not invoke - error handler. Not released. - -Version 1.4 -- March 20, 1991 -- Gene Pizzetta, Howard Goldstein - Code to check module data byte (S2) was replaced by Howard - Goldstein's elegant solution which uses a "true" extent - number: ((data_mod * 32) + extent). Entering a ^C no - longer really aborts FILEATTR; instead FA immediately prints - "Wait..." on the screen, turns off paging, turns on quiet - mode, sets the results flag, and finishes what it was doing. - All this is to prevent unexpected results when only some of - a file's directory entries are changed. All errors - including a conflicting file found during a PUBLIC request, - now set the program error flag and invoke the error handler - so an active SUBMIT or ZEX script can be aborted. The error - flag will have the following values: 2, invalid directory; - 10, no files on disk; 18, disk is read-only; 19, invalid - option; 4, all other errors. If no matching files are - found, the program error flag will be set to FFh, but the - error handler will not be invoked. A few other code changes - were made, including a check for CP/M-Plus, under which - FILEATTR will not work. Not released. - -Version 1.3 -- February 22, 1991 -- Gene Pizzetta - Corrected bug that caused faulty operation on large files: - The module data byte (S2) byte was not being checked, so - such files appeared 2 or more times in the directory display - and the public routine was often not finding conflicting - files. Added configuration byte and command line option (X) - for screen paging (paging is suppressed in quiet mode). - Made quiet mode responsive to ZCPR quiet flag and changed Q - command line option to toggle. Usage screen reflects - current effect of X and Q toggles. Attribute configuration - area changed to be compatible with ZCNFG TOGL3 routine. - Actions of D and ND options reversed so they work the same - as the others. Added configuration byte for printing - summary line even in quiet mode, as suggested by Howard - Goldstein. Removed blank lines from screen display, - allowing three more filenames to be shown. Removed tabs - from usage screen so PRINT and PSTR are not needed. - Eliminated leading zero from user number display. Now - prints "file" instead of "files" in summary when only 1 - matching file is found. Ditto for attribute(s) altered. - -Version 1.2 -- November 30, 1988 -- Carson Wilson - Fixed bug of no program name display when FILEATTR's name - was 8 characters long. - -Version 1.1 -- October 30, 1988 -- Carson Wilson - Now wildcards the command forms "FA d: /options" and "FA d: - options." - -Version 1.0 -- September 26, 1988 -- Carson Wilson - If a filespec is given, no leading slash is required before - the options. Link with version 4 libraries. Removed /X - option--ZSDOS 10T always closes the first extent when a file - is written to. Changed summary to read "files matched". - -Version 0.9 -- July 7, 1988 -- Carson Wilson - Increased length of search FCB (AMBFIL) by one byte. Set up - AMBFIL as '?' + 35 binary 0's. ZRDOS and CP/M zero the - drive byte (FCB+0) during search next calls, so reinitialize - it to '?' before rescanning the directory. PROGID now - prints stored name on GO/JUMP. - -Version 0.8 -- June 26, 1988 -- Carson Wilson - Use SYSLIB PRINT for help display. VPRINT does not expand - tabs. Now traps disk track changes at the BIOS level. - Allows '-' as well as 'N' for "negate option." Auto- - wildcards FCB1 for attribute set as well as display. - -Version 0.7 -- May 24, 1988 -- Carson Wilson - Cosmetic changes to help, display. Made public routines - faster by 1/2 directory scan average. Consolidated file - attribute setting/resetting routines for efficiency and - clarity. - -Version 0.6 -- May 14, 1988 -- Carson Wilson - Changed "Publ" to "Publc" and "Priv" to "Privt". Added Q - and X options, made options installable. Added test for bad - ZCPR directory & chain to error handler. - -Version 0.5 -- May 4, 1988 -- Carson Wilson - Fixed bug at CHKRO inherited from MAKE.ASM. Uses Bridger - Mitchell's FRESET to reset disks. Uses ZCPR invocation name - in signon, help, etc. Added F4 attribute. Now includes all - valid ZSDOS attributes. Help now fully "smart" under ZCPR. - Reworked VID3.Z80 and VID4.Z80 from VLIB11 and moved them - into FA.Z80 (see end of file). Put STNDOUT mode ON by - default at beginning of each attribute display sequence for - faster ZCPR displays. - -Version 0.4 -- April 27, 1988 -- Carson Wilson - Tests for matching files at other user areas before setting - the public attribit. - -Version 0.3 -- April 26, 1988 -- Carson Wilson diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FA16A.FOR b/branches/s100/RomDsk/ZSYS_1024KB/FA16A.FOR deleted file mode 100644 index e9ed3d43..00000000 --- a/branches/s100/RomDsk/ZSYS_1024KB/FA16A.FOR +++ /dev/null @@ -1,6 +0,0 @@ -An update and bug-fix of FILEATTR (FA), a ZSDOS utility that -allows rapid setting, resetting, or displaying of file attributes -under ZSDOS, ZRDOS, and CP/M 2.2. Several additional features -are available under ZCPR3, including error flag setting, error -handler invocation, and an enhanced display. Version 1.6A adds -documentation; otherwise, same as 1.6. diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FA16CFG.TXT b/branches/s100/RomDsk/ZSYS_1024KB/FA16CFG.TXT deleted file mode 100644 index 4067b9ba..00000000 --- a/branches/s100/RomDsk/ZSYS_1024KB/FA16CFG.TXT +++ /dev/null @@ -1,39 +0,0 @@ - -Option Q -- If the ZCPR quiet flag is set, FILEATTR will always default to -quiet mode. To make quiet mode the default at all times, even when running -under CP/M, set this configuration option to "Yes". Whatever is selected -here can be toggled with the command line "Q" option. - -Option X -- A "Yes" will cause FILEATTR to page screen output by default. -A "No" will default to continuous scrolling. The chosen default can be -toggled with the command line "X" option. Screen paging is always turned -off in quiet mode. - -Option R -- As distributed, FILEATTR prints nothing to the screen when it -is operating in quiet mode. If this configuration option is "Yes", the -results summary line that gives the number of matching files found and the -number of attributes changed will be printed even in quiet mode. - -Option S -- Enter the number of lines on your video display screen. Under -ZCPR 3.3 and higher, the number of screen lines for paging is obtained from -the environment descriptor. This configuration parameter is used only if -running under CP/M. - - - Attribute Configuration Options - -As distributed, FILEATTR will not change any file attribute unless -explicitly commanded to do so by a command line option. To configure -FILEATTR to turn a file attribute ON or OFF by default, toggle the -appropriate configuration selection. - -For example, to make FILEATTR set all matching files to Public by default, -change the "Public attribute" setting to "Turn On". Then FILEATTR will set -the specified files to Public unless the /NP command line option is given -(which would cause the files to be set to Private). Since there is no -command which tells FILEATTR not to change an attribute, however, the -program will now insist on turning the Public attribute either on (default) -or off (through the /NP option). - -Most users will have neither need nor desire to change the configuration -default as distributed which will "Leave As-Is" all matching files. diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FILEATTR.COM b/branches/s100/RomDsk/ZSYS_1024KB/FILEATTR.COM deleted file mode 100644 index 4527d090..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/FILEATTR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FILEDATE.CFG b/branches/s100/RomDsk/ZSYS_1024KB/FILEDATE.CFG deleted file mode 100644 index da1ca45f..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/FILEDATE.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FILEDATE.COM b/branches/s100/RomDsk/ZSYS_1024KB/FILEDATE.COM deleted file mode 100644 index 11b83616..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/FILEDATE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/FLASH.MAN b/branches/s100/RomDsk/ZSYS_1024KB/FLASH.MAN deleted file mode 100644 index e57de5c2..00000000 --- a/branches/s100/RomDsk/ZSYS_1024KB/FLASH.MAN +++ /dev/null @@ -1,35 +0,0 @@ -NAME - flash - in-situ 29F040 flash ROM programmer for N8VEM, Zeta and N8 computers -SYNOPSIS - flashz - flashn8 -DESCRIPTION - The flashz and flashn8 erase and program the FLASH ROM chip from an - image file. flashz is used for the N8VEM Z80-SBC and Zeta computers. - flashn8 is used with the N8 home computer. Both function the same - except in the way memory is addressed. - - flash expects a 512k file in the same directory containing the image - that will be programmed into the ROM. This file must have the - unimaginative filename of ROM.IMG. The whole process of erasing and - programming the ROM takes less than a minute - far less than the time - taken to upload your new image. - - This program is only suitable for 29F040 512k FLASH ROMs. - - Assemble with TASM using the command - tasm -t80 -g3 flashz.asm flashz.com - tasm -t80 -g3 flashn8.asm flashn8.com - -JUMPERS - The following jumpers must be in place on the boards to allow the - 29F040 to be programmed. - For the N8VEM Z8-SBC MK-II: K1 1-2, K6 2-3, K8 2-3 - For the N8: K3 1-2, K4 2-3, K5 2-3 - For the Zeta, no jumpers need (or can) be set. - -AUTHOR - Written by David Giles so he doesn't have to open the box his Zeta - lives in so often. Reports to N8VEM group or vk5dg@internode.on.net - - diff --git a/branches/s100/RomDsk/ZSYS_1024KB/INITDIR.CFG b/branches/s100/RomDsk/ZSYS_1024KB/INITDIR.CFG deleted file mode 100644 index 96baa986..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/INITDIR.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/INITDIR.COM b/branches/s100/RomDsk/ZSYS_1024KB/INITDIR.COM deleted file mode 100644 index fd46387a..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/INITDIR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/LBREXT.COM b/branches/s100/RomDsk/ZSYS_1024KB/LBREXT.COM deleted file mode 100644 index c0c950e3..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/LBREXT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/LIB.COM b/branches/s100/RomDsk/ZSYS_1024KB/LIB.COM deleted file mode 100644 index 45d7fb21..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/LIB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/LINK.COM b/branches/s100/RomDsk/ZSYS_1024KB/LINK.COM deleted file mode 100644 index e188fb92..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/LINK.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/LOAD.COM b/branches/s100/RomDsk/ZSYS_1024KB/LOAD.COM deleted file mode 100644 index b9601e00..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/LOAD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/MAC.COM b/branches/s100/RomDsk/ZSYS_1024KB/MAC.COM deleted file mode 100644 index f49e835a..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/MAC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/MBASIC.COM b/branches/s100/RomDsk/ZSYS_1024KB/MBASIC.COM deleted file mode 100644 index c9ec3cd3..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/MBASIC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/NULU.COM b/branches/s100/RomDsk/ZSYS_1024KB/NULU.COM deleted file mode 100644 index fc5594b1..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/NULU.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/PIP.COM b/branches/s100/RomDsk/ZSYS_1024KB/PIP.COM deleted file mode 100644 index 4b2ce4b6..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/PIP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/PUTBG.COM b/branches/s100/RomDsk/ZSYS_1024KB/PUTBG.COM deleted file mode 100644 index 970e2d8a..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/PUTBG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/PUTDS.COM b/branches/s100/RomDsk/ZSYS_1024KB/PUTDS.COM deleted file mode 100644 index c0ceba64..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/PUTDS.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/RELOG.COM b/branches/s100/RomDsk/ZSYS_1024KB/RELOG.COM deleted file mode 100644 index 13ffc62e..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/RELOG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/RMAC.COM b/branches/s100/RomDsk/ZSYS_1024KB/RMAC.COM deleted file mode 100644 index 9ab7206b..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/RMAC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/SETTERM.COM b/branches/s100/RomDsk/ZSYS_1024KB/SETTERM.COM deleted file mode 100644 index eca19bf9..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/SETTERM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/SETUPZST.COM b/branches/s100/RomDsk/ZSYS_1024KB/SETUPZST.COM deleted file mode 100644 index 35e4b589..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/SETUPZST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/SID.COM b/branches/s100/RomDsk/ZSYS_1024KB/SID.COM deleted file mode 100644 index 3b073ba5..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/SID.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/STAMPS.DAT b/branches/s100/RomDsk/ZSYS_1024KB/STAMPS.DAT deleted file mode 100644 index 23cd9bd7..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/STAMPS.DAT and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/STAT.COM b/branches/s100/RomDsk/ZSYS_1024KB/STAT.COM deleted file mode 100644 index 1de359f2..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/STAT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/SUBMIT.COM b/branches/s100/RomDsk/ZSYS_1024KB/SUBMIT.COM deleted file mode 100644 index 2e788827..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/SUBMIT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/SUPERSUB.COM b/branches/s100/RomDsk/ZSYS_1024KB/SUPERSUB.COM deleted file mode 100644 index a25d60a6..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/SUPERSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/TD.CFG b/branches/s100/RomDsk/ZSYS_1024KB/TD.CFG deleted file mode 100644 index ab44bab9..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/TD.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/TD.COM b/branches/s100/RomDsk/ZSYS_1024KB/TD.COM deleted file mode 100644 index 552aba67..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/TD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/TERMBASE.DAT b/branches/s100/RomDsk/ZSYS_1024KB/TERMBASE.DAT deleted file mode 100644 index 358d61c0..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/TERMBASE.DAT and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/TESTCLOK.COM b/branches/s100/RomDsk/ZSYS_1024KB/TESTCLOK.COM deleted file mode 100644 index d547e2b8..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/TESTCLOK.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/UNARC.COM b/branches/s100/RomDsk/ZSYS_1024KB/UNARC.COM deleted file mode 100644 index 8cc90746..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/UNARC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/UNCR.COM b/branches/s100/RomDsk/ZSYS_1024KB/UNCR.COM deleted file mode 100644 index 42385ddd..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/UNCR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/UNZIP.COM b/branches/s100/RomDsk/ZSYS_1024KB/UNZIP.COM deleted file mode 100644 index afde7204..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/UNZIP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/XSUB.COM b/branches/s100/RomDsk/ZSYS_1024KB/XSUB.COM deleted file mode 100644 index 15e86abf..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/XSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZAP.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZAP.COM deleted file mode 100644 index 47ffcbb8..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZAP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZCAL.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZCAL.COM deleted file mode 100644 index a5add241..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZCAL.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZCNFG.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZCNFG.COM deleted file mode 100644 index ae423dc5..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZCNFG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZCNFG24.CFG b/branches/s100/RomDsk/ZSYS_1024KB/ZCNFG24.CFG deleted file mode 100644 index 1bfe49bf..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZCNFG24.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZDE.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZDE.COM deleted file mode 100644 index 8814a523..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZDE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZDENST.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZDENST.COM deleted file mode 100644 index 8ccc9767..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZDENST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZPATH.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZPATH.COM deleted file mode 100644 index 5c0aa503..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZPATH.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZSCONFIG.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZSCONFIG.COM deleted file mode 100644 index 2cc26074..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZSCONFIG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZSVSTAMP.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZSVSTAMP.COM deleted file mode 100644 index 026d5d7a..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZSVSTAMP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZSVSTAMP.DOC b/branches/s100/RomDsk/ZSYS_1024KB/ZSVSTAMP.DOC deleted file mode 100644 index 2a8a7c1e..00000000 --- a/branches/s100/RomDsk/ZSYS_1024KB/ZSVSTAMP.DOC +++ /dev/null @@ -1,118 +0,0 @@ - ZSVSTAMP USAGE NOTES - - - -1.0 INTRODUCTION - - ZSVSTAMP is a utility program that saves the create -date/time stamp of a given file in memory. At a later time, -ZSVSTAMP can restore the create stamp to a file. This can be -useful when modifying a file with an editor that actually creates -a new copy of the file rather than modifying it in place. -ZSVSTAMP allows the original creation date of the document to be -retained. - - In order to support all types of date stamping under ZSDOS, -ZSVSTAMP uses the get/set stamp functions of ZSDOS (or ZDDOS) and -thus may only be run under these operating systems. It also -requires ZCPR3 with multiple command line, external FCB and -message buffer. If an attempt is made to run ZSVSTAMP on a -system that does not meet these requirements, the program will -abort with an error message. - - - -2.0 OPERATION - - ZSVSTAMP has two modes of operation -- Manual and Automatic. - - - -2.1 Automatic Mode - - This mode is the most commonly used. It is extremely well -suited for use in alias scripts and can make the whole process of -saving and restoring date stamps virtually transparent to the -user. The syntax is: - - ZSVSTAMP approg [ufn] - -where "approg" is the program, such as an editor, that you wish -to run and "ufn" is an unambiguous file name to be modified by -"approg." When a command of this type is given, ZSVSTAMP saves -"ufn"'s creation date in protected memory. It then causes -"approg" to be run, and when "approg" finishes, ZSVSTAMP is -automatically run again to restore the original create stamp to -"ufn." If "ufn" does not exist, or if the disk does not support -date stamping, ZSVSTAMP displays a warning message and -immediately passes control to "approg" without attempting to save -a stamp. In this situation, ZSVSTAMP is not rerun when "approg" -completes execution. - - Some editors allow a syntax such as - - EDIT oldfile newfile - -When ZSVSTAMP is invoked with more than one parameter following -the application name, no stamps are saved or restored. This -feature can be disabled if desired, (see the section on -customization). - - - -2.2 Manual Mode - - Manual mode can be used to save or restore a file's create -stamp. The syntax is: - - ZSVSTAMP ufn /G or /S - -to Get or Save a file's create stamp, or: - - ZSVSTAMP ufn /P or /R - -to Put or Restore a saved stamp back onto a file. - - - -3.0 CUSTOMIZING ZSVSTAMP - -There are five configuration flags located near the beginning of -the program. Each flag is preceeded by an ASCII string to help -identify its function. These flags may be patched to customize -ZSVSTAMP as desired. - - The first four flags determine whether or not various -warning messages can be displayed when ZSVSTAMP is being run in -Automatic Mode. Setting a flag to 0 disables its associated -message; any other value enables the message. The flags are -labeled "NOSTMP," "NOFILE," "READERR," and "UPDTERR," and they -affect the "Disk has no time/date stamps," "File not found," -"Can't read time/date stamp," and "Can't update time/date stamp" -messages respectively. The program is distributed with all four -messages enabled. Please note that these flags have no effect in -Manual Mode where error messages are always enabled. - - The fifth and final configuration flag is labeled -"REPLALWS." It determines what ZSVSTAMP will do when more than -one parameter follows the application name in an Automatic Mode -command. If the byte following the "REPLALWS" label equals 0, -ZSVSTAMP checks to see if there is more than one parameter -following the application program name. If there is, ZSVSTAMP -simply exits to the application without saving or updating any -stamps. (This is the default setting in the distributed -version.) If the "REPLALWS" flag is non-zero, no such check is -made. - - - -4.0 CONTACTING THE AUTHOR - - Howard Goldstein may be contacted at: - - Newton Centre Z-Node, (Z-Node 3): 617/965-7259 - - Ladera Z-Node, (Z-Node 2): 213/670-9465 - - Home phone, (voice): 203/787-1918 - \ No newline at end of file diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZXD.CFG b/branches/s100/RomDsk/ZSYS_1024KB/ZXD.CFG deleted file mode 100644 index f202ae59..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZXD.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_1024KB/ZXD.COM b/branches/s100/RomDsk/ZSYS_1024KB/ZXD.COM deleted file mode 100644 index 20395673..00000000 Binary files a/branches/s100/RomDsk/ZSYS_1024KB/ZXD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/CLRDIR.COM b/branches/s100/RomDsk/ZSYS_512KB/CLRDIR.COM deleted file mode 100644 index d1f2a7d6..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/CLRDIR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/COPY.CFG b/branches/s100/RomDsk/ZSYS_512KB/COPY.CFG deleted file mode 100644 index 3d5310ac..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/COPY.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/COPY.COM b/branches/s100/RomDsk/ZSYS_512KB/COPY.COM deleted file mode 100644 index 87c0c2fb..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/COPY.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/DDT.COM b/branches/s100/RomDsk/ZSYS_512KB/DDT.COM deleted file mode 100644 index 83f8603f..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/DDT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/DIF.COM b/branches/s100/RomDsk/ZSYS_512KB/DIF.COM deleted file mode 100644 index 87b89d75..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/DIF.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/DSCONFIG.COM b/branches/s100/RomDsk/ZSYS_512KB/DSCONFIG.COM deleted file mode 100644 index b77dd008..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/DSCONFIG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/DUMP.COM b/branches/s100/RomDsk/ZSYS_512KB/DUMP.COM deleted file mode 100644 index 03a77c3c..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/DUMP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ED.COM b/branches/s100/RomDsk/ZSYS_512KB/ED.COM deleted file mode 100644 index a0f0f541..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ED.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/FA16.CFG b/branches/s100/RomDsk/ZSYS_512KB/FA16.CFG deleted file mode 100644 index b7974d36..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/FA16.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/FILEATTR.COM b/branches/s100/RomDsk/ZSYS_512KB/FILEATTR.COM deleted file mode 100644 index 4527d090..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/FILEATTR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/FILEDATE.CFG b/branches/s100/RomDsk/ZSYS_512KB/FILEDATE.CFG deleted file mode 100644 index da1ca45f..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/FILEDATE.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/FILEDATE.COM b/branches/s100/RomDsk/ZSYS_512KB/FILEDATE.COM deleted file mode 100644 index 11b83616..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/FILEDATE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/FLASH.MAN b/branches/s100/RomDsk/ZSYS_512KB/FLASH.MAN deleted file mode 100644 index e57de5c2..00000000 --- a/branches/s100/RomDsk/ZSYS_512KB/FLASH.MAN +++ /dev/null @@ -1,35 +0,0 @@ -NAME - flash - in-situ 29F040 flash ROM programmer for N8VEM, Zeta and N8 computers -SYNOPSIS - flashz - flashn8 -DESCRIPTION - The flashz and flashn8 erase and program the FLASH ROM chip from an - image file. flashz is used for the N8VEM Z80-SBC and Zeta computers. - flashn8 is used with the N8 home computer. Both function the same - except in the way memory is addressed. - - flash expects a 512k file in the same directory containing the image - that will be programmed into the ROM. This file must have the - unimaginative filename of ROM.IMG. The whole process of erasing and - programming the ROM takes less than a minute - far less than the time - taken to upload your new image. - - This program is only suitable for 29F040 512k FLASH ROMs. - - Assemble with TASM using the command - tasm -t80 -g3 flashz.asm flashz.com - tasm -t80 -g3 flashn8.asm flashn8.com - -JUMPERS - The following jumpers must be in place on the boards to allow the - 29F040 to be programmed. - For the N8VEM Z8-SBC MK-II: K1 1-2, K6 2-3, K8 2-3 - For the N8: K3 1-2, K4 2-3, K5 2-3 - For the Zeta, no jumpers need (or can) be set. - -AUTHOR - Written by David Giles so he doesn't have to open the box his Zeta - lives in so often. Reports to N8VEM group or vk5dg@internode.on.net - - diff --git a/branches/s100/RomDsk/ZSYS_512KB/INITDIR.CFG b/branches/s100/RomDsk/ZSYS_512KB/INITDIR.CFG deleted file mode 100644 index 96baa986..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/INITDIR.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/INITDIR.COM b/branches/s100/RomDsk/ZSYS_512KB/INITDIR.COM deleted file mode 100644 index fd46387a..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/INITDIR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/LBREXT.COM b/branches/s100/RomDsk/ZSYS_512KB/LBREXT.COM deleted file mode 100644 index c0c950e3..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/LBREXT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/LOAD.COM b/branches/s100/RomDsk/ZSYS_512KB/LOAD.COM deleted file mode 100644 index b9601e00..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/LOAD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/NULU.COM b/branches/s100/RomDsk/ZSYS_512KB/NULU.COM deleted file mode 100644 index fc5594b1..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/NULU.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/PIP.COM b/branches/s100/RomDsk/ZSYS_512KB/PIP.COM deleted file mode 100644 index 4b2ce4b6..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/PIP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/PUTDS.COM b/branches/s100/RomDsk/ZSYS_512KB/PUTDS.COM deleted file mode 100644 index c0ceba64..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/PUTDS.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/RELOG.COM b/branches/s100/RomDsk/ZSYS_512KB/RELOG.COM deleted file mode 100644 index 13ffc62e..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/RELOG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/SETTERM.COM b/branches/s100/RomDsk/ZSYS_512KB/SETTERM.COM deleted file mode 100644 index eca19bf9..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/SETTERM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/SETUPZST.COM b/branches/s100/RomDsk/ZSYS_512KB/SETUPZST.COM deleted file mode 100644 index 35e4b589..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/SETUPZST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/STAT.COM b/branches/s100/RomDsk/ZSYS_512KB/STAT.COM deleted file mode 100644 index 1de359f2..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/STAT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/SUBMIT.COM b/branches/s100/RomDsk/ZSYS_512KB/SUBMIT.COM deleted file mode 100644 index 2e788827..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/SUBMIT.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/SUPERSUB.COM b/branches/s100/RomDsk/ZSYS_512KB/SUPERSUB.COM deleted file mode 100644 index a25d60a6..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/SUPERSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/TD.CFG b/branches/s100/RomDsk/ZSYS_512KB/TD.CFG deleted file mode 100644 index ab44bab9..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/TD.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/TD.COM b/branches/s100/RomDsk/ZSYS_512KB/TD.COM deleted file mode 100644 index 552aba67..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/TD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/TERMBASE.DAT b/branches/s100/RomDsk/ZSYS_512KB/TERMBASE.DAT deleted file mode 100644 index 358d61c0..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/TERMBASE.DAT and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/TESTCLOK.COM b/branches/s100/RomDsk/ZSYS_512KB/TESTCLOK.COM deleted file mode 100644 index d547e2b8..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/TESTCLOK.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/UNARC.COM b/branches/s100/RomDsk/ZSYS_512KB/UNARC.COM deleted file mode 100644 index 8cc90746..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/UNARC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/UNCR.COM b/branches/s100/RomDsk/ZSYS_512KB/UNCR.COM deleted file mode 100644 index 42385ddd..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/UNCR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/XSUB.COM b/branches/s100/RomDsk/ZSYS_512KB/XSUB.COM deleted file mode 100644 index 15e86abf..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/XSUB.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZAP.COM b/branches/s100/RomDsk/ZSYS_512KB/ZAP.COM deleted file mode 100644 index 47ffcbb8..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZAP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZCAL.COM b/branches/s100/RomDsk/ZSYS_512KB/ZCAL.COM deleted file mode 100644 index a5add241..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZCAL.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZCNFG.COM b/branches/s100/RomDsk/ZSYS_512KB/ZCNFG.COM deleted file mode 100644 index ae423dc5..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZCNFG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZCNFG24.CFG b/branches/s100/RomDsk/ZSYS_512KB/ZCNFG24.CFG deleted file mode 100644 index 1bfe49bf..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZCNFG24.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZDE.COM b/branches/s100/RomDsk/ZSYS_512KB/ZDE.COM deleted file mode 100644 index 8814a523..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZDE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZPATH.COM b/branches/s100/RomDsk/ZSYS_512KB/ZPATH.COM deleted file mode 100644 index 5c0aa503..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZPATH.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZSCONFIG.COM b/branches/s100/RomDsk/ZSYS_512KB/ZSCONFIG.COM deleted file mode 100644 index 2cc26074..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZSCONFIG.COM and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZXD.CFG b/branches/s100/RomDsk/ZSYS_512KB/ZXD.CFG deleted file mode 100644 index f202ae59..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZXD.CFG and /dev/null differ diff --git a/branches/s100/RomDsk/ZSYS_512KB/ZXD.COM b/branches/s100/RomDsk/ZSYS_512KB/ZXD.COM deleted file mode 100644 index 20395673..00000000 Binary files a/branches/s100/RomDsk/ZSYS_512KB/ZXD.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/FDTST.COM b/branches/s100/RomDsk/cfg_n8_2312/FDTST.COM deleted file mode 100644 index 5cd9f77c..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/FDTST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/FLASHN8.COM b/branches/s100/RomDsk/cfg_n8_2312/FLASHN8.COM deleted file mode 100644 index 61c5789d..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/FLASHN8.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/LDTIM.COM b/branches/s100/RomDsk/cfg_n8_2312/LDTIM.COM deleted file mode 100644 index 1ce1dfc7..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/RTC.COM b/branches/s100/RomDsk/cfg_n8_2312/RTC.COM deleted file mode 100644 index 0ac25a6a..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/SURVEY.COM b/branches/s100/RomDsk/cfg_n8_2312/SURVEY.COM deleted file mode 100644 index 2b0bf4e4..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/SURVEY.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/XM-A0.COM b/branches/s100/RomDsk/cfg_n8_2312/XM-A0.COM deleted file mode 100644 index 6afb31f3..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/XM-A0.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/XM-A1.COM b/branches/s100/RomDsk/cfg_n8_2312/XM-A1.COM deleted file mode 100644 index 42a67c31..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/XM-A1.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/XM5-A0.COM b/branches/s100/RomDsk/cfg_n8_2312/XM5-A0.COM deleted file mode 100644 index e233bee9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/XM5-A0.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2312/XM5-A1.COM b/branches/s100/RomDsk/cfg_n8_2312/XM5-A1.COM deleted file mode 100644 index 625e06ac..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2312/XM5-A1.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/FDTST.COM b/branches/s100/RomDsk/cfg_n8_2511/FDTST.COM deleted file mode 100644 index 5cd9f77c..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/FDTST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/FLASHN8.COM b/branches/s100/RomDsk/cfg_n8_2511/FLASHN8.COM deleted file mode 100644 index 61c5789d..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/FLASHN8.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/LDTIM.COM b/branches/s100/RomDsk/cfg_n8_2511/LDTIM.COM deleted file mode 100644 index 1ce1dfc7..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/RTC.COM b/branches/s100/RomDsk/cfg_n8_2511/RTC.COM deleted file mode 100644 index 0ac25a6a..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/SURVEY.COM b/branches/s100/RomDsk/cfg_n8_2511/SURVEY.COM deleted file mode 100644 index 2b0bf4e4..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/SURVEY.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/XM-A0.COM b/branches/s100/RomDsk/cfg_n8_2511/XM-A0.COM deleted file mode 100644 index 6afb31f3..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/XM-A0.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/XM-A1.COM b/branches/s100/RomDsk/cfg_n8_2511/XM-A1.COM deleted file mode 100644 index 42a67c31..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/XM-A1.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/XM5-A0.COM b/branches/s100/RomDsk/cfg_n8_2511/XM5-A0.COM deleted file mode 100644 index e233bee9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/XM5-A0.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8_2511/XM5-A1.COM b/branches/s100/RomDsk/cfg_n8_2511/XM5-A1.COM deleted file mode 100644 index 625e06ac..00000000 Binary files a/branches/s100/RomDsk/cfg_n8_2511/XM5-A1.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/1200.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/38400.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/9600.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/T5.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/XM.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_cvdu/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_cvdu/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_cvdu/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/1200.COM b/branches/s100/RomDsk/cfg_n8vem_dide/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/38400.COM b/branches/s100/RomDsk/cfg_n8vem_dide/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/9600.COM b/branches/s100/RomDsk/cfg_n8vem_dide/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/FDTST.COM b/branches/s100/RomDsk/cfg_n8vem_dide/FDTST.COM deleted file mode 100644 index cf9544eb..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/FDTST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_dide/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_dide/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_dide/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/T5.COM b/branches/s100/RomDsk/cfg_n8vem_dide/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/XM.COM b/branches/s100/RomDsk/cfg_n8vem_dide/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_dide/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_dide/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_dide/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/1200.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/38400.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/9600.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/ECIDETST.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/ECIDETST.COM deleted file mode 100644 index f0140c58..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/ECIDETST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/FDCMON.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/FDCMON.COM deleted file mode 100644 index 197af733..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/FDCMON.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/FDTST.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/FDTST.COM deleted file mode 100644 index ebea0d52..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/FDTST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/T5.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/TP-IDE.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/TP-IDE.COM deleted file mode 100644 index 726efd5b..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/TP-IDE.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/XM.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_diskio/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/1200.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/38400.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/9600.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/FDTST.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/FDTST.COM deleted file mode 100644 index 6e85b8f8..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/FDTST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/T5.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/XM.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_diskio3/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_diskio3/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_diskio3/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/1200.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/38400.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/9600.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/PPIDETST.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/PPIDETST.COM deleted file mode 100644 index 1cfc72b7..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/PPIDETST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/T5.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/VT3.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/VT3.COM deleted file mode 100644 index 6290a6d3..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/VT3.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/XM.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppide/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_ppide/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppide/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/1200.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/38400.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/9600.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/T5.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/VT3.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/VT3.COM deleted file mode 100644 index 6290a6d3..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/VT3.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/XM.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_ppisd/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_ppisd/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_ppisd/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/1200.COM b/branches/s100/RomDsk/cfg_n8vem_propio/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/38400.COM b/branches/s100/RomDsk/cfg_n8vem_propio/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/9600.COM b/branches/s100/RomDsk/cfg_n8vem_propio/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_propio/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_propio/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_propio/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/T5.COM b/branches/s100/RomDsk/cfg_n8vem_propio/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/XM.COM b/branches/s100/RomDsk/cfg_n8vem_propio/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_propio/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_propio/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_propio/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_simh/HDIR.COM b/branches/s100/RomDsk/cfg_n8vem_simh/HDIR.COM deleted file mode 100644 index 8901335c..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_simh/HDIR.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_simh/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_simh/LDTIM.COM deleted file mode 100644 index d2959fae..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_simh/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_simh/R.COM b/branches/s100/RomDsk/cfg_n8vem_simh/R.COM deleted file mode 100644 index 2e4b504f..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_simh/R.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_simh/RSETSIMH.COM b/branches/s100/RomDsk/cfg_n8vem_simh/RSETSIMH.COM deleted file mode 100644 index e055f07a..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_simh/RSETSIMH.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_simh/TIMER.COM b/branches/s100/RomDsk/cfg_n8vem_simh/TIMER.COM deleted file mode 100644 index 83e6e688..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_simh/TIMER.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_simh/URL.COM b/branches/s100/RomDsk/cfg_n8vem_simh/URL.COM deleted file mode 100644 index 45446079..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_simh/URL.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_simh/W.COM b/branches/s100/RomDsk/cfg_n8vem_simh/W.COM deleted file mode 100644 index 342f07ad..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_simh/W.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/1200.COM b/branches/s100/RomDsk/cfg_n8vem_std/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/38400.COM b/branches/s100/RomDsk/cfg_n8vem_std/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/9600.COM b/branches/s100/RomDsk/cfg_n8vem_std/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_std/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_std/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_std/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/T5.COM b/branches/s100/RomDsk/cfg_n8vem_std/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/VT3.COM b/branches/s100/RomDsk/cfg_n8vem_std/VT3.COM deleted file mode 100644 index 6290a6d3..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/VT3.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/XM.COM b/branches/s100/RomDsk/cfg_n8vem_std/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_std/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_std/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_std/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/1200.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/38400.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/9600.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/FLASHZ.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/LDTIM.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/RTC.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/T5.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/XM.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_n8vem_vdu/XM5.COM b/branches/s100/RomDsk/cfg_n8vem_vdu/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_n8vem_vdu/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/1200.COM b/branches/s100/RomDsk/cfg_s100_std/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/38400.COM b/branches/s100/RomDsk/cfg_s100_std/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/9600.COM b/branches/s100/RomDsk/cfg_s100_std/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/FLASHZ.COM b/branches/s100/RomDsk/cfg_s100_std/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/LDTIM.COM b/branches/s100/RomDsk/cfg_s100_std/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/RTC.COM b/branches/s100/RomDsk/cfg_s100_std/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/T5.COM b/branches/s100/RomDsk/cfg_s100_std/T5.COM deleted file mode 100644 index ab55d759..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/T5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/VT3.COM b/branches/s100/RomDsk/cfg_s100_std/VT3.COM deleted file mode 100644 index 6290a6d3..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/VT3.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/XM.COM b/branches/s100/RomDsk/cfg_s100_std/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_s100_std/XM5.COM b/branches/s100/RomDsk/cfg_s100_std/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_s100_std/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/1200.COM b/branches/s100/RomDsk/cfg_zeta_ppp/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/38400.COM b/branches/s100/RomDsk/cfg_zeta_ppp/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/9600.COM b/branches/s100/RomDsk/cfg_zeta_ppp/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/FDTST.COM b/branches/s100/RomDsk/cfg_zeta_ppp/FDTST.COM deleted file mode 100644 index 30e36f60..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/FDTST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/FLASHZ.COM b/branches/s100/RomDsk/cfg_zeta_ppp/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/LDTIM.COM b/branches/s100/RomDsk/cfg_zeta_ppp/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/RTC.COM b/branches/s100/RomDsk/cfg_zeta_ppp/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/SURVEY.COM b/branches/s100/RomDsk/cfg_zeta_ppp/SURVEY.COM deleted file mode 100644 index 2b0bf4e4..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/SURVEY.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/TSTPPP.COM b/branches/s100/RomDsk/cfg_zeta_ppp/TSTPPP.COM deleted file mode 100644 index 761e43e1..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/TSTPPP.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/XM.COM b/branches/s100/RomDsk/cfg_zeta_ppp/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_ppp/XM5.COM b/branches/s100/RomDsk/cfg_zeta_ppp/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_ppp/XM5.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/1200.COM b/branches/s100/RomDsk/cfg_zeta_std/1200.COM deleted file mode 100644 index d00960b0..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/1200.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/38400.COM b/branches/s100/RomDsk/cfg_zeta_std/38400.COM deleted file mode 100644 index 6d81bc17..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/38400.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/9600.COM b/branches/s100/RomDsk/cfg_zeta_std/9600.COM deleted file mode 100644 index 4727badf..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/9600.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/FDTST.COM b/branches/s100/RomDsk/cfg_zeta_std/FDTST.COM deleted file mode 100644 index 30e36f60..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/FDTST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/FLASHZ.COM b/branches/s100/RomDsk/cfg_zeta_std/FLASHZ.COM deleted file mode 100644 index 853ae7d9..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/FLASHZ.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/LDTIM.COM b/branches/s100/RomDsk/cfg_zeta_std/LDTIM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/LDTIM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/PPIDETST.COM b/branches/s100/RomDsk/cfg_zeta_std/PPIDETST.COM deleted file mode 100644 index 1cfc72b7..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/PPIDETST.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/RTC.COM b/branches/s100/RomDsk/cfg_zeta_std/RTC.COM deleted file mode 100644 index da0aebc1..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/RTC.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/SURVEY.COM b/branches/s100/RomDsk/cfg_zeta_std/SURVEY.COM deleted file mode 100644 index 2b0bf4e4..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/SURVEY.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/XM.COM b/branches/s100/RomDsk/cfg_zeta_std/XM.COM deleted file mode 100644 index abcc6828..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/XM.COM and /dev/null differ diff --git a/branches/s100/RomDsk/cfg_zeta_std/XM5.COM b/branches/s100/RomDsk/cfg_zeta_std/XM5.COM deleted file mode 100644 index 8ea2b661..00000000 Binary files a/branches/s100/RomDsk/cfg_zeta_std/XM5.COM and /dev/null differ diff --git a/branches/s100/RomList.txt b/branches/s100/RomList.txt deleted file mode 100644 index c8aac1e5..00000000 --- a/branches/s100/RomList.txt +++ /dev/null @@ -1,252 +0,0 @@ -You should find the following ROM -images in the Output driectory. -Refer to the descriptions below to select -one that matches your hardware -configuration, burn it, and use it. - -Note there are two set of rom builds -below, one for generic DRI CP/M (BDOS & CCP) -and one for ZSystem (ZSDOS & ZCPR) - -Note that all builds are now set for 512KB ROMs. -The builds will work fine in 1MB ROMs. If you -want to use the full 1MB ROM address space, just -do a cutom build. - -Note that all builds are now set for 38.4Kbsp -baud rate on the console with 8 data bits, no -parity, and 1 stop bit. The baud rate can be -changed in the config file if you want to do a -custom build. - -DRI CP/M (BDOS & CCP) ---------------------- - - N8VEM_std.rom for N8VEM Z80 SBC V1/V2: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk (no floppy/IDE) - - Drives A:=ROM, B:=RAM - - N8VEM_diskio.rom for N8VEM Z80 SBC V1/V2 + DISKIO: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via DISKIO - - IDE support via DISKIO - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=IDE0-00, F:=IDE0-01, G:=IDE0-02, H:=IDE0-03 - - N8VEM_dide.rom for N8VEM Z80 SBC V1/V2 + DUAL IDE: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via DISKIO - - IDE support via DISKIO - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=IDE0-00, F:=IDE0-01, G:=IDE0-02, H:=IDE0-03 - - N8VEM_diskio3.rom for N8VEM Z80 SBC V1/V2 + DISKIO3: - - EXPERIMENTAL! - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via DISKIO3 - - IDE support via DISKIO3 - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=IDE0-00, F:=IDE0-01, G:=IDE0-02, H:=IDE0-03 - - N8VEM_ppide.rom for N8VEM Z80 SBC V1/V2 + PPIDE: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - IDE support via DISKIO - - Drives A:=ROM, B:=RAM, C:=PPIDE0-00, D:=PPIDE0-01, E:=PPIDE0-02, F:=PPIDE0-03 - - N8VEM_ppisd.rom for N8VEM Z80 SBC V1/V2 + PPISD: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - PPISD support - - Drives A:=ROM, B:=RAM, C:=SD0-00, D:=SD0-01, E:=SD0-02, F:=SD0-03 - - N8VEM_propio.rom for N8VEM Z80 SBC V1/V2 + PROPIO: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - SD Card support via PropIO - - VGA console support via PropIO - - PS/2 Keyboard support via PropIO - - Drives A:=ROM, B:=RAM, C:=PRPSD0-00, D:=PRPSD0-01, E:=PRPSD0-02, F:=PRPSD0-03 - - WARNING: You must use the RomWBW specific firmware - for the Propeller found in the Support directory! - - NOTE: Console defaults to VGA & PS/2 Keyboard. Short JP2 - (one bit input port) to use the serial port as the console. - - N8VEM_simh.rom for N8VEM SIMH Simulator: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk (no floppy/IDE) - - Drives A:=ROM, B:=RAM, C:=HDSK0-00, D:=HDSK0-01, E:=HDSK0-02, F:=HDSK0-03 - - N8VEM_vdu.rom for N8VEM Z80 SBC V1/V2: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - VDU board support - - Drives A:=ROM, B:=RAM - - ZETA_std.rom for Zeta Z80 SBC: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - PPIDE support via built-in PPI - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=PPIDE00-0, F:=PPIDE0-01, G:=PPIDE0-02, H:=PPIDE0-03 - - ZETA_ppp.rom for Zeta Z80 SBC w/ ParPortProp: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - SD Card support via ParPortProp - - VGA console support via ParPortProp - - PS/2 Keyboard support via ParPortProp - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=PPPSD0-00, F:=PPPSD0-01, F:=PPPSD0-02, G:=PPPSD0-03 - - WARNING: You must use the RomWBW specific firmware - for the Propeller found in the Support directory! - - NOTE: Console defaults to VGA & PS/2 Keyboard. Short JP1 (CONFIG) - to use the serial port as the console. - - N8_2511.rom for N8 2511 Z180: - - Assumes oscillator frequency of 18.432MHz - - CPU clock at X1 (18.432MHz) - - 512KB ROM, 1MB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - SD card support via built-in SD card slot - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=SD0-00, F:=SD0-01, G:=SD0-02, H:=SD0-03 - - N8_2312.rom for N8 2312 Z180: - - Assumes oscillator frequency of 18.432MHz - - CPU clock at X1 (18.432MHz) - - 512KB ROM, 1MB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - SD card support via built-in SD card slot - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=SD0-00, F:=SD0-01, G:=SD0-02, H:=SD0-03 - -ZSYSTEM (ZSDOS & ZCPR) ----------------------- - - N8VEM_std_z.rom for N8VEM Z80 SBC V1/V2: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk (no floppy/IDE) - - Drives A:=RAM, B:=ROM - - N8VEM_diskio_z.rom for N8VEM Z80 SBC V1/V2 + DISKIO: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via DISKIO - - IDE support via DISKIO - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=IDE0-00, F:=IDE0-01, G:=IDE0-02, H:=IDE0-03 - - N8VEM_dide_z.rom for N8VEM Z80 SBC V1/V2 + DUAL IDE: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via DISKIO - - IDE support via DISKIO - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=IDE0-00, F:=IDE0-01, G:=IDE0-02, H:=IDE0-03 - - N8VEM_diskio3_z.rom for N8VEM Z80 SBC V1/V2 + DISKIO3: - - EXPERIMENTAL! - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via DISKIO3 - - IDE support via DISKIO3 - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=IDE0-00, F:=IDE0-01, G:=IDE0-02, H:=IDE0-03 - - N8VEM_ppide_z.rom for N8VEM Z80 SBC V1/V2 + PPIDE: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - IDE support via DISKIO - - Drives A:=ROM, B:=RAM, C:=PPIDE0-00, D:=PPIDE0-01, E:=PPIDE0-02, F:=PPIDE0-03 - - N8VEM_ppisd_z.rom for N8VEM Z80 SBC V1/V2 + PPISD: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - PPISD support - - Drives A:=ROM, B:=RAM, C:=SD0-00, D:=SD0-01, E:=SD0-02, F:=SD0-03 - - N8VEM_propio_z.rom for N8VEM Z80 SBC V1/V2 + PROPIO: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - SD Card support via PropIO - - VGA console support via PropIO - - PS/2 Keyboard support via PropIO - - Drives A:=ROM, B:=RAM, C:=PRPSD0-00, D:=PRPSD0-01, E:=PRPSD0-02, F:=PRPSD0-03 - - WARNING: You must use the RomWBW specific firmware - for the Propeller found in the Support directory! - - NOTE: Console defaults to VGA & PS/2 Keyboard. Short JP2 - (one bit input port) to use the serial port as the console. - - N8VEM_vdu_z.rom for N8VEM Z80 SBC V1/V2: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - VDU board support - - Drives A:=ROM, B:=RAM - - N8VEM_simh_Z.rom for N8VEM SIMH Simulator: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk (no floppy/IDE) - - Drives A:=ROM, B:=RAM, C:=HDSK0-00, D:=HDSK0-01, E:=HDSK0-02, F:=HDSK0-03 - - ZETA_std_z.rom for Zeta Z80 SBC: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - PPIDE support via built-in PPI - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=PPIDE0-00, F:=PPIDE0-01, G:=PPIDE0-02, H:=PPIDE0-03 - - ZETA_ppp_z.rom for Zeta Z80 SBC w/ ParPortProp: - - 512KB ROM, 512KB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - SD Card support via ParPortProp - - VGA console support via ParPortProp - - PS/2 Keyboard support via ParPortProp - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=PPPSD0-00, F:=PPPSD0-01, F:=PPPSD0-02, G:=PPPSD0-03 - - WARNING: You must use the RomWBW specific firmware - for the Propeller found in the Support directory! - - NOTE: Console defaults to VGA & PS/2 Keyboard. Short JP1 (CONFIG) - to use the serial port as the console. - - N8_2511_z.rom for N8 2511 Z180: - - Assumes oscillator frequency of 18.432MHz - - CPU clock at X1 (18.432MHz) - - 512KB ROM, 1MB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - SD card support via built-in SD card slot - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=SD0-00, F:=SD0-01, G:=SD0-02, H:=SD0-03 - - N8_2312_z.rom for N8 2312 Z180: - - Assumes oscillator frequency of 18.432MHz - - CPU clock at X1 (18.432MHz) - - 512KB ROM, 1MB RAM - - 38.4KB serial console baud rate - - Basic ROM/RAM disk - - Floppy support via built-in FDC - - SD card support via built-in SD card slot - - Drives A:=ROM, B:=RAM, C:=FD0, D:=FD1, E:=SD0-00, F:=SD0-01, G:=SD0-02, H:=SD0-03 diff --git a/branches/s100/Source/Build.ps1 b/branches/s100/Source/Build.ps1 deleted file mode 100644 index ccfd7a7d..00000000 --- a/branches/s100/Source/Build.ps1 +++ /dev/null @@ -1,155 +0,0 @@ -param([string]$Platform = "", [string]$Config = "", [string]$RomSize = "", [string]$SYS = "", [string]$RomName = "") - -$Platform = $Platform.ToUpper() -while ($true) -{ - if (($Platform -eq "N8VEM") -or ($Platform -eq "ZETA") -or ($Platform -eq "N8") -or ($Platform -eq "S2I") -or ($Platform -eq "S100")) {break} - $Platform = (Read-Host -prompt "Platform [N8VEM|ZETA|N8|S2I|S100]").Trim().ToUpper() -} - -while ($true) -{ - $ConfigFile = "config_${Platform}_${Config}.asm" - if (Test-Path $ConfigFile) {break} - if ($Config -ne "") {Write-Host "${ConfigFile} does not exist!"} - - "Configurations available:" - Get-Item "config_${Platform}_*.asm" | foreach {Write-Host " >", $_.Name.Substring(8 + $Platform.Length, $_.Name.Length - 12 - $Platform.Length)} - $Config = (Read-Host -prompt "Configuration").Trim() -} - -while ($true) -{ - if (($RomSize -eq "512") -or ($RomSize -eq "1024")) {break} - $RomSize = (Read-Host -prompt "ROM Size [512|1024]").Trim() -} - -if ($Platform -eq "N8") {$CPUType = "180"} else {$CPUType = "80"} - -$SYS = $SYS.ToUpper() -while ($true) -{ - if (($SYS -eq "CPM") -or ($SYS -eq "ZSYS")) {break} - $SYS = (Read-Host -prompt "System [CPM|ZSYS]").Trim().ToUpper() -} - -if ($RomName -eq "") {$RomName = "${Platform}_${Config}"} -while ($RomName -eq "") -{ - $CP = (Read-Host -prompt "ROM Name [${Config}]").Trim() - if ($RomName -eq "") {$RomName = $Config} -} - -$ErrorAction = 'Stop' - -$TasmPath = '..\tools\tasm32' -$CpmToolsPath = '..\tools\cpmtools' - -$env:TASMTABS = $TasmPath -$env:PATH = $TasmPath + ';' + $CpmToolsPath + ';' + $env:PATH - -$OutDir = "../Output" -$RomFmt = "rom${RomSize}KB" -$BlankFile = "blank${RomSize}KB.dat" -#$ConfigFile = "Config_${Config}.asm" -$RomDiskFile = "RomDisk.tmp" -$RomFile = "${OutDir}/${RomName}.rom" -$SysImgFile = "${OutDir}/${RomName}.sys" -$LoaderFile = "${OutDir}/${RomName}.com" - -"" -"Building ${RomName}: ${ROMSize}KB ROM configuration ${Config} for Z${CPUType}..." -"" - -$TimeStamp = '"' + (Get-Date -Format 'yyMMddThhmm') + '"' -$Variant = '"RomWBW-' + $Env:UserName + '"' - -Function Asm($Component, $Opt, $Architecture=$CPUType, $Output="${Component}.bin") -{ - $Cmd = "tasm -t${Architecture} -g3 ${Opt} ${Component}.asm ${Output}" - $Cmd | write-host - Invoke-Expression $Cmd | write-host - if ($LASTEXITCODE -gt 0) {throw "TASM returned exit code $LASTEXITCODE"} -} - -Function Concat($InputFileList, $OutputFile) -{ - Set-Content $OutputFile -Value $null - foreach ($InputFile in $InputFileList) - { - Add-Content $OutputFile -Value ([System.IO.File]::ReadAllBytes($InputFile)) -Encoding byte - } -} - -# Generate the build settings include file - -@" -; RomWBW Configured for ${Platform} ${Config}, $(Get-Date) -; -#DEFINE TIMESTAMP ${TimeStamp} -#DEFINE VARIANT ${Variant} -; -ROMSIZE .EQU ${ROMSize} ; SIZE OF ROM IN KB -PLATFORM .EQU PLT_${Platform} ; HARDWARE PLATFORM -; -; INCLUDE PLATFORM SPECIFIC DEVICE DEFINITIONS -; -#IF (PLATFORM == PLT_S100) - #INCLUDE "std-s100.inc" -#ELSE - #INCLUDE "std-n8vem.inc" -#ENDIF -; -#INCLUDE "${ConfigFile}" -; -"@ | Out-File "build.inc" -Encoding ASCII - -# Build components - -if ($SYS -eq "CPM") -{ - Asm 'ccpb03' -Output 'cp.bin' - Asm 'bdosb01' -Output 'dos.bin' -} -if ($SYS -eq "ZSYS") -{ - Asm 'zcprw' -Architecture '85' -Output 'cp.bin' - Asm 'zsdos' -Output 'dos.bin' -} - -Asm 'syscfg' -Asm 'cbios' "-dBLD_SYS=SYS_${SYS}" -Asm 'dbgmon' -Asm 'prefix' -Asm 'bootrom' -Asm 'bootapp' -Asm 'loader' -Asm 'pgzero' -Asm 'hbios' -Asm 'hbfill' -Asm 'romfill' - -# Generate result files using components above - -"Building ${RomName} output files..." - -Concat 'cp.bin','dos.bin','cbios.bin' 'os.bin' -Concat 'prefix.bin','os.bin' $SysImgFile -Concat 'pgzero.bin','bootrom.bin','syscfg.bin','loader.bin','romfill.bin','dbgmon.bin','os.bin','hbfill.bin' 'rom0.bin' -Concat 'pgzero.bin','bootrom.bin','syscfg.bin','loader.bin','hbios.bin' 'rom1.bin' -Concat 'bootapp.bin','syscfg.bin','loader.bin','hbios.bin','dbgmon.bin','os.bin' $LoaderFile - -# Create the RomDisk image - -"Building ${RomSize}KB ${RomName} ROM disk data file..." - -Copy-Item $BlankFile $RomDiskFile -cpmcp -f $RomFmt $RomDiskFile ../RomDsk/${SYS}_${RomSize}KB/*.* 0: -cpmcp -f $RomFmt $RomDiskFile ../RomDsk/cfg_${Platform}_${Config}/*.* 0: -cpmcp -f $RomFmt $RomDiskFile ../Apps/core/*.* 0: -cpmcp -f $RomFmt $RomDiskFile ../Output/${RomName}.sys 0:${SYS}.sys - -Concat 'rom0.bin','rom1.bin',$RomDiskFile $RomFile - -# Cleanup -Remove-Item $RomDiskFile \ No newline at end of file diff --git a/branches/s100/Source/Clean.cmd b/branches/s100/Source/Clean.cmd deleted file mode 100644 index c354d414..00000000 --- a/branches/s100/Source/Clean.cmd +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -if exist *.bin del *.bin -if exist *.com del *.com -if exist *.img del *.img -if exist *.rom del *.rom -if exist *.lst del *.lst -if exist *.exp del *.exp -if exist *.tmp del *.tmp -if exist *.mrk del *.mrk -if exist build.inc del build.inc \ No newline at end of file diff --git a/branches/s100/Source/Make.cmd b/branches/s100/Source/Make.cmd deleted file mode 100644 index c161db34..00000000 --- a/branches/s100/Source/Make.cmd +++ /dev/null @@ -1 +0,0 @@ -@..\tools\gcc\mingw32-make %* \ No newline at end of file diff --git a/branches/s100/Source/MakeBlankROM.ps1 b/branches/s100/Source/MakeBlankROM.ps1 deleted file mode 100644 index 1bf64ea9..00000000 --- a/branches/s100/Source/MakeBlankROM.ps1 +++ /dev/null @@ -1,4 +0,0 @@ -# Create a "dummy" rom image, filled with hex E5 -# -Set-Content -Value ([byte[]](0xE5) * (512KB - 64KB)) -Encoding byte -Path 'blank512KB.dat' -Set-Content -Value ([byte[]](0xE5) * (1MB - 64KB)) -Encoding byte -Path 'blank1024KB.dat' \ No newline at end of file diff --git a/branches/s100/Source/ansi.asm b/branches/s100/Source/ansi.asm deleted file mode 100644 index 5a5671e6..00000000 --- a/branches/s100/Source/ansi.asm +++ /dev/null @@ -1,1337 +0,0 @@ -; -;================================================================================================== -; ANSI EMULATION MODULE -;================================================================================================== -; -; TODO: -; 1) INSERT/DELETE CHARACTERS CTL SEQUENCES -; 2) OTHER CTL SEQUENCES? -; -;================================================================================================== -; ANSI EMULATION MODULE CONSTANTS -;================================================================================================== -; -ANSI_DEFATTR .EQU 0 ; ALL ATTRIBUTES OFF -ANSI_DEFCOLOR .EQU 7 ; WHITE ON BLACK -; -;================================================================================================== -; ANSI EMULATION MODULE -;================================================================================================== -; -ANSI_INIT: - PRTS("ANSI: RESET$") -; - JP ANSI_INI ; REUSE THE INI FUNCTION BELOW -; -; -; -ANSI_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,ANSI_IN ; $30 - DEC A - JR Z,ANSI_OUT ; $31 - DEC A - JR Z,ANSI_IST ; $32 - DEC A - JR Z,ANSI_OST ; $33 - DEC A - JR Z,ANSI_CFG ; $34 - CP 8 - JP Z,ANSI_INI ; $38 - CP 9 - JP Z,ANSI_QRY ; $39 - CALL PANIC -; -;================================================================================================== -; ANSI EMULATION MODULE BIOS FUNCTION ENTRY POINTS -;================================================================================================== -; -; READ A CHARACTER -; -ANSI_IN: ; HANDLE INPUT REQUEST -; - ; RETURN QUEUED DATA IF WE HAVE ANY - LD A,(ANSI_QLEN) ; GET THE CURRENT QUEUE LENGTH - OR A ; SET FLAGS - JR Z,ANSI_IN1 ; NOTHING THERE, GO TO KEYBOARD READ - DEC A ; DECREMENT THE QUEUE LENGTH - LD (ANSI_QLEN),A ; AND SAVE IT - LD HL,(ANSI_QPTR) ; GET THE QUEUE POINTER - LD A,(HL) ; GET THE NEXT QUEUE BYTE - INC HL ; INCREMENT THE POINTER - LD (ANSI_QPTR),HL ; AND SAVE IT - LD E,A ; RETURN VALUE IN E - XOR A ; SIGNAL SUCCESS - RET ; DONE -; -ANSI_IN1: ; PERFORM ACTUAL KEYBOARD INPUT - LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ - CALL EMU_VDADISP ; CALL VDA DISPATCHER - LD A,E ; CHARACTER READ INTO A - BIT 7,A ; TEST HIGH BIT - JR NZ,ANSI_IN2 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR - XOR A ; OTHERWISE, SIGNAL SUCCESS - RET ; AND RETURN THE KEY -; -ANSI_IN2: ; HANDLE SPECIAL KEY - CALL ANSI_KDISP ; IF $80 OR HIGHER, DISPATCH - JR ANSI_IN ; AND LOOP -; -; WRITE A CHARACTER W/ EMULATION -; -ANSI_OUT: - LD HL,ANSI_OUT2 ; RETURN ADDRESS - PUSH HL ; PUT IT ON STACK - LD A,E ; GET THE INCOMING CHARACTER - CP $20 ; $00-$1F IS C0 - JP C,ANSI_C0DISP ; IF C0, DO C0 DISPATCH - CP $80 ; $20-$7F - JR C,ANSI_OUT1 ; HANDLE VIA STATE MACHINE - CP $A0 ; $80-$9F IS C1 - JP C,ANSI_C1DISP ; IF C1, DO C1 DISPATCH -; -ANSI_OUT1: ; PROCESS OTHER CHARS VIA STATE MACHINE - LD HL,(ANSI_STATE) ; LOAD THE CURRENT STATE - JP (HL) ; DO IT -; CALL JPHL ; DO IT -; -ANSI_OUT2: ; SET RESULT AND RETURN - XOR A ; SIGNAL SUCCESS - RET -; -; CHECK INPUT STATUS -; -ANSI_IST: ; CHECK QUEUE FIRST - LD A,(ANSI_QLEN) ; GET CURRENT QUEUE LENGTH - OR A ; SET FLAGS - RET NZ ; RETURN IF CHAR(S) WAITING -; - ; QUEUE WAS EMPTY, CHECK HARDWARE STATUS - LD B,BF_VDAKST ; SET FUNCTION TO KEYBOARD STATUS - CALL EMU_VDADISP ; CHECK STATUS - OR A ; SET FLAGS - RET Z ; NO KEYS WAITING, RETURN NO JOY -; - ; KEY WAITING, GET IT AND HANDLE IT - LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ - CALL EMU_VDADISP ; DO IT - LD A,E ; CHARACTER READ TO A - BIT 7,A ; TEST HIGH BIT - JR NZ,ANSI_IST1 ; HANDLE $80 OR HIGHER AS SPECIAL CHAR -; - ; REGULAR CHARACTER RECEIVED, QUEUE IT AND RETURN CHARS WAITING STATUS - LD HL,ANSI_QUEUE ; SET HL TO START OF QUEUE - LD (ANSI_QPTR),HL ; RESET QUEUE POINTER - LD A,E ; RESTORE CHARACTER RECEIVED - LD (HL),A ; SAVE IT AT THE HEAD OF THE QUEUE - XOR A ; ZERO ACCUM - INC A ; ASSUM := 1 (NUM CHARS IN QUEUE) - LD (ANSI_QLEN),A ; SAVE NEW QUEUE LEN - JR ANSI_IST ; REPEAT -; -ANSI_IST1: ; HANDLE SPECIAL KEY - CALL ANSI_KDISP ; DO SPECIAL KEY HANDLING - JR ANSI_IST ; REPEAT -; -; CHECK OUTPUT STATUS -; -ANSI_OST: ; VIDEO OUTPUT IS *ALWAYS* READY - XOR A ; ZERO ACCUM - INC A ; A := $FF TO SIGNAL OUTPUT BUFFER READY - RET -; -; SET CONFIGURATION -; -ANSI_CFG: - XOR A ; SIGNAL SUCCESS - RET -; -; INITIALIZE -; -ANSI_INI: - ; QUERY THE VIDEO DRIVER FOR SCREEN DIMENSIONS - LD B,BF_VDAQRY ; FUNCTION IS QUERY - LD HL,0 ; WE DO NOT WANT A COPY OF THE CHARACTER BITMAP DATA - CALL EMU_VDADISP ; PERFORM THE QUERY FUNCTION - LD (ANSI_DIM),DE ; SAVE THE SCREEN DIMENSIONS RETURNED -; - ; INITIALIZE ALL WORKING VARIABLES - LD DE,0 ; DE := 0, CURSOR TO HOME POSITION 0,0 - LD (ANSI_POS),DE ; SAVE CURSOR POSITION - LD HL,ANSI_STBASE ; SET STATE TO BASE - LD (ANSI_STATE),HL ; DO IT - LD A,ANSI_DEFATTR ; DEFAULT ATTRIBUTE - LD (ANSI_ATTR),A ; CLEAR ATTRIBUTES - LD A,ANSI_DEFCOLOR ; DEFAULT COLOR - LD (ANSI_COLOR),A ; RESET COLOR - XOR A ; ZERO ACCUM - LD (ANSI_WRAP),A ; CLEAR WRAP FLAG - LD (ANSI_LNM),A ; SET LINE FEED NEW LINE MODE - LD (ANSI_CKM),A ; CLEAR DEC CURSOR KEY MODE - LD (ANSI_QLEN),A ; ZERO THE QUEUE LENGTH - LD A,$FF ; SET ALL BITS OF ACCUM - LD (ANSI_AWM),A ; SET DEC AUTOWRAP MODE -; - ; RESET TAB STOPS TO DEFAULT (EVERY 8 CHARACTERS) - LD A,%10000000 ; STOP AT FIRST OF EVERY 8 CHARACTERS - LD HL,ANSI_TABS ; POINT TO TAB STOP BITMAP - LD B,32 ; INIT 32 BYTES -; -ANSI_INI1: ; LOOP TO RESET TAB STOPS - LD (HL),A ; SET A BYTE - INC HL ; POINT TO NEXT BYTE - DJNZ ANSI_INI1 ; LOOP TILL ALL BYTES DONE -; - ; RESET THE CURRENT VIDEO DRIVER - LD B,BF_VDARES ; SET FUNCTION TO RESET - JP EMU_VDADISP ; RESET VDA AND RETURN -; -; QUERY STATUS -; -ANSI_QRY: - XOR A ; SIGNAL SUCCESS - RET -; -;================================================================================================== -; ANSI STATE MACHINE ENTRY POINTS -;================================================================================================== -; -ANSI_STBASE: ; STATE == BASE - JP ANSI_RENDER ; RENDER THE GLYPH -; -; -; -ANSI_STESC: ; STATE == ESCAPE SEQUENCE - RES 7,A ; CLEAR HIGH BIT - CP $30 ; $20 - $2F ARE INTERMEDIATE CHARS - JP C,ANSI_COLLINT ; COLLECT INTERMEDIATE CHARACTERS - CP $7F ; $30 - $7E - RET NC ; IGNORE $7F - LD HL,ANSI_STBASE ; BASE STATE - LD (ANSI_STATE),HL ; SET IT - JP ANSI_ESCDISP ; DISPATCH FOR ESCAPE SEQUENCE -; -; -; -ANSI_STCTL: ; STATE == CONTROL SEQUENCE - RES 7,A ; CLEAR HIGH BIT - CP $30 - JP C,ANSI_COLLINT ; COLLECT INTERMEDIATE CHARACTERS - CP $3C - JP C,ANSI_COLLPAR ; COLLECT PARAMETERS - CP $40 - JP C,ANSI_COLLPRI ; COLLECT PRIVATE CHARACTERS - CP $7F ; $30 - $7E - RET NC ; IGNORE $7F - LD HL,ANSI_STBASE ; BASE STATE - LD (ANSI_STATE),HL ; SET IT - JP ANSI_CTLDISP ; DISPATCH FOR CONTROL SEQUENCE -; -; -; -ANSI_STSTR: ; STATE == STRING DATA - RET -; -;================================================================================================== -; ANSI C0 DISPATCHING -;================================================================================================== -; -ANSI_C0DISP: - CP $08 ; BS: BACKSPACE - JP Z,ANSI_BS - CP $0A ; LF: LINEFEED - JP Z,ANSI_LF - CP $0B ; VT: VERTICAL TAB - JP Z,ANSI_LF ; TREAD AS LINEFEED - CP $0C ; FF: FORMFEED - JP Z,ANSI_LF ; TREAT AS LINEFEED - CP $0D ; CR: CARRIAGE RETURN - JP Z,ANSI_CR - CP $18 ; CAN: CANCEL - JP Z,ANSI_CAN - CP $1A ; SUB: ??? - JP Z,ANSI_SUB - CP $1B ; ESC: ESCAPE - JP Z,ANSI_ESC - RET -; -;================================================================================================== -; ANSI C1 DISPATCHING -;================================================================================================== -; -ANSI_C1DISP: - CP $84 ; IND: INDEX - JP Z,ANSI_LF ; DO IT - CP $85 ; NEL: NEXT LINE - JP Z,ANSI_NEL ; DO IT - CP $88 ; HTS: HORIZONTAL TAB SET - JP Z,ANSI_HTS ; DO IT - CP $8D ; RI: REVERSE INDEX - JP Z,ANSI_RI ; DO IT - CP $9B ; CSI: CONTROL SEQ INTRODUCER - JP Z,ANSI_CSI ; HANDLE IT -; - ; IGNORE OTHERS - RET -; -;================================================================================================== -; ANSI ESCAPE SEQUENCE DISPATCHING -;================================================================================================== -; -ANSI_ESCDISP: -#IF (ANSITRACE >= 2) - PRTS("($") - PUSH AF - LD A,(ANSI_INT) - OR A - CALL NZ,COUT - CALL PC_COMMA - POP AF - CALL COUT - CALL PC_RPAREN -#ENDIF - LD (ANSI_FINAL),A ; RECORD THE FINAL CHARACTER - LD A,(ANSI_INT) ; LOAD THE INTERMEDIATE CHARACTER - OR A ; SET FLAGS - JR Z,ANSI_ESCDISP1 ; NO INT CHARACTER, DO NORMAL DISPATCH - CP '#' ; INTERMEDIATE CHAR == '#'? - JR Z,ANSI_ESCDISP2 ; YES, DO # DISPATCHING - JP ANSI_UNK ; UNKNOWN, ABORT -; -ANSI_ESCDISP1: ; NORMAL ESCAPE DISPATCHING, NO INT CHARACTER - LD A,(ANSI_FINAL) ; GET FINAL CHARACTER - CP $40 ; $30-$3F - JR C,ANSI_ESCDISP1A ; YES, CONTINUE NORMALLY - CP $60 ; $40-$5F - JR NC,ANSI_ESCDISP1A ; NOPE, $60 AND ABOVE CONTINUE NORMALLY -; - ; $40-$5F MAPS TO $80-$9F IN C1 RANGE - CALL ANSI_CLEAR ; CLEAR STATE RELATED VARIABLES - LD HL,ANSI_STBASE ; BASE STATE - LD (ANSI_STATE),HL ; SET IT - ADD A,$40 ; MAP $40-$5F -> $80-$9F - JP ANSI_C1DISP ; PROCESS AS C1 CHARACTER -; -ANSI_ESCDISP1A: ; CONTINUE NORMAL ESCAPE SEQ DISPATCHING - CP 'c' ; RIS: RESET TO INITIAL STATE - JP Z,ANSI_INI ; DO A FULL RESET - JP ANSI_UNK ; UNKNOWN, ABORT -; -ANSI_ESCDISP2: ; ESC DISPATCHING FOR '#' INT CHAR - LD A,(ANSI_FINAL) ; GET FINAL CHARACTER - CP '8' ; DECALN: DEC SCREEN ALIGNMENT TEST - JP Z,ANSI_DECALN ; HANDLE IT - JP ANSI_UNK ; UNKNOWN, ABORT -; -;================================================================================================== -; ANSI CONTROL SEQUENCE DISPATCHING -;================================================================================================== -; -ANSI_CTLDISP: - LD (ANSI_FINAL),A ; RECORD THE FINAL CHARACTER -#IF (ANSITRACE >= 2) - PUSH AF - PRTS("($") - LD A,(ANSI_PRI) - OR A - CALL NZ,COUT - CALL PC_COMMA - LD DE,ANSI_PARLST - LD A,(ANSI_PARIDX) - INC A - CALL PRTHEXBUF - CALL PC_COMMA - LD A,(ANSI_INT) - OR A - CALL NZ,COUT - CALL PC_COMMA - POP AF - CALL COUT - CALL PC_RPAREN -#ENDIF - ; BRANCH BASED ON PRIVATE CHARACTER OF SEQUENCE - LD A,(ANSI_PRI) ; GET THE PRIVATE CHARACTER - OR A ; SET FLAGS - JR Z,ANSI_STD ; IF ZERO, NO PRIVATE CHAR, DO STANDARD - CP '?' ; '?' = DEC PRIVATE - JR Z,ANSI_DEC ; HANDLE DEC PRIVATE SEQUENCES - JR ANSI_UNK ; UNKNOWN, ABORT -; -ANSI_STD: ; DISPATCH ON INTERMEDIATE CHAR W/ NO PRIVATE CHAR (STD) - LD A,(ANSI_INT) ; GET THE INTERMEDIATE CHARCACTER - OR A ; SET FLAGS - JR Z,ANSI_STD1 ; NO INTERMEDIATE CHARACTER, HANDLE IT - ; CHECK FOR ANY OTHER STD INTERMEDIATE CHARACTERS HERE... - JR ANSI_UNK ; UNKNOWN, ABORT -; -ANSI_STD1: ; DISPATCH FOR FINAL CHAR W/ NO INTERMEDIATE CHAR AND NO PRIVATE CHAR (STD) - LD A,(ANSI_FINAL) ; GET FINAL CHARACTER - CP 'A' ; CUU: CURSOR UP - JP Z,ANSI_CUU - CP 'B' ; CUD: CURSOR DOWN - JP Z,ANSI_CUD - CP 'C' ; CUF: CURSOR FORWARD - JP Z,ANSI_CUF - CP 'D' ; CUB: CURSOR BACKWARD - JP Z,ANSI_CUB - CP 'H' ; CUP: CURSOR POSITION - JP Z,ANSI_CUP - CP 'J' ; ED: ERASE IN DISPLAY - JP Z,ANSI_ED - CP 'K' ; EL: ERASE IN LINE - JP Z,ANSI_EL - CP 'L' ; IL: INSERT LINE - JP Z,ANSI_IL - CP 'M' ; DL: DELETE LINE - JP Z,ANSI_DL - CP 'f' ; HVP: HORIZONTAL/VERTICAL POSITION - JP Z,ANSI_HVP - CP 'g' ; TBC: TAB CLEAR - JP Z,ANSI_TBC - CP 'h' ; SM: SET MODE - JP Z,ANSI_SM - CP 'l' ; RM: RESET MODE - JP Z,ANSI_RM - CP 'm' ; SGR: SELECT GRAPHIC RENDITION - JP Z,ANSI_SGR - ; CHECK FOR ANY OTHERS HERE - JR ANSI_UNK ; UNKNOWN, ABORT -; -ANSI_DEC: ; DISPATCH ON INTERMEDIATE CHAR W/ PRIVATE CHAR = '?' (DEC) - LD A,(ANSI_INT) ; GET THE INTERMEDIATE CHARCACTER - OR A ; SET FLAGS - JR Z,ANSI_DEC1 ; NO INTERMEDIATE CHARACTER, HANDLE IT - ; CHECK FOR ANY OTHER DEC INTERMEDIATE CHARACTERS HERE... - JR ANSI_UNK ; UNKNOWN, ABORT -; -ANSI_DEC1: ; DISPATCH FOR FINAL CHAR W/ NO INTERMEDIATE CHAR AND PRIVATE CHAR = '?' (DEC) - LD A,(ANSI_FINAL) ; GET FINAL CHARACTER - CP 'h' ; SM: SET DEC MODE - JP Z,ANSI_DECSM - CP 'l' ; RM: RESET DEC MODE - JP Z,ANSI_DECRM - JR ANSI_UNK ; UNKNOWN, ABORT -; -ANSI_UNK: ; DIAGNOSE UNKNOWN SEQUENCE -#IF (ANSITRACE >= 2) - PRTS("***UNK***$") -#ENDIF - RET -; -;================================================================================================== -; ANSI PROTOCOL SUPPORT FUNCTIONS -;================================================================================================== -; -; CLEAR THE WORKING VARIABLES AT START OF NEW ESC/CTL SEQUENCE -; -ANSI_CLEAR: - PUSH AF ; PRESERVE AF - LD HL,ANSI_VARS ; POINT TO VARS - LD B,ANSI_VARLEN ; B := NUMBER OF BYTES TO CLEAR - XOR A ; A := 0 -; -ANSI_CLEAR1: ; LOOP - LD (HL),A ; CLEAR THE BYTE - INC HL ; BUMP POINTER - DJNZ ANSI_CLEAR1 ; LOOP AS NEEDED -; - POP AF ; RECOVER AF - RET ; DONE -; -; COLLECT INTERMEDIATE CHARACTERS -; WE DO NOT SUPPORT MORE THAN 1 WHICH IS ALL THAT IS EVER -; USED BY THE STANDARD. IF MORE THAN ONE RECEIVED, IT IS OVERLAID -; -ANSI_COLLINT: - LD (ANSI_INT),A ; RECORD INTERMEDIATE CHAR - RET ; DONE -; -; COLLECT PARAMETERS -; ';' SEPARATES PARAMETERS -; '0'-'9' ARE DIGITS OF CURRENT PARAMETER -; -ANSI_COLLPAR: - ; HANDLE SEPARATOR - CP $3B ; ';' SEPARATOR? - JR NZ,ANSI_COLLPAR1 ; NOPE, CONTINUE - LD A,(ANSI_PARIDX) ; GET CURRENT PARM POS INDEX - INC A ; INCREMENT - AND $0F ; 16 PARMS MAX!!! - LD (ANSI_PARIDX),A ; SAVE IT - RET ; DONE -; -ANSI_COLLPAR1: ; HANDLE '0'-'9' - CP '9' + 1 ; > '9'? - RET NC ; YUP, IGNORE CHAR - SUB '0' ; CONVERT TO BINARY VALUE - LD B,A ; SAVE VALUE IN B - LD A,(ANSI_PARIDX) ; A := CURRENT PARM INDEX - LD HL,ANSI_PARLST ; POINT TO START OF PARM LIST - LD DE,0 ; SETUP DE := 0 - LD E,A ; NOW DE := PARM OFFSET - ADD HL,DE ; NOW HL := PARM BYTE TO UPDATE - LD A,(HL) ; GET CURRENT VALUE - LD C,A ; COPY TO C - RLCA ; MULTIPLY BY 10 - RLCA ; " - ADD A,C ; " - RLCA ; " - ADD A,B ; ADD NEW DIGIT - LD (HL),A ; SAVE UPDATED VALUE - RET ; DONE -; -; COLLECT PRIVATE CHARACTERS -; WE DO NOT SUPPORT MORE THAN 1 WHICH IS ALL THAT IS EVER -; USED BY THE STANDARD. IF MORE THAN ONE RECEIVED, IT IS OVERLAID -; -ANSI_COLLPRI: - LD (ANSI_PRI),A ; RECORD THE PRIVATE CHARACTER - RET ; DONE -; -; CANCEL AN ESC/CTL SEQUENCE IN PROGRESS -; SOME VT TERMINALS WILL SHOW AN ERROR SYMBOL IN THIS CASE -; -ANSI_SUB: - ; DISPLAY AN ERR SYMBOL??? -; -; CANCEL AN ESC/CTL SEQUENCE IN PROGRESS -; -ANSI_CAN: - LD HL,ANSI_STBASE ; SET STATE TO BASE - LD (ANSI_STATE),HL ; SAVE IT - RET -; -; START AN ESC SEQ, CANCEL ANY ESC/CTL SEQUENCE IN PROGRESS -; -ANSI_ESC: - CALL ANSI_CLEAR ; CLEAR STATE RELEATED VARIABLES - LD HL,ANSI_STESC ; SET STATE TO ESCAPE SEQUENCE - LD (ANSI_STATE),HL ; SAVE IT - RET -; -; START A CTL SEQ -; -ANSI_CSI: - CALL ANSI_CLEAR ; CLEAR STATE RELEATED VARIABLES - LD HL,ANSI_STCTL ; SET STATE TO CONTROL SEQUENCE - LD (ANSI_STATE),HL ; SAVE IT - RET -; -;================================================================================================== -; ANSI FUNCTION EXECUTION -;================================================================================================== -; -ANSI_RENDER: -#IF (ANSITRACE >= 2) - LD A,E - CALL COUT -#ENDIF - PUSH DE - - ; IF WRAP PENDING, DO IT NOW - LD A,(ANSI_WRAP) ; GET THE WRAP FLAG - OR A ; SET FLAGS - CALL NZ,ANSI_NEL ; IF SET, PERFORM A LINEWRAP (CLEARS WRAP FLAG) -; - ; WRITE THE CHARACTER - POP DE ; RECOVER THE CHAR TO RENDER - LD B,BF_VDAWRC ; FUNC := WRITE CHARACTER - CALL EMU_VDADISP ; SPIT OUT THE RAW CHARACTER -; - ; END OF LINE HANDLING (CHECK FOR RIGHT MARGIN EXCEEDED) - LD A,(ANSI_COLS) ; GET SCREEN COLUMNS - LD B,A ; PUT IT IN B - LD A,(ANSI_COL) ; GET COLUMN - INC A ; BUMP IT TO REFLECT NEW CURSOR POSITION - LD (ANSI_COL),A ; SAVE IT - CP B ; PAST MAX? - RET C ; IF NOT, ALL DONE, JUST RETURN -; - ; CURSOR MOVED PAST RIGHT MARGIN, FIX IT AND SET WRAP FLAG - DEC A ; BACK TO RIGHT MARGIN - LD (ANSI_COL),A ; SAVE IT - CALL ANSI_XY ; UPDATE CURSOR POSITION ON SCREEN - LD A,$FF ; LOAD $FF TO SET FLAG - LD (ANSI_WRAP),A ; SAVE FLAG - RET ; AND RETURN -; -ANSI_FF: - LD DE,0 ; PREPARE TO HOME CURSOR - LD (ANSI_POS),DE ; SAVE NEW CURSOR POSITION - CALL ANSI_XY ; EXECUTE - LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS - LD H,D ; SET UP TO MULTIPLY ROWS BY COLS - CALL MULT8 ; HL := H * E TO GET TOTAL SCREEN POSITIONS - LD E,' ' ; FILL SCREEN WITH BLANKS - LD B,BF_VDAFIL ; SET FUNCTION TO FILL - CALL EMU_VDADISP ; PERFORM FILL - JP ANSI_XY ; HOME CURSOR AND RETURN -; -ANSI_BS: - LD A,(ANSI_COL) ; GET CURRENT COLUMN - DEC A ; BACK IT UP BY ONE - RET C ; IF CARRY, MARGIN EXCEEDED, ABORT - LD (ANSI_COL),A ; SAVE NEW COLUMN - JP ANSI_XY ; UDPATE CUSROR AND RETURN -; -ANSI_CR: - XOR A ; ZERO ACCUM - LD (ANSI_COL),A ; COL := 0 - JP ANSI_XY ; REPOSITION CURSOR AND RETURN -; -ANSI_LF: ; LINEFEED (FORWARD INDEX) - LD A,(ANSI_ROW) ; GET CURRENT ROW - LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS - DEC D ; D := MAX ROW NUM - CP D ; >= LAST ROW? - JR NC,ANSI_LF1 ; NEED TO SCROLL - INC A ; BUMP TO NEXT ROW - LD (ANSI_ROW),A ; SAVE IT - JP ANSI_XY ; UPDATE CURSOR AND RETURN -; -ANSI_LF1: ; SCROLL - LD E,1 ; SCROLL FORWARD 1 LINE - LD B,BF_VDASCR ; SET FUNCTION TO SCROLL - JP EMU_VDADISP ; DO THE SCROLLING AND RETURN -; -ANSI_RI: ; REVERSE INDEX (REVERSE LINEFEED) - LD A,(ANSI_ROW) ; GET CURRENT ROW - OR A ; SET FLAGS - JR Z,ANSI_RI1 ; IF AT TOP (ROW 0), NEED TO SCROLL - DEC A ; BUMP TO PRIOR ROW - LD (ANSI_ROW),A ; SAVE IT - JP ANSI_XY ; RESPOSITION CURSOR AND RETURN -; -ANSI_HT: ; HORIZONTAL TAB -; - ; CHECK FOR RIGHT MARGIN, IF AT MARGIN, IGNORE - LD A,(ANSI_COLS) ; GET SCREEN COLUMN COUNT - DEC A ; MAKE IT MAX COL NUM - LD B,A ; SAVE IN B - LD A,(ANSI_COL) ; GET CURRENT COLUMN - CP B ; COMPARE TO MAX - RET NC ; IF COL >= MAX, IGNORE -; - ; INCREMENT COL TILL A TAB STOP IS HIT OR RIGHT MARGIN -ANSI_HT1: - INC A ; NEXT COLUMN - PUSH AF ; SAVE COLUMN - PUSH BC ; SAVE MAX COLUMN - LD HL,ANSI_TABS ; POINT TO TABSTOP BITMAP - CALL BITTST ; TEST BIT FOR CURRENT COLUMN - POP BC ; RECOVER MAX COLUMN - POP AF ; RECOVER CUR COLUMN - JR NZ,ANSI_HT2 ; IF TABSTOP HIT, COMMIT NEW COLUMN - CP B ; TEST FOR RIGHT MARGIN - JR NC,ANSI_HT2 ; IF AT RIGHT MARGIN, COMMIT NEW COLUMN - JR ANSI_HT1 ; LOOP UNTIL DONE -; -ANSI_HT2: ; COMMIT THE NEW COLUMN VALUE - LD (ANSI_COL),A ; SAVE THE NEW COLUMN - JP ANSI_XY ; UPDATE CURSOR AND RETURN -; -ANSI_RI1: ; REVERSE SCROLL - LD E,-1 ; SCROLL -1 LINES (REVERSE SCROLL 1 LINE) - LD B,BF_VDASCR ; SET FUNCTION TO SCROLL - JP EMU_VDADISP ; DO THE SCROLLING AND RETURN -; -; -; -ANSI_HTS: ; HORIZONTAL TAB SET - LD HL,ANSI_TABS ; POINT TO TAB STOP BITMAP - LD A,(ANSI_COL) ; SET TAB STOP AT CURRENT COL - CALL BITSET ; SET THE APPROPRIATE BIT - RET -; -; -; -ANSI_TBC: ; TAB CLEAR - LD A,(ANSI_PARLST) ; GET FIRST PARM - OR A ; SET FLAGS - JR Z,ANSI_TBC1 ; 0 = CLEAR TAB AT CURRENT COL - CP 3 ; TEST FOR 3 - JR Z,ANSI_TBC2 ; 3 = CLEAR ALL TABS - RET ; ANYTHING ELSE IS IGNORED -; -ANSI_TBC1: ; CLEAR TAB AT CURRENT COL - LD HL,ANSI_TABS ; POINT TO TAB STOP BITMAP - LD A,(ANSI_COL) ; SET TAB STOP AT CURRENT COL - CALL BITCLR ; CLEAR THE APPROPRIATE BIT - RET ; DONE -; -ANSI_TBC2: ; CLEAR ALL TABS - LD HL,ANSI_TABS ; POINT TO TABSTOP BITMAP - LD B,32 ; CLEAR 32 BYTES - XOR A ; CLEAR WITH VALUE OF ZERO -; -ANSI_TBC3: ; CLEAR ALL TABS LOOP - LD (HL),A ; SET THE CURRENT BYTE - INC HL ; POINT TO NEXT BYTE - DJNZ ANSI_TBC3 ; LOOP UNTIL DONE - RET ; DONE -; -; -; -ANSI_SM: ; SET MODE -ANSI_DECSM: ; SET DEC MODE - LD C,$FF ; FLAG VALUE (SET VALUE) - JR ANSI_MODE ; GO TO SET/RESET MODE -; -ANSI_RM: ; RESET MODE -ANSI_DECRM: ; RESET DEC MODE - LD C,$00 ; FLAG VALUE (RESET VALUE) - JR ANSI_MODE ; GO TO SET/RESET MODE -; -ANSI_MODE: ; (RE)SET MODES, FLAG VALUE IN C - LD A,(ANSI_PARIDX) ; GET CURRENT PARM INDEX - INC A ; INCREMENT TO MAKE IT THE PARM COUNT - LD B,A ; MOVE COUNT TO B FOR LOOPING - LD HL,ANSI_PARLST ; USE HL AS PARM POINTER - -ANSI_MODE1: ; (RE)SET MODE LOOP - CALL ANSI_MODE2 - INC HL - DJNZ ANSI_MODE1 - -ANSI_MODE2: ; (RE)SET MODE LOOP - LD A,(ANSI_PRI) ; GET PRIVATE CHAR - OR A ; SET FLAGS - JR Z,ANSI_MODE3 ; IF ZERO, HANDLE SANDARD MODES - CP '?' ; IF '?', DEC PRIVATE - JR Z,ANSI_MODE4 ; HANDLE DEC PRIVATE MODES - RET ; OTHERWISE IGNORE -; -ANSI_MODE3: ; STANDARD MODES - LD A,(HL) ; GET PARM - INC HL ; INCREMENT POINTER FOR NEXT LOOP - CP 20 ; LNM: LINE FEED NEW LINE MODE? - JR Z,ANSI_MDLNM ; DO IT - RET ; OTHERWISE IGNORE -; -ANSI_MODE4: ; DEC PRIVATE MODES - LD A,(HL) ; GET PARM - CP 1 ; DECCKM: DEC CURSOR KEY MODE - JR Z,ANSI_MDDECCKM ; DO IT - CP 7 ; DECAWM: DEC AUTOWRAP MODE - JR Z,ANSI_MDDECAWM ; DO IT - RET ; OTHERWISE IGNORE -; -ANSI_MDLNM: ; (RE)SET LINE FEED NEW LINE MODE - LD A,C ; GET THE VALUE - LD (ANSI_LNM),A ; SAVE IT - RET -; -ANSI_MDDECCKM: ; (RE)SET DEC CURSOR KEY MODE FLAG - LD A,C ; GET THE VALUE - LD (ANSI_CKM),A ; SAVE IT - RET ; DONE -; -ANSI_MDDECAWM: ; (RE)SET DEC AUTOWRAP MODE - LD A,C ; GET THE VALUE - LD (ANSI_AWM),A ; SAVE IT - RET ; DONE -; -; -; -ANSI_NEL: ; NEXT LINE - CALL ANSI_CR - JP ANSI_LF -; -; -; -ANSI_CUU: ; CURSOR UP - LD A,(ANSI_PARLST) ; GET PARM - OR A ; SET FLAGS - JR NZ,ANSI_CUU1 ; WE HAVE A PARM, CONTINUE - INC A ; DEFAULT TO 1 -; -ANSI_CUU1: - LD B,A ; PARM IN B - LD A,(ANSI_ROW) ; GET CURRENT ROW - SUB B ; DECREMENT BY PARM VALUE - JR NC,ANSI_CUU2 ; NO CARRY, WE ARE GOOD - XOR A ; LESS THAN 0, FIX IT -; -ANSI_CUU2: - LD (ANSI_ROW),A ; SAVE IT - JP ANSI_XY ; MOVE CURSOR AND RETURN -; -; -; -ANSI_CUD: ; CURSOR DOWN - LD A,(ANSI_PARLST) ; GET PARM - OR A ; SET FLAGS - JR NZ,ANSI_CUD1 ; WE HAVE A PARM, CONTINUE - INC A ; DEFAULT TO 1 -ANSI_CUD1: - LD B,A ; PARM IN B - LD A,(ANSI_ROWS) ; GET ROW COUNT - DEC A ; DEC FOR MAX ROW NUM - LD C,A ; MAX ROW NUM IN C - LD A,(ANSI_ROW) ; GET CURRENT ROW - ADD A,B ; ADD PARM VALUE, A HAS NEW ROW - CP C ; COMPARE NEW ROW TO MAX ROW - JR C,ANSI_CUD2 ; IF CARRY, WE ARE WITHIN MARGIN - LD A,C ; OTHERWISE, SET TO MARGIN -; -ANSI_CUD2: - LD (ANSI_ROW),A ; SAVE IT - JP ANSI_XY ; MOVE CURSOR AND RETURN -; -; -; -ANSI_CUF: ; CURSOR FORWARD - LD A,(ANSI_PARLST) ; GET PARM - OR A ; SET FLAGS - JR NZ,ANSI_CUF1 ; WE HAVE A PARM, CONTINUE - INC A ; DEFAULT TO 1 -; -ANSI_CUF1: - LD B,A ; PARM IN B - LD A,(ANSI_COLS) ; GET COL COUNT - DEC A ; DEC FOR MAX COL NUM - LD C,A ; MAX COL NUM IN C - LD A,(ANSI_COL) ; GET CURRENT COL - ADD A,B ; ADD PARM VALUE, A HAS NEW COL - CP C ; COMPARE NEW COL TO MAX COL - JR C,ANSI_CUF2 ; IF CARRY, WE ARE WITHIN MARGINS - LD A,C ; OTHERWISE, SET TO MARGIN -; -ANSI_CUF2: - LD (ANSI_COL),A ; SAVE IT - JP ANSI_XY ; MOVE CURSOR AND RETURN -; -; -; -ANSI_CUB: ; CURSOR BACKWARD - LD A,(ANSI_PARLST) ; GET PARM - OR A ; SET FLAGS - JR NZ,ANSI_CUB1 ; WE HAVE A PARM, CONTINUE - INC A ; DEFAULT TO 1 -; -ANSI_CUB1: - LD B,A ; PARM IN B - LD A,(ANSI_COL) ; GET CURRENT COL - SUB B ; DECREMENT BY PARM VALUE - JR NC,ANSI_CUB2 ; NO CARRY, WE ARE GOOD - XOR A ; LESS THAN 0, FIX IT -; -ANSI_CUB2: - LD (ANSI_COL),A ; SAVE IT - JP ANSI_XY ; MOVE CURSOR AND RETURN -; -; -; -ANSI_CUP: ; CURSOR UPDATE -ANSI_HVP: ; HORIZONTAL/VERTICAL POSITION -; - ; HANDLE ROW NUMBER - LD A,(ANSI_PARLST + 0) ; ROW PARM - DEC A ; ADJUST FOR ZERO OFFSET - JP P,ANSI_CUP1 ; 0 OR MORE, OK, CONTINUE - XOR A ; NEGATIVE, FIX IT -ANSI_CUP1: - LD HL,ANSI_ROWS ; HL POINTS TO ROW COUNT - CP (HL) ; COMPARE TO ROW COUNT - JR C,ANSI_CUP2 ; IN BOUNDS, CONTINUE - LD A,(HL) ; FIX IT, LOAD ROW COUNT - DEC A ; SET TO LAST ROW NUM -ANSI_CUP2: - LD D,A ; COMMIT ROW NUMBER TO D -; - ; HANDLE COL NUMBER - LD A,(ANSI_PARLST + 1) ; COL PARM - DEC A ; ADJUST FOR ZERO OFFSET - JP P,ANSI_CUP3 ; 0 OR MORE, OK, CONTINUE - XOR A ; NEGATIVE, FIX IT -ANSI_CUP3: - LD HL,ANSI_COLS ; HL POINTS TO COL COUNT - CP (HL) ; COMPARE TO COL COUNT - JR C,ANSI_CUP4 ; IN BOUNDS, CONTINUE - LD A,(HL) ; FIX IT, LOAD COL COUNT - DEC A ; SET TO LAST COL NUM -ANSI_CUP4: - LD E,A ; COMMIT COL NUMBER TO E -; - ; COMMIT THE NEW CURSOR POSITION AND RETURN - LD (ANSI_POS),DE ; SAVE IT - JP ANSI_XY ; UPDATE CURSOR AND RETURN -; -; -; -ANSI_ED: ; ERASE IN DISPLAY - LD A,(ANSI_PARLST + 0) ; GET FIRST PARM - CP 0 ; ERASE CURSOR TO EOS - JR Z,ANSI_ED1 - CP 1 ; ERASE START THRU CURSOR - JR Z,ANSI_ED2 - CP 2 ; ERASE FULL DISPLAY? - JR Z,ANSI_ED3 - RET ; INVALID? -; -ANSI_ED1: ; ERASE CURSOR THRU EOS - LD DE,(ANSI_POS) ; GET CURSOR POSITION - CALL ANSI_XY2IDX ; HL NOW HAS CURSOR INDEX - PUSH HL ; SAVE IT - LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS - LD E,0 ; COL POSITION := 0 - CALL ANSI_XY2IDX ; HL NOW HAS EOS INDEX - POP DE ; RECOVER CURSOR POS INDEX - OR A ; CLEAR CARRY - SBC HL,DE ; SUBTRACT CURSOR INDEX FROM EOS INDEX - JR ANSI_ED4 ; COMPLETE THE FILL -; -ANSI_ED2: ; ERASE START THRU CURSOR - LD DE,0 ; CURSOR TO 0,0 FOR NOW - LD B,BF_VDASCP ; SET FUNCTION TO SET CURSOR POSITION - CALL EMU_VDADISP ; DO IT - LD DE,(ANSI_POS) ; GET ORIGINAL CURSOR POSITION - CALL ANSI_XY2IDX ; HL NOW HAS INDEX - INC HL ; ADD 1 POSITION TO ERASE THRU CURSOR POSITION - JR ANSI_ED4 ; COMPLETE THE FILL -; -ANSI_ED3: ; ERASE FULL DISPLAY - LD DE,0 ; CURSOR POS 0,0 - LD B,BF_VDASCP ; FUNCTION = SET CURSOR POS - CALL EMU_VDADISP ; DO IT - LD DE,(ANSI_DIM) ; DE := SCREEN ROWS/COLS - CALL ANSI_XY2IDX ; HL := CHARS ON SCREEN -; -ANSI_ED4: ; COMMON FILL PROCESS COMPLETION - LD E,' ' ; FILL WITH BLANK - LD B,BF_VDAFIL ; FUNCTION = FILL - CALL EMU_VDADISP ; DO IT - JP ANSI_XY ; RESTORE CURSOR POS AND RETURN -; -; -; -ANSI_EL: ; ERASE IN LINE - LD A,(ANSI_PARLST + 0) ; GET FIRST PARM - CP 0 ; ERASE CURSOR TO EOL - JR Z,ANSI_EL1 - CP 1 ; ERASE START THRU CURSOR - JR Z,ANSI_EL2 - CP 2 ; ERASE FULL LINE? - JR Z,ANSI_EL3 - RET ; INVALID? -; -ANSI_EL1: ; ERASE CURSOR THRU EOL - LD DE,(ANSI_POS) ; GET CURSOR POSITION - CALL ANSI_XY2IDX ; HL NOW HAS CURSOR INDEX - PUSH HL ; SAVE IT - LD DE,(ANSI_POS) ; GET CURSOR POSITION - LD E,0 ; COL POSITION := 0 - INC D ; ROW := ROW + 1 - CALL ANSI_XY2IDX ; HL NOW HAS EOL INDEX - POP DE ; RECOVER CURSOR POS INDEX - OR A ; CLEAR CARRY - SBC HL,DE ; SUBTRACT CURSOR INDEX FROM EOL INDEX - JR ANSI_EL4 ; COMPLETE THE FILL -; -ANSI_EL2: ; ERASE START THRU CURSOR - LD DE,(ANSI_POS) ; GET CURSOR POS - LD E,0 ; COL := 0, START OF ROW - LD B,BF_VDASCP ; SET FUNCTION TO SET CURSOR POSITION - CALL EMU_VDADISP ; DO IT - LD HL,(ANSI_POS) ; GET ORIGINAL CURSOR POSITION - LD H,0 ; ONLY ERASE COLUMNS - INC HL ; ADD 1 POSITION TO ERASE THRU CURSOR POSITION - JR ANSI_EL4 ; COMPLETE THE FILL -; -ANSI_EL3: ; ERASE FULL LINE - LD DE,(ANSI_POS) ; GET CURSOR POSITION - LD E,0 ; COL := 0 (START OF ROW) - LD B,BF_VDASCP ; FUNC = SET CURSOR POS - CALL EMU_VDADISP ; DO IT - LD HL,(ANSI_DIM) ; GET SCREEN DIM IN HL - LD H,0 ; H := 0, HL IS NOW CHARS IN A LINE - JR ANSI_EL4 ; COMPLETE THE FILL -; -ANSI_EL4 .EQU ANSI_ED4 ; REUSE CODE ABOVE -; -; -; -ANSI_IL: - LD A,(ANSI_PARLST) ; GET PARM - OR A ; SET FLAGS - JR NZ,ANSI_IL1 ; GOT IT CONTINUE - INC A ; NO PARM, DEFAULT TO 1 -; -ANSI_IL1: - LD B,A ; SET LOOP COUNTER - LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS - DEC D ; POINT TO LAST ROW - LD E,0 ; FIRST CHAR OF ROW -; -ANSI_IL2: - PUSH BC ; PRESERVE LOOP COUNTER - PUSH DE ; PRESERVE STARTING POSTION - CALL ANSI_IL3 ; DO AN ITERATION - POP DE ; RECOVER STARTING POSITION - POP BC ; RECOVER LOOP COUNTER - DJNZ ANSI_IL2 ; LOOP AS NEEDED -; - ; RESTORE CURSOR POSTION AND RETURN - JP ANSI_XY -; -ANSI_IL3: - ; SET CURSOR POSITION TO DEST - PUSH DE ; PRESERVE DE - LD B,BF_VDASCP ; FUNC = SET CURSOR POS - CALL EMU_VDADISP ; DO IT - POP DE ; RECOVER DE - ; SET HL TO LENGTH - LD HL,(ANSI_DIM) ; GET DIMENSIONS - LD H,0 ; ZERO MSB, SO COPY LEN IS COL COUNT - ; CHECK ROW, GET OUT IF WORKING ROW IS CURRENT ROW - LD A,(ANSI_ROW) ; GET CURRENT ROW - CP D ; COMPARE TO WORKING ROW NUM - JR Z,ANSI_IL4 ; IF EQUAL WE ARE DONE - ; SET DE TO SOURCE POS - DEC D ; DE NOW POINTS TO PRIOR ROW - ; DO THE COPY - PUSH DE ; PRESERVE DE - LD B,BF_VDACPY ; FUNCTION = COPY - CALL EMU_VDADISP ; COPY THE LINE - POP DE ; RECOVER DE - JR ANSI_IL3 ; LOOP -; -ANSI_IL4: ;CLEAR INSERTED LINE - LD E,' ' ; FILL WITH BLANK - LD B,BF_VDAFIL ; FUNCTION = FILL - JP EMU_VDADISP ; DO IT -; -; -; -ANSI_DL: - LD A,(ANSI_PARLST) ; GET PARM - OR A ; SET FLAGS - JR NZ,ANSI_DL1 ; GOT IT CONTINUE - INC A ; NO PARM, DEFAULT TO 1 -; -ANSI_DL1: - LD B,A ; SET LOOP COUNTER - LD DE,(ANSI_POS) ; GET CURSOR POS - LD E,0 ; COL := 0, START OF ROW -; -ANSI_DL2: - PUSH BC ; PRESERVE LOOP COUNTER - PUSH DE ; PRESERVE STARTING POSTION - CALL ANSI_DL3 ; DO AN ITERATION - POP DE ; RECOVER STARTING POSITION - POP BC ; RECOVER LOOP COUNTER - DJNZ ANSI_DL2 ; LOOP AS NEEDED -; - ; RESTORE CURSOR POSTION AND RETURN - JP ANSI_XY -; -ANSI_DL3: - ; SET CURSOR TO START OF DEST ROW - PUSH DE ; PRESERVE DE - LD B,BF_VDASCP ; FUNC = SET CURSOR POS - CALL EMU_VDADISP ; DO IT - POP DE ; RECOVER DE - ; SET DE TO SOURCE POS - INC D ; NEXT ROW, DE NOW HAS SOURCE - ; SET HL TO LENGTH - LD HL,(ANSI_DIM) ; GET DIMENSIONS - LD H,0 ; ZERO MSB, SO COPY LEN IS COL COUNT - ; CHECK ROW, GET OUT IF WORKING ROW NUM PAST END - LD A,(ANSI_ROWS) ; GET ROW COUNT - CP D ; COMPARE TO WORKING ROW NUM - JR Z,ANSI_DL4 ; IF EQUAL WE ARE DONE - ; DO THE COPY - PUSH DE ; PRESERVE DE - LD B,BF_VDACPY ; FUNCTION = COPY - CALL EMU_VDADISP ; COPY THE LINE - POP DE ; RECOVER DE - JR ANSI_DL3 ; LOOP -; -ANSI_DL4: ;CLEAR BOTTOM LINE - LD E,' ' ; FILL WITH BLANK - LD B,BF_VDAFIL ; FUNCTION = FILL - JP EMU_VDADISP ; DO IT -; -; -; -ANSI_SGR: ; SET GRAPHIC RENDITION - LD A,(ANSI_PARIDX) ; GET CURRENT PARM INDEX - INC A ; INC TO MAKE IT THE COUNT - LD B,A ; B IS NOW LOOP COUNTER - LD HL,ANSI_PARLST ; HL POINTS TO START OF PARM LIST -; -ANSI_SGR1: ; PROCESSING LOOP - PUSH BC ; PRESERVE BC - PUSH HL ; PRESERVE HL - LD A,(HL) - CALL ANSI_SGR2 ; HANDLE PARM - POP HL ; RESTORE HL - POP BC ; RESTORE BC - INC HL ; POINT TO NEXT PARM - DJNZ ANSI_SGR1 ; LOOP TILL DONE -; - ; NOW IMPLEMENT ALL CHANGES - LD A,(ANSI_ATTR) ; GET THE ATTRIBUTE VALUE - LD E,A ; MOVE TO E - LD B,BF_VDASAT ; SET ATTRIBUTE FUNCTION - CALL EMU_VDADISP ; CALL THE FUNCTION - LD A,(ANSI_COLOR) ; GET THE COLOR VALUE - LD E,A ; MOVE TO E - LD B,BF_VDASCO ; SET ATTRIBUTE FUNCTION - CALL EMU_VDADISP ; CALL THE FUNCTION - RET ; RETURN -; -ANSI_SGR2: ; HANDLE THE REQUEST CODE - CP 0 ; ALL OFF - JR Z,ANSI_SGR_OFF ; DO IT - CP 1 ; BOLD - JR Z,ANSI_SGR_BOLD ; DO IT - CP 4 ; UNDERLINE - JR Z,ANSI_SGR_UL ; DO IT - CP 5 ; BLINK - JR Z,ANSI_SGR_BLINK ; DO IT - CP 7 ; REVERSE - JR Z,ANSI_SGR_REV ; DO IT - CP 30 ; START OF FOREGROUND - RET C ; OUT OF RANGE - CP 38 ; END OF RANGE - JR C,ANSI_SGR_FG ; SET FOREGROUND - CP 40 ; START OF BACKGROUND - RET C ; OUT OF RANGE - CP 48 ; END OF RANGE - JR C,ANSI_SGR_BG ; SET BACKGROUND - RET ; OTHERWISE OUT OF RANGE -; -ANSI_SGR_OFF: - LD A,ANSI_DEFATTR ; DEFAULT ATTRIBUTE - LD (ANSI_ATTR),A ; CLEAR ATTRIBUTES - LD A,ANSI_DEFCOLOR ; DEFAULT COLOR - LD (ANSI_COLOR),A ; RESET COLOR - RET -; -ANSI_SGR_BOLD: - LD A,(ANSI_COLOR) ; LOAD CURRENT COLOR - OR %00001000 ; SET BOLD BIT - LD (ANSI_COLOR),A ; SAVE IT - RET -; -ANSI_SGR_UL: - LD A,(ANSI_ATTR) ; LOAD CURRENT ATTRIBUTE - OR %00000010 ; SET UNDERLINE BIT - LD (ANSI_ATTR),A ; SAVE IT - RET -; -ANSI_SGR_BLINK: - LD A,(ANSI_ATTR) ; LOAD CURRENT ATTRIBUTE - OR %00000001 ; SET BLINK BIT - LD (ANSI_ATTR),A ; SAVE IT - RET -; -ANSI_SGR_REV: - LD A,(ANSI_ATTR) ; LOAD CURRENT ATTRIBUTE - OR %00000100 ; SET REVERSE BIT - LD (ANSI_ATTR),A ; SAVE IT - RET -; -ANSI_SGR_FG: - SUB 30 - LD E,A - LD A,(ANSI_COLOR) - AND %11111000 - OR E - LD (ANSI_COLOR),A - RET -; -ANSI_SGR_BG: - SUB 40 - RLCA - RLCA - RLCA - RLCA - LD E,A - LD A,(ANSI_COLOR) - AND %10001111 - OR E - LD (ANSI_COLOR),A - RET -; -; -; -ANSI_DECALN: ; DEC SCREEN ALIGNMENT TEST - LD DE,0 ; PREPARE TO HOME CURSOR - LD (ANSI_POS),DE ; SAVE NEW CURSOR POSITION - CALL ANSI_XY ; EXECUTE - LD DE,(ANSI_DIM) ; GET SCREEN DIMENSIONS - LD H,D ; SET UP TO MULTIPLY ROWS BY COLS - CALL MULT8 ; HL := H * E TO GET TOTAL SCREEN POSITIONS - LD E,'E' ; FILL SCREEN WITH BLANKS - LD B,BF_VDAFIL ; SET FUNCTION TO FILL - CALL EMU_VDADISP ; PERFORM FILL - JP ANSI_XY ; HOME CURSOR AND RETURN -; -;================================================================================================== -; ANSI PROTOCOL KEYBOARD DISPATCHING -;================================================================================================== -; -; HANDLE SPECIAL KEYBOARD CHARACTERS BY FILLING QUEUE WITH DATA -; -ANSI_KDISP: - ; RESET THE QUEUE POINTER - LD HL,ANSI_QUEUE - LD (ANSI_QPTR),HL -; - ; HANDLE FUNCTION KEYS - LD B,'P' - CP $E0 ; F1 - JR Z,ANSI_KDISP_FN - LD B,'Q' - CP $E1 ; F2 - JR Z,ANSI_KDISP_FN - LD B,'R' - CP $E2 ; F3 - JR Z,ANSI_KDISP_FN - LD B,'S' - CP $E3 ; F4 - JR Z,ANSI_KDISP_FN -; - ; HANDLE EDIT KEYS - LD B,'2' - CP $F0 ; INSERT - JR Z,ANSI_KDISP_ED - LD B,'3' - CP $F1 ; DELETE - JR Z,ANSI_KDISP_ED - LD B,'1' - CP $F2 ; HOME - JR Z,ANSI_KDISP_ED - LD B,'4' - CP $F3 ; END - JR Z,ANSI_KDISP_ED - LD B,'5' - CP $F4 ; PAGEUP - JR Z,ANSI_KDISP_ED - LD B,'6' - CP $F5 ; PAGEDOWN - JR Z,ANSI_KDISP_ED -; - ; HANDLE DIRECTION KEYS - LD B,'A' - CP $F6 ; UP - JR Z,ANSI_KDISP_DIR - LD B,'B' - CP $F7 ; DOWN - JR Z,ANSI_KDISP_DIR - LD B,'D' - CP $F8 ; LEFT - JR Z,ANSI_KDISP_DIR - LD B,'C' - CP $F9 ; RIGHT - JR Z,ANSI_KDISP_DIR -; - RET ; NO MATCH, DONE -; -ANSI_KDISP_FN: ; ADD FUNCTION KEY SEQUENCE TO QUEUE - LD A,$1B - LD (HL),A - INC HL - LD A,'O' - LD (HL),A - INC HL - LD A,B - LD (HL),A - LD A,3 - LD (ANSI_QLEN),A - RET -; -ANSI_KDISP_ED: ; ADD EDIT KEY SEQUENCE TO QUEUE - LD A,$1B - LD (HL),A - INC HL - LD A,'[' - LD (HL),A - INC HL - LD A,B - LD (HL),A - INC HL - LD A,'~' - LD (HL),A - LD A,4 - LD (ANSI_QLEN),A - RET -; -ANSI_KDISP_DIR: ; ADD DIRECTION KEY SEQUENCE TO QUEUE -; - ; SPECIAL CASE FOR CURSOR KEY MODE - LD A,(ANSI_CKM) - OR A - JR NZ,ANSI_KDISP_FN ; HANDLE LIKE FUNCTION KEY -; - LD A,$1B - LD (HL),A - INC HL - LD A,'[' - LD (HL),A - INC HL - LD A,B - LD (HL),A - LD A,3 - LD (ANSI_QLEN),A - RET -; -;================================================================================================== -; SUPPORT FUNCTIONS -;================================================================================================== -; -ANSI_XY: - XOR A ; ZERO ACCUM - LD (ANSI_WRAP),A ; CLEAR THE WRAP FLAG - LD DE,(ANSI_POS) ; GET THE DESIRED CURSOR POSITION - LD B,BF_VDASCP ; SET FUNCTION TO SET CURSOR POSITION - JP EMU_VDADISP ; REPOSITION CURSOR -; -; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL -; D=ROW, E=COL -; -ANSI_XY2IDX: - PUSH DE - LD HL,(ANSI_DIM) ; GET DIMENSIONS - LD H,L ; COLS -> H - LD E,D ; ROW NUM -> E - CALL MULT8 ; HL := H * E (ROW OFFSET) - POP DE ; RECOVER ORIGINAL ROW/COL - LD D,0 ; GET RID OF ROW COUNT - ADD HL,DE ; ADD COLUMN OFFSET - RET ; RETURN, HL HAS INDEX -; -;================================================================================================== -; WORKING DATA STORAGE -;================================================================================================== -; -ANSI_POS: -ANSI_COL .DB 0 ; CURRENT COLUMN - 0 BASED -ANSI_ROW .DB 0 ; CURRENT ROW - 0 BASED -; -ANSI_DIM: -ANSI_COLS .DB 80 ; NUMBER OF COLUMNS ON SCREEN -ANSI_ROWS .DB 24 ; NUMBER OF ROWS ON SCREEN -; -ANSI_STATE .DW PANIC ; CURRENT FUNCTION FOR STATE MACHINE -ANSI_ATTR .DB ANSI_DEFATTR ; CURRENT CHARACTER ATTRIBUTE -ANSI_COLOR .DB ANSI_DEFCOLOR ; CURRENT CHARACTER COLOR; -ANSI_WRAP .DB 0 ; WRAP PENDING FLAG -ANSI_TABS .FILL 32,0 ; TAB STOP BIT MAP (256 BITS) -ANSI_LNM .DB 0 ; LINE FEED NEW LINE MODE FLAG -ANSI_CKM .DB 0 ; DEC CURSOR KEY MODE FLAG -ANSI_AWM .DB 0 ; DEC AUTOWRAP MODE FLAG -ANSI_QLEN .DB 0 ; INPUT QUEUE LENGTH -ANSI_QPTR .DW 0 ; CURRENT QUEUE POINTER -ANSI_QUEUE .FILL 16,0 ; 16 BYTE QUEUE BUFFER -; -ANSI_VARS: -ANSI_PRI .DB 0 ; PRIVATE CHARACTER RECORDED HERE -ANSI_INT .DB 0 ; INTERMEDIATE CHARACTER RECORDED HERE -ANSI_FINAL .DB 0 ; FINAL CHARACTER RECORDED HERE -ANSI_PARIDX .DB 0 ; NUMBER OF PARAMETERS RECORDED -ANSI_PARLST .FILL 16,0 ; PARAMETER VALUE LIST (UP TO 16 BYTE VALUES) -ANSI_VARLEN .EQU $ - ANSI_VARS diff --git a/branches/s100/Source/bdosb01.asm b/branches/s100/Source/bdosb01.asm deleted file mode 100644 index d468861a..00000000 --- a/branches/s100/Source/bdosb01.asm +++ /dev/null @@ -1,2586 +0,0 @@ - .title "Digital Research BDOS, Version 2.2" - .page 49 - -ENDFIL .EQU 1 ;FILL FULL BDOS LENGTH -; -IOBYTE: .EQU 3 ; I/O DEFINITION BYTE. -TDRIVE: .EQU 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY: .EQU 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB: .EQU 5CH ; DEFAULT FILE CONTROL BLOCK. -TBUFF: .EQU 80H ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE: .EQU 100H ; TRANSIANT PROGRAM STORAGE AREA. -; -; SET CONTROL CHARACTER .EQUATES. -; -CNTRLC: .EQU 3 ; CONTROL-C -CNTRLE: .EQU 05H ; CONTROL-E -BS: .EQU 08H ; BACKSPACE -TAB: .EQU 09H ; TAB -LF: .EQU 0AH ; LINE FEED -FF: .EQU 0CH ; FORM FEED -CR: .EQU 0DH ; CARRIAGE RETURN -CNTRLP: .EQU 10H ; CONTROL-P -CNTRLR: .EQU 12H ; CONTROL-R -CNTRLS: .EQU 13H ; CONTROL-S -CNTRLU: .EQU 15H ; CONTROL-U -CNTRLX: .EQU 18H ; CONTROL-X -CNTRLZ: .EQU 1AH ; CONTROL-Z (END-OF-FILE MARK) -DEL: .EQU 7FH ; RUBOUT - -; CPM ORIGIN CALCULATE - -NK .EQU 59 ;SYSTEM SIZE -BASE .EQU (NK*1024)-5000H -CCPO .EQU BASE+3400H ;CCP ORIGIN -BDOSO .EQU BASE+3C00H ;BDOS ORIGIN -BIOSO .EQU BASE+4A00H ;BIOS ORIGIN - - .ORG BDOSO - .DB 0,0,0,0,0,0 ;OLD SERIAL NUMBER -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE: JP FBASE1 -; -; BDOS ERROR TABLE. -; -BADSCTR:.DW ERROR1 ; BAD SECTOR ON READ OR WRITE. -BADSLCT:.DW ERROR2 ; BAD DISK SELECT. -RODISK: .DW ERROR3 ; DISK IS READ ONLY. -ROFILE: .DW ERROR4 ; FILE IS READ ONLY. -; -; ENTRY INTO BDOS. (DE) OR (E) ARE THE PARAMETERS PASSED. THE -; FUNCTION NUMBER DESIRED IS IN REGISTER (C). -; E contains drive number if passing this -FBASE1: EX DE,HL ; SAVE THE (DE) PARAMETERS. - LD (PARAMS),HL - EX DE,HL - LD A,E ; AND SAVE REGISTER (E) IN PARTICULAR. - LD (EPARAM),A - LD HL,0 - LD (STATUS),HL ; CLEAR RETURN STATUS. - ADD HL,SP - LD (USRSTACK),HL ; SAVE USERS STACK POINTER. - LD SP,STKAREA ; AND SET OUR OWN. - XOR A ; CLEAR AUTO SELECT STORAGE SPACE. - LD (AUTOFLAG),A - LD (AUTO),A - LD HL,GOBACK ; SET RETURN ADDRESS. - PUSH HL - LD A,C ; GET FUNCTION NUMBER. - CP NFUNCTS ; VALID FUNCTION NUMBER? - RET NC - LD C,E ; KEEP SINGLE REGISTER FUNCTION HERE. - LD HL,FUNCTNS ; NOW LOOK THRU THE FUNCTION TABLE. - LD E,A - LD D,0 ; (DE)=FUNCTION NUMBER. - ADD HL,DE - ADD HL,DE ; (HL)=(START OF TABLE)+2*(FUNCTION NUMBER). - LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE)=ADDRESS FOR THIS FUNCTION. - LD HL,(PARAMS) ; RETRIEVE PARAMETERS. - EX DE,HL ; NOW (DE) HAS THE ORIGINAL PARAMETERS. - JP (HL) ; EXECUTE DESIRED FUNCTION. -; -; BDOS FUNCTION JUMP TABLE. -; -NFUNCTS:.EQU 41 ; NUMBER OF FUNCTIONS IN FOLLOWIN TABLE. -; -FUNCTNS:.DW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - .DW SETIOB,PRTSTR,R.DBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - .DW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - .DW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - .DW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - .DW RTN,WTSPECL -; -; BDOS ERROR MESSAGE SECTION. -; -ERROR1: LD HL,BADSEC ; BAD SECTOR MESSAGE. - CALL PRTERR ; PRINT IT AND GET A 1 CHAR RESPONCE. - CP CNTRLC ; RE-BOOT REQUEST (CONTROL-C)? - JP Z,0 ; YES. - RET ; NO, RETURN TO RETRY I/O FUNCTION. - -ERROR2: LD HL,BADSEL ; BAD DRIVE SELECTED. - JP ERROR5 -; -ERROR3: LD HL,DISKRO ; DISK IS READ ONLY. - JP ERROR5 -; -ERROR4: LD HL,FILERO ; FILE IS READ ONLY. -; -ERROR5: CALL PRTERR - JP 0 ; ALWAYS REBOOT ON THESE ERRORS. -; -BDOSERR:.DB "BDOS ERR ON " -BDOSDRV:.DB " : $" -BADSEC: .DB "BAD SECTOR$" -BADSEL: .DB "SELECT$" -FILERO: .DB "FILE " -DISKRO: .DB "R/O$" -; -; PRINT BDOS ERROR MESSAGE. -; -PRTERR: PUSH HL ; SAVE SECOND MESSAGE POINTER. - CALL OUTCRLF ; SEND (CR)(LF). - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - ADD A,'A' ; MAKE ASCII. - LD (BDOSDRV),A ; AND PUT IN MESSAGE. - LD BC,BDOSERR ; AND PRINT IT. - CALL PRTMESG - POP BC ; PRINT SECOND MESSAGE LINE NOW. - CALL PRTMESG -; -; GET AN INPUT CHARACTER. WE WILL CHECK OUR 1 CHARACTER -; BUFFER FIRST. THIS MAY BE SET BY THE CONSOLE STATUS ROUTINE. -; -GETCHAR:LD HL,CHARBUF ; CHECK CHARACTER BUFFER. - LD A,(HL) ; ANYTHING PRESENT ALREADY? - LD (HL),0 ; ...EITHER CASE CLEAR IT. - OR A - RET NZ ; YES, USE IT. - JP CONIN ; NOPE, GO GET A CHARACTER RESPONCE. -; -; INPUT AND ECHO A CHARACTER. -; -GETECHO:CALL GETCHAR ; INPUT A CHARACTER. - CALL CHKCHAR ; CARRIAGE CONTROL? - RET C ; NO, A REGULAR CONTROL CHAR SO DON'T ECHO. - PUSH AF ; OK, SAVE CHARACTER NOW. - LD C,A - CALL OUTCON ; AND ECHO IT. - POP AF ; GET CHARACTER AND RETURN. - RET -; -; CHECK CHARACTER IN (A). SET THE ZERO FLAG ON A CARRIAGE -; CONTROL CHARACTER AND THE CARRY FLAG ON ANY OTHER CONTROL -; CHARACTER. -; -CHKCHAR:CP CR ; CHECK FOR CARRIAGE RETURN, LINE FEED, BACKSPACE, - RET Z ; OR A TAB. - CP LF - RET Z - CP TAB - RET Z - CP BS - RET Z - CP ' ' ; OTHER CONTROL CHAR? SET CARRY FLAG. - RET -; -; CHECK THE CONSOLE DURING OUTPUT. HALT ON A CONTROL-S, THEN -; REBOOT ON A CONTROL-C. IF ANYTHING ELSE IS READY, CLEAR THE -; ZERO FLAG AND RETURN (THE CALLING ROUTINE MAY WANT TO DO -; SOMETHING). -; -CKCONSOL: - LD A,(CHARBUF) ; CHECK BUFFER. - OR A ; IF ANYTHING, JUST RETURN WITHOUT CHECKING. - JP NZ,CKCON2 - CALL CONST ; NOTHING IN BUFFER. CHECK CONSOLE. - AND 01H ; LOOK AT BIT 0. - RET Z ; RETURN IF NOTHING. - CALL CONIN ; OK, GET IT. - CP CNTRLS ; IF NOT CONTROL-S, RETURN WITH ZERO CLEARED. - JP NZ,CKCON1 - CALL CONIN ; HALT PROCESSING UNTIL ANOTHER CHAR - CP CNTRLC ; IS TYPED. CONTROL-C? - JP Z,0 ; YES, REBOOT NOW. - XOR A ; NO, JUST PRETEND NOTHING WAS EVER READY. - RET -CKCON1: LD (CHARBUF),A ; SAVE CHARACTER IN BUFFER FOR LATER PROCESSING. -CKCON2: LD A,1 ; SET (A) TO NON ZERO TO MEAN SOMETHING IS READY. - RET -; -; OUTPUT (C) TO THE SCREEN. IF THE PRINTER FLIP-FLOP FLAG -; IS SET, WE WILL SEND CHARACTER TO PRINTER ALSO. THE CONSOLE -; WILL BE CHECKED IN THE PROCESS. -; -OUTCHAR:LD A,(OUTFLAG) ; CHECK OUTPUT FLAG. - OR A ; ANYTHING AND WE WON'T GENERATE OUTPUT. - JP NZ,OUTCHR1 - PUSH BC - CALL CKCONSOL ; CHECK CONSOLE (WE DON'T CARE WHATS THERE). - POP BC - PUSH BC - CALL CONOUT ; OUTPUT (C) TO THE SCREEN. - POP BC - PUSH BC - LD A,(PRTFLAG) ; CHECK PRINTER FLIP-FLOP FLAG. - OR A - CALL NZ,LIST ; PRINT IT ALSO IF NON-ZERO. - POP BC -OUTCHR1:LD A,C ; UPDATE CURSORS POSITION. - LD HL,CURPOS - CP DEL ; RUBOUTS DON'T DO ANYTHING HERE. - RET Z - INC (HL) ; BUMP LINE POINTER. - CP ' ' ; AND RETURN IF A NORMAL CHARACTER. - RET NC - DEC (HL) ; RESTORE AND CHECK FOR THE START OF THE LINE. - LD A,(HL) - OR A - RET Z ; INGNORE CONTROL CHARACTERS AT THE START OF THE LINE. - LD A,C - CP BS ; IS IT A BACKSPACE? - JP NZ,OUTCHR2 - DEC (HL) ; YES, BACKUP POINTER. - RET -OUTCHR2:CP LF ; IS IT A LINE FEED? - RET NZ ; IGNORE ANYTHING ELSE. - LD (HL),0 ; RESET POINTER TO START OF LINE. - RET -; -; OUTPUT (A) TO THE SCREEN. IF IT IS A CONTROL CHARACTER -; (OTHER THAN CARRIAGE CONTROL), USE ^X FORMAT. -; -SHOWIT: LD A,C - CALL CHKCHAR ; CHECK CHARACTER. - JP NC,OUTCON ; NOT A CONTROL, USE NORMAL OUTPUT. - PUSH AF - LD C,'^' ; FOR A CONTROL CHARACTER, PRECEED IT WITH '^'. - CALL OUTCHAR - POP AF - OR '@' ; AND THEN USE THE LETTER .EQUIVELANT. - LD C,A -; -; FUNCTION TO OUTPUT (C) TO THE CONSOLE DEVICE AND EXPAND TABS -; IF NECESSARY. -; -OUTCON: LD A,C - CP TAB ; IS IT A TAB? - JP NZ,OUTCHAR ; USE REGULAR OUTPUT. -OUTCON1:LD C,' ' ; YES IT IS, USE SPACES INSTEAD. - CALL OUTCHAR - LD A,(CURPOS) ; GO UNTIL THE CURSOR IS AT A MULTIPLE OF 8 - - AND 07H ; POSITION. - JP NZ,OUTCON1 - RET -; -; ECHO A BACKSPACE CHARACTER. ERASE THE PREVOIUS CHARACTER -; ON THE SCREEN. -; -BACKUP: CALL BACKUP1 ; BACKUP THE SCREEN 1 PLACE. - LD C,' ' ; THEN BLANK THAT CHARACTER. - CALL CONOUT -BACKUP1:LD C,BS ; THEN BACK SPACE ONCE MORE. - JP CONOUT -; -; SIGNAL A DELETED LINE. PRINT A '#' AT THE END AND START -; OVER. -; -NEWLINE:LD C,'#' - CALL OUTCHAR ; PRINT THIS. - CALL OUTCRLF ; START NEW LINE. -NEWLN1: LD A,(CURPOS) ; MOVE THE CURSOR TO THE STARTING POSITION. - LD HL,STARTING - CP (HL) - RET NC ; THERE YET? - LD C,' ' - CALL OUTCHAR ; NOPE, KEEP GOING. - JP NEWLN1 -; -; OUTPUT A (CR) (LF) TO THE CONSOLE DEVICE (SCREEN). -; -OUTCRLF:LD C,CR - CALL OUTCHAR - LD C,LF - JP OUTCHAR -; -; PRINT MESSAGE POINTED TO BY (BC). IT WILL END WITH A '$'. -; -PRTMESG:LD A,(BC) ; CHECK FOR TERMINATING CHARACTER. - CP '$' - RET Z - INC BC - PUSH BC ; OTHERWISE, BUMP POINTER AND PRINT IT. - LD C,A - CALL OUTCON - POP BC - JP PRTMESG -; -; FUNCTION TO EXECUTE A BUFFERED READ. -; -R.DBUFF: LD A,(CURPOS) ; USE PRESENT LOCATION AS STARTING ONE. - LD (STARTING),A - LD HL,(PARAMS) ; GET THE MAXIMUM BUFFER SPACE. - LD C,(HL) - INC HL ; POINT TO FIRST AVAILABLE SPACE. - PUSH HL ; AND SAVE. - LD B,0 ; KEEP A CHARACTER COUNT. -R.DBUF1: PUSH BC - PUSH HL -R.DBUF2: CALL GETCHAR ; GET THE NEXT INPUT CHARACTER. - AND 7FH ; STRIP BIT 7. - POP HL ; RESET REGISTERS. - POP BC - CP CR ; EN OF THE LINE? - JP Z,R.DBUF17 - CP LF - JP Z,R.DBUF17 - CP BS ; HOW ABOUT A BACKSPACE? - JP NZ,R.DBUF3 - LD A,B ; YES, BUT IGNORE AT THE BEGINNING OF THE LINE. - OR A - JP Z,R.DBUF1 - DEC B ; OK, UPDATE COUNTER. - LD A,(CURPOS) ; IF WE BACKSPACE TO THE START OF THE LINE, - LD (OUTFLAG),A ; TREAT AS A CANCEL (CONTROL-X). - JP R.DBUF10 -R.DBUF3: CP DEL ; USER TYPED A RUBOUT? - JP NZ,R.DBUF4 - LD A,B ; IGNORE AT THE START OF THE LINE. - OR A - JP Z,R.DBUF1 - LD A,(HL) ; OK, ECHO THE PREVOIUS CHARACTER. - DEC B ; AND RESET POINTERS (COUNTERS). - DEC HL - JP R.DBUF15 -R.DBUF4: CP CNTRLE ; PHYSICAL END OF LINE? - JP NZ,R.DBUF5 - PUSH BC ; YES, DO IT. - PUSH HL - CALL OUTCRLF - XOR A ; AND UPDATE STARTING POSITION. - LD (STARTING),A - JP R.DBUF2 -R.DBUF5: CP CNTRLP ; CONTROL-P? - JP NZ,R.DBUF6 - PUSH HL ; YES, FLIP THE PRINT FLAG FILP-FLOP BYTE. - LD HL,PRTFLAG - LD A,1 ; PRTFLAG=1-PRTFLAG - SUB (HL) - LD (HL),A - POP HL - JP R.DBUF1 -R.DBUF6: CP CNTRLX ; CONTROL-X (CANCEL)? - JP NZ,R.DBUF8 - POP HL -R.DBUF7: LD A,(STARTING) ; YES, BACKUP THE CURSOR TO HERE. - LD HL,CURPOS - CP (HL) - JP NC,R.DBUFF ; DONE YET? - DEC (HL) ; NO, DECREMENT POINTER AND OUTPUT BACK UP ONE SPACE. - CALL BACKUP - JP R.DBUF7 -R.DBUF8: CP CNTRLU ; CNTROL-U (CANCEL LINE)? - JP NZ,R.DBUF9 - CALL NEWLINE ; START A NEW LINE. - POP HL - JP R.DBUFF -R.DBUF9: CP CNTRLR ; CONTROL-R? - JP NZ,R.DBUF14 -R.DBUF10:PUSH BC ; YES, START A NEW LINE AND RETYPE THE OLD ONE. - CALL NEWLINE - POP BC - POP HL - PUSH HL - PUSH BC -R.DBUF11:LD A,B ; DONE WHOLE LINE YET? - OR A - JP Z,R.DBUF12 - INC HL ; NOPE, GET NEXT CHARACTER. - LD C,(HL) - DEC B ; COUNT IT. - PUSH BC - PUSH HL - CALL SHOWIT ; AND DISPLAY IT. - POP HL - POP BC - JP R.DBUF11 -R.DBUF12:PUSH HL ; DONE WITH LINE. IF WE WERE DISPLAYING - LD A,(OUTFLAG) ; THEN UPDATE CURSOR POSITION. - OR A - JP Z,R.DBUF2 - LD HL,CURPOS ; BECAUSE THIS LINE IS SHORTER, WE MUST - SUB (HL) ; BACK UP THE CURSOR (NOT THE SCREEN HOWEVER) - LD (OUTFLAG),A ; SOME NUMBER OF POSITIONS. -R.DBUF13:CALL BACKUP ; NOTE THAT AS LONG AS (OUTFLAG) IS NON - LD HL,OUTFLAG ; ZERO, THE SCREEN WILL NOT BE CHANGED. - DEC (HL) - JP NZ,R.DBUF13 - JP R.DBUF2 ; NOW JUST GET THE NEXT CHARACTER. -; -; JUST A NORMAL CHARACTER, PUT THIS IN OUR BUFFER AND ECHO. -; -R.DBUF14:INC HL - LD (HL),A ; STORE CHARACTER. - INC B ; AND COUNT IT. -R.DBUF15:PUSH BC - PUSH HL - LD C,A ; ECHO IT NOW. - CALL SHOWIT - POP HL - POP BC - LD A,(HL) ; WAS IT AN ABORT REQUEST? - CP CNTRLC ; CONTROL-C ABORT? - LD A,B - JP NZ,R.DBUF16 - CP 1 ; ONLY IF AT START OF LINE. - JP Z,0 -R.DBUF16:CP C ; NOPE, HAVE WE FILLED THE BUFFER? - JP C,R.DBUF1 -R.DBUF17:POP HL ; YES END THE LINE AND RETURN. - LD (HL),B - LD C,CR - JP OUTCHAR ; OUTPUT (CR) AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE CONSOLE DEVICE. -; -GETCON: CALL GETECHO ; GET AND ECHO. - JP SETSTAT ; SAVE STATUS AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE TAPE READER DEVICE. -; -GETRDR: CALL READER ; GET A CHARACTER FROM READER, SET STATUS AND RETURN. - JP SETSTAT -; -; FUNCTION TO PERFORM DIRECT CONSOLE I/O. IF (C) CONTAINS (FF) -; THEN THIS IS AN INPUT REQUEST. IF (C) CONTAINS (FE) THEN -; THIS IS A STATUS REQUEST. OTHERWISE WE ARE TO OUTPUT (C). -; -DIRCIO: LD A,C ; TEST FOR (FF). - INC A - JP Z,DIRC1 - INC A ; TEST FOR (FE). - JP Z,CONST - JP CONOUT ; JUST OUTPUT (C). -DIRC1: CALL CONST ; THIS IS AN INPUT REQUEST. - OR A - JP Z,GOBACK1 ; NOT READY? JUST RETURN (DIRECTLY). - CALL CONIN ; YES, GET CHARACTER. - JP SETSTAT ; SET STATUS AND RETURN. -; -; FUNCTION TO RETURN THE I/O BYTE. -; -GETIOB: LD A,(IOBYTE) - JP SETSTAT -; -; FUNCTION TO SET THE I/O BYTE. -; -SETIOB: LD HL,IOBYTE - LD (HL),C - RET -; -; FUNCTION TO PRINT THE CHARACTER STRING POINTED TO BY (DE) -; ON THE CONSOLE DEVICE. THE STRING ENDS WITH A '$'. -; -PRTSTR: EX DE,HL - LD C,L - LD B,H ; NOW (BC) POINTS TO IT. - JP PRTMESG -; -; FUNCTION TO INTERIGATE THE CONSOLE DEVICE. -; -GETCSTS:CALL CKCONSOL -; -; GET HERE TO SET THE STATUS AND RETURN TO THE CLEANUP -; SECTION. THEN BACK TO THE USER. -; -SETSTAT:LD (STATUS),A -RTN: RET -; -; SET THE STATUS TO 1 (READ OR WRITE ERROR CODE). -; -IOERR1: LD A,1 - JP SETSTAT -; -OUTFLAG:.DB 0 ; OUTPUT FLAG (NON ZERO MEANS NO OUTPUT). -STARTING: - .DB 2 ; STARTING POSITION FOR CURSOR. -CURPOS: .DB 0 ; CURSOR POSITION (0=START OF LINE). -PRTFLAG:.DB 0 ; PRINTER FLAG (CONTROL-P TOGGLE). LIST IF NON ZERO. -CHARBUF:.DB 0 ; SINGLE INPUT CHARACTER BUFFER. -; -; STACK AREA FOR BDOS CALLS. -; -USRSTACK: - .DW 0 ; SAVE USERS STACK POINTER HERE. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA:.EQU $ ; END OF STACK AREA. -; -USERNO: .DB 0 ; CURRENT USER NUMBER. -ACTIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -PARAMS: .DW 0 ; SAVE (DE) PARAMETERS HERE ON ENTRY. -STATUS: .DW 0 ; STATUS RETURNED FROM BDOS FUNCTION. -; -; SELECT ERROR OCCURED, JUMP TO ERROR ROUTINE. -; -SLCTERR:LD HL,BADSLCT -; -; JUMP TO (HL) INDIRECTLY. -; -JUMPHL: LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE) CONTAIN THE DESIRED ADDRESS. - EX DE,HL - JP (HL) -; -; BLOCK MOVE. (DE) TO (HL), (C) BYTES TOTAL. -; -DE2HL: INC C ; IS COUNT DOWN TO ZERO? -DE2HL1: DEC C - RET Z ; YES, WE ARE DONE. - LD A,(DE) ; NO, MOVE ONE MORE BYTE. - LD (HL),A - INC DE - INC HL - JP DE2HL1 ; AND REPEAT. -; -; SELECT THE DESIRED DRIVE. -; -SELECT: LD A,(ACTIVE) ; GET ACTIVE DISK. - LD C,A - CALL SELDSK ; SELECT IT. - LD A,H ; VALID DRIVE? - OR L ; VALID DRIVE? - RET Z ; RETURN IF NOT. -; -; HERE, THE BIOS RETURNED THE ADDRESS OF THE PARAMETER BLOCK -; IN (HL). WE WILL EXTRACT THE NECESSARY POINTERS AND SAVE THEM. -; - LD E,(HL) ; YES, GET ADDRESS OF TRANSLATION TABLE INTO (DE). - INC HL - LD D,(HL) - INC HL - LD (SCRATCH1),HL ; SAVE POINTERS TO SCRATCH AREAS. - INC HL - INC HL - LD (SCRATCH2),HL ; DITTO. - INC HL - INC HL - LD (SCRATCH3),HL ; DITTO. - INC HL - INC HL - EX DE,HL ; NOW SAVE THE TRANSLATION TABLE ADDRESS. - LD (XLATE),HL - LD HL,DIRBUF ; PUT THE NEXT 8 BYTES HERE. - LD C,8 ; THEY CONSIST OF THE DIRECTORY BUFFER - CALL DE2HL ; POINTER, PARAMETER BLOCK POINTER, - LD HL,(DISKPB) ; CHECK AND ALLOCATION VECTORS. - EX DE,HL - LD HL,SECTORS ; MOVE PARAMETER BLOCK INTO OUR RAM. - LD C,15 ; IT IS 15 BYTES LONG. - CALL DE2HL - LD HL,(DSKSIZE) ; CHECK DISK SIZE. - LD A,H ; MORE THAN 256 BLOCKS ON THIS? - LD HL,BIGDISK - LD (HL),0FFH ; SET TO SAMLL. - OR A - JP Z,SELECT1 - LD (HL),0 ; WRONG, SET TO LARGE. -SELECT1:LD A,0FFH ; CLEAR THE ZERO FLAG. - OR A - RET -; -; ROUTINE TO HOME THE DISK TRACK HEAD AND CLEAR POINTERS. -; -HOMEDRV:CALL HOME ; HOME THE HEAD. - XOR A - LD HL,(SCRATCH2) ; SET OUR TRACK POINTER ALSO. - LD (HL),A - INC HL - LD (HL),A - LD HL,(SCRATCH3) ; AND OUR SECTOR POINTER. - LD (HL),A - INC HL - LD (HL),A - RET -; -; DO THE ACTUAL DISK READ AND CHECK THE ERROR RETURN STATUS. -; -DOREAD: CALL READ - JP IORET -; -; DO THE ACTUAL DISK WRITE AND HANDLE ANY BIOS ERROR. -; -DOWRITE:CALL WRITE -IORET: OR A - RET Z ; RETURN UNLESS AN ERROR OCCURED. - LD HL,BADSCTR ; BAD READ/WRITE ON THIS SECTOR. - JP JUMPHL -; -; ROUTINE TO SELECT THE TRACK AND SECTOR THAT THE DESIRED -; BLOCK NUMBER FALLS IN. -; -TRKSEC: LD HL,(FILEPOS) ; GET POSITION OF LAST ACCESSED FILE - LD C,2 ; IN DIRECTORY AND COMPUTE SECTOR #. - CALL SHIFTR ; SECTOR #=FILE-POSITION/4. - LD (BLKNMBR),HL ; SAVE THIS AS THE BLOCK NUMBER OF INTEREST. - LD (CKSUMTBL),HL ; WHAT'S IT DOING HERE TOO? -; -; IF THE SECTOR NUMBER HAS ALREADY BEEN SET (BLKNMBR), ENTER -; AT THIS POINT. -; -TRKSEC1:LD HL,BLKNMBR - LD C,(HL) ; MOVE SECTOR NUMBER INTO (BC). - INC HL - LD B,(HL) - LD HL,(SCRATCH3) ; GET CURRENT SECTOR NUMBER AND - LD E,(HL) ; MOVE THIS INTO (DE). - INC HL - LD D,(HL) - LD HL,(SCRATCH2) ; GET CURRENT TRACK NUMBER. - LD A,(HL) ; AND THIS INTO (HL). - INC HL - LD H,(HL) - LD L,A -TRKSEC2:LD A,C ; IS DESIRED SECTOR BEFORE CURRENT ONE? - SUB E - LD A,B - SBC A,D - JP NC,TRKSEC3 - PUSH HL ; YES, DECREMENT SECTORS BY ONE TRACK. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - LD A,E - SUB L - LD E,A - LD A,D - SBC A,H - LD D,A ; NOW WE HAVE BACKED UP ONE FULL TRACK. - POP HL - DEC HL ; ADJUST TRACK COUNTER. - JP TRKSEC2 -TRKSEC3:PUSH HL ; DESIRED SECTOR IS AFTER CURRENT ONE. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - ADD HL,DE ; BUMP SECTOR POINTER TO NEXT TRACK. - JP C,TRKSEC4 - LD A,C ; IS DESIRED SECTOR NOW BEFORE CURRENT ONE? - SUB L - LD A,B - SBC A,H - JP C,TRKSEC4 - EX DE,HL ; NOT YES, INCREMENT TRACK COUNTER - POP HL ; AND CONTINUE UNTIL IT IS. - INC HL - JP TRKSEC3 -; -; HERE WE HAVE DETERMINED THE TRACK NUMBER THAT CONTAINS THE -; DESIRED SECTOR. -; -TRKSEC4:POP HL ; GET TRACK NUMBER (HL). - PUSH BC - PUSH DE - PUSH HL - EX DE,HL - LD HL,(OFFSET) ; ADJUST FOR FIRST TRACK OFFSET. - ADD HL,DE - LD B,H - LD C,L - CALL SETTRK ; SELECT THIS TRACK. - POP DE ; RESET CURRENT TRACK POINTER. - LD HL,(SCRATCH2) - LD (HL),E - INC HL - LD (HL),D - POP DE - LD HL,(SCRATCH3) ; RESET THE FIRST SECTOR ON THIS TRACK. - LD (HL),E - INC HL - LD (HL),D - POP BC - LD A,C ; NOW SUBTRACT THE DESIRED ONE. - SUB E ; TO MAKE IT RELATIVE (1-# SECTORS/TRACK). - LD C,A - LD A,B - SBC A,D - LD B,A - LD HL,(XLATE) ; TRANSLATE THIS SECTOR ACCORDING TO THIS TABLE. - EX DE,HL - CALL SECTRN ; LET THE BIOS TRANSLATE IT. - LD C,L - LD B,H - JP SETSEC ; AND SELECT IT. -; -; COMPUTE BLOCK NUMBER FROM RECORD NUMBER (SAVNREC) AND -; EXTENT NUMBER (SAVEXT). -; -GETBLOCK: - LD HL,BLKSHFT ; GET LOGICAL TO PHYSICAL CONVERSION. - LD C,(HL) ; NOTE THAT THIS IS BASE 2 LOG OF RATIO. - LD A,(SAVNREC) ; GET RECORD NUMBER. -GETBLK1:OR A ; COMPUTE (A)=(A)/2^BLKSHFT. - RRA - DEC C - JP NZ,GETBLK1 - LD B,A ; SAVE RESULT IN (B). - LD A,8 - SUB (HL) - LD C,A ; COMPUTE (C)=8-BLKSHFT. - LD A,(SAVEXT) -GETBLK2:DEC C ; COMPUTE (A)=SAVEXT*2^(8-BLKSHFT). - JP Z,GETBLK3 - OR A - RLA - JP GETBLK2 -GETBLK3:ADD A,B - RET -; -; ROUTINE TO EXTRACT THE (BC) BLOCK BYTE FROM THE FCB POINTED -; TO BY (PARAMS). IF THIS IS A BIG-DISK, THEN THESE ARE 16 BIT -; BLOCK NUMBERS, ELSE THEY ARE 8 BIT NUMBERS. -; NUMBER IS RETURNED IN (HL). -; -EXTBLK: LD HL,(PARAMS) ; GET FCB ADDRESS. - LD DE,16 ; BLOCK NUMBERS START 16 BYTES INTO FCB. - ADD HL,DE - ADD HL,BC - LD A,(BIGDISK) ; ARE WE USING A BIG-DISK? - OR A - JP Z,EXTBLK1 - LD L,(HL) ; NO, EXTRACT AN 8 BIT NUMBER FROM THE FCB. - LD H,0 - RET -EXTBLK1:ADD HL,BC ; YES, EXTRACT A 16 BIT NUMBER. - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ; RETURN IN (HL). - RET -; -; COMPUTE BLOCK NUMBER. -; -COMBLK: CALL GETBLOCK - LD C,A - LD B,0 - CALL EXTBLK - LD (BLKNMBR),HL - RET -; -; CHECK FOR A ZERO BLOCK NUMBER (UNUSED). -; -CHKBLK: LD HL,(BLKNMBR) - LD A,L ; IS IT ZERO? - OR H - RET -; -; ADJUST PHYSICAL BLOCK (BLKNMBR) AND CONVERT TO LOGICAL -; SECTOR (LOGSECT). THIS IS THE STARTING SECTOR OF THIS BLOCK. -; THE ACTUAL SECTOR OF INTEREST IS THEN ADDED TO THIS AND THE -; RESULTING SECTOR NUMBER IS STORED BACK IN (BLKNMBR). THIS -; WILL STILL HAVE TO BE ADJUSTED FOR THE TRACK NUMBER. -; -LOGICAL:LD A,(BLKSHFT) ; GET LOG2(PHYSICAL/LOGICAL SECTORS). - LD HL,(BLKNMBR) ; GET PHYSICAL SECTOR DESIRED. -LOGICL1:ADD HL,HL ; COMPUTE LOGICAL SECTOR NUMBER. - DEC A ; NOTE LOGICAL SECTORS ARE 128 BYTES LONG. - JP NZ,LOGICL1 - LD (LOGSECT),HL ; SAVE LOGICAL SECTOR. - LD A,(BLKMASK) ; GET BLOCK MASK. - LD C,A - LD A,(SAVNREC) ; GET NEXT SECTOR TO ACCESS. - AND C ; EXTRACT THE RELATIVE POSITION WITHIN PHYSICAL BLOCK. - OR L ; AND ADD IT TOO LOGICAL SECTOR. - LD L,A - LD (BLKNMBR),HL ; AND STORE. - RET -; -; SET (HL) TO POINT TO EXTENT BYTE IN FCB. -; -SETEXT: LD HL,(PARAMS) - LD DE,12 ; IT IS THE TWELTH BYTE. - ADD HL,DE - RET -; -; SET (HL) TO POINT TO RECORD COUNT BYTE IN FCB AND (DE) TO -; NEXT RECORD NUMBER BYTE. -; -SETHLDE:LD HL,(PARAMS) - LD DE,15 ; RECORD COUNT BYTE (#15). - ADD HL,DE - EX DE,HL - LD HL,17 ; NEXT RECORD NUMBER (#32). - ADD HL,DE - RET -; -; SAVE CURRENT FILE DATA FROM FCB. -; -STRDATA:CALL SETHLDE - LD A,(HL) ; GET AND STORE RECORD COUNT BYTE. - LD (SAVNREC),A - EX DE,HL - LD A,(HL) ; GET AND STORE NEXT RECORD NUMBER BYTE. - LD (SAVNXT),A - CALL SETEXT ; POINT TO EXTENT BYTE. - LD A,(EXTMASK) ; GET EXTENT MASK. - AND (HL) - LD (SAVEXT),A ; AND SAVE EXTENT HERE. - RET -; -; SET THE NEXT RECORD TO ACCESS. IF (MODE) IS SET TO 2, THEN -; THE LAST RECORD BYTE (SAVNREC) HAS THE CORRECT NUMBER TO ACCESS. -; FOR S.EQUENTIAL ACCESS, (MODE) WILL BE .EQUAL TO 1. -; -SETNREC:CALL SETHLDE - LD A,(MODE) ; GET S.EQUENTIAL FLAG (=1). - CP 2 ; A 2 INDICATES THAT NO ADDER IS NEEDED. - JP NZ,STNREC1 - XOR A ; CLEAR ADDER (RANDOM ACCESS?). -STNREC1:LD C,A - LD A,(SAVNREC) ; GET LAST RECORD NUMBER. - ADD A,C ; INCREMENT RECORD COUNT. - LD (HL),A ; AND SET FCB'S NEXT RECORD BYTE. - EX DE,HL - LD A,(SAVNXT) ; GET NEXT RECORD BYTE FROM STORAGE. - LD (HL),A ; AND PUT THIS INTO FCB AS NUMBER OF RECORDS USED. - RET -; -; SHIFT (HL) RIGHT (C) BITS. -; -SHIFTR: INC C -SHIFTR1:DEC C - RET Z - LD A,H - OR A - RRA - LD H,A - LD A,L - RRA - LD L,A - JP SHIFTR1 -; -; COMPUTE THE CHECK-SUM FOR THE DIRECTORY BUFFER. RETURN -; INTEGER SUM IN (A). -; -CHECKSUM: - LD C,128 ; LENGTH OF BUFFER. - LD HL,(DIRBUF) ; GET ITS LOCATION. - XOR A ; CLEAR SUMMATION BYTE. -CHKSUM1:ADD A,(HL) ; AND COMPUTE SUM IGNORING CARRIES. - INC HL - DEC C - JP NZ,CHKSUM1 - RET -; -; SHIFT (HL) LEFT (C) BITS. -; -SHIFTL: INC C -SHIFTL1:DEC C - RET Z - ADD HL,HL ; SHIFT LEFT 1 BIT. - JP SHIFTL1 -; -; ROUTINE TO SET A BIT IN A 16 BIT VALUE CONTAINED IN (BC). -; THE BIT SET DEPENDS ON THE CURRENT DRIVE SELECTION. -; -SETBIT: PUSH BC ; SAVE 16 BIT WORD. - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - LD C,A - LD HL,1 - CALL SHIFTL ; SHIFT BIT 0 INTO PLACE. - POP BC ; NOW 'OR' THIS WITH THE ORIGINAL WORD. - LD A,C - OR L - LD L,A ; LOW BYTE DONE, DO HIGH BYTE. - LD A,B - OR H - LD H,A - RET -; -; EXTRACT THE WRITE PROTECT STATUS BIT FOR THE CURRENT DRIVE. -; THE RESULT IS RETURNED IN (A), BIT 0. -; -GETWPRT:LD HL,(WRTPRT) ; GET STATUS BYTES. - LD A,(ACTIVE) ; WHICH DRIVE IS CURRENT? - LD C,A - CALL SHIFTR ; SHIFT STATUS SUCH THAT BIT 0 IS THE - LD A,L ; ONE OF INTEREST FOR THIS DRIVE. - AND 01H ; AND ISOLATE IT. - RET -; -; FUNCTION TO WRITE PROTECT THE CURRENT DISK. -; -WRTPRTD:LD HL,WRTPRT ; POINT TO STATUS WORD. - LD C,(HL) ; SET (BC) .EQUAL TO THE STATUS. - INC HL - LD B,(HL) - CALL SETBIT ; AND SET THIS BIT ACCORDING TO CURRENT DRIVE. - LD (WRTPRT),HL ; THEN SAVE. - LD HL,(DIRSIZE) ; NOW SAVE DIRECTORY SIZE LIMIT. - INC HL ; REMEMBER THE LAST ONE. - EX DE,HL - LD HL,(SCRATCH1) ; AND STORE IT HERE. - LD (HL),E ; PUT LOW BYTE. - INC HL - LD (HL),D ; THEN HIGH BYTE. - RET -; -; CHECK FOR A READ ONLY FILE. -; -CHKROFL:CALL FCB2HL ; SET (HL) TO FILE ENTRY IN DIRECTORY BUFFER. -CKROF1: LD DE,9 ; LOOK AT BIT 7 OF THE NINTH BYTE. - ADD HL,DE - LD A,(HL) - RLA - RET NC ; RETURN IF OK. - LD HL,ROFILE ; ELSE, PRINT ERROR MESSAGE AND TERMINATE. - JP JUMPHL -; -; CHECK THE WRITE PROTECT STATUS OF THE ACTIVE DISK. -; -CHKWPRT:CALL GETWPRT - RET Z ; RETURN IF OK. - LD HL,RODISK ; ELSE PRINT MESSAGE AND TERMINATE. - JP JUMPHL -; -; ROUTINE TO SET (HL) POINTING TO THE PROPER ENTRY IN THE -; DIRECTORY BUFFER. -; -FCB2HL: LD HL,(DIRBUF) ; GET ADDRESS OF BUFFER. - LD A,(FCBPOS) ; RELATIVE POSITION OF FILE. -; -; ROUTINE TO ADD (A) TO (HL). -; -ADDA2HL:ADD A,L - LD L,A - RET NC - INC H ; TAKE CARE OF ANY CARRY. - RET -; -; ROUTINE TO GET THE 'S2' BYTE FROM THE FCB SUPPLIED IN -; THE INITIAL PARAMETER SPECIFICATION. -; -GETS2: LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD DE,14 ; RELATIVE POSITION OF 'S2'. - ADD HL,DE - LD A,(HL) ; EXTRACT THIS BYTE. - RET -; -; CLEAR THE 'S2' BYTE IN THE FCB. -; -CLEARS2:CALL GETS2 ; THIS SETS (HL) POINTING TO IT. - LD (HL),0 ; NOW CLEAR IT. - RET -; -; SET BIT 7 IN THE 'S2' BYTE OF THE FCB. -; -SETS2B7:CALL GETS2 ; GET THE BYTE. - OR 80H ; AND SET BIT 7. - LD (HL),A ; THEN STORE. - RET -; -; COMPARE (FILEPOS) WITH (SCRATCH1) AND SET FLAGS BASED ON -; THE DIFFERENCE. THIS CHECKS TO SEE IF THERE ARE MORE FILE -; NAMES IN THE DIRECTORY. WE ARE AT (FILEPOS) AND THERE ARE -; (SCRATCH1) OF THEM TO CHECK. -; -MOREFLS:LD HL,(FILEPOS) ; WE ARE HERE. - EX DE,HL - LD HL,(SCRATCH1) ; AND DON'T GO PAST HERE. - LD A,E ; COMPUTE DIFFERENCE BUT DON'T KEEP. - SUB (HL) - INC HL - LD A,D - SBC A,(HL) ; SET CARRY IF NO MORE NAMES. - RET -; -; CALL THIS ROUTINE TO PREVENT (SCRATCH1) FROM BEING GREATER -; THAN (FILEPOS). -; -CHKNMBR:CALL MOREFLS ; SCRATCH1 TOO BIG? - RET C - INC DE ; YES, RESET IT TO (FILEPOS). - LD (HL),D - DEC HL - LD (HL),E - RET -; -; COMPUTE (HL)=(DE)-(HL) -; -SUBHL: LD A,E ; COMPUTE DIFFERENCE. - SUB L - LD L,A ; STORE LOW BYTE. - LD A,D - SBC A,H - LD H,A ; AND THEN HIGH BYTE. - RET -; -; SET THE DIRECTORY CHECKSUM BYTE. -; -SETDIR: LD C,0FFH -; -; ROUTINE TO SET OR COMPARE THE DIRECTORY CHECKSUM BYTE. IF -; (C)=0FFH, THEN THIS WILL SET THE CHECKSUM BYTE. ELSE THE BYTE -; WILL BE CHECKED. IF THE CHECK FAILS (THE DISK HAS BEEN CHANGED), -; THEN THIS DISK WILL BE WRITE PROTECTED. -; -CHECKDIR: - LD HL,(CKSUMTBL) - EX DE,HL - LD HL,(ALLOC1) - CALL SUBHL - RET NC ; OK IF (CKSUMTBL) > (ALLOC1), SO RETURN. - PUSH BC - CALL CHECKSUM ; ELSE COMPUTE CHECKSUM. - LD HL,(CHKVECT) ; GET ADDRESS OF CHECKSUM TABLE. - EX DE,HL - LD HL,(CKSUMTBL) - ADD HL,DE ; SET (HL) TO POINT TO BYTE FOR THIS DRIVE. - POP BC - INC C ; SET OR CHECK ? - JP Z,CHKDIR1 - CP (HL) ; CHECK THEM. - RET Z ; RETURN IF THEY ARE THE SAME. - CALL MOREFLS ; NOT THE SAME, DO WE CARE? - RET NC - CALL WRTPRTD ; YES, MARK THIS AS WRITE PROTECTED. - RET -CHKDIR1:LD (HL),A ; JUST SET THE BYTE. - RET -; -; DO A WRITE TO THE DIRECTORY OF THE CURRENT DISK. -; -DIRWRITE: - CALL SETDIR ; SET CHECKSUM BYTE. - CALL DIRDMA ; SET DIRECTORY DMA ADDRESS. - LD C,1 ; TELL THE BIOS TO ACTUALLY WRITE. - CALL DOWRITE ; THEN DO THE WRITE. - JP DEFDMA -; -; READ FROM THE DIRECTORY. -; -DIRREAD:CALL DIRDMA ; SET THE DIRECTORY DMA ADDRESS. - CALL DOREAD ; AND READ IT. -; -; ROUTINE TO SET THE DMA ADDRESS TO THE USERS CHOICE. -; -DEFDMA: LD HL,USERDMA ; RESET THE DEFAULT DMA ADDRESS AND RETURN. - JP DIRDMA1 -; -; ROUTINE TO SET THE DMA ADDRESS FOR DIRECTORY WORK. -; -DIRDMA: LD HL,DIRBUF -; -; SET THE DMA ADDRESS. ON ENTRY, (HL) POINTS TO -; WORD CONTAINING THE DESIRED DMA ADDRESS. -; -DIRDMA1:LD C,(HL) - INC HL - LD B,(HL) ; SETUP (BC) AND GO TO THE BIOS TO SET IT. - JP SETDMA -; -; MOVE THE DIRECTORY BUFFER INTO USER'S DMA SPACE. -; -MOVEDIR:LD HL,(DIRBUF) ; BUFFER IS LOCATED HERE, AND - EX DE,HL - LD HL,(USERDMA) ; PUT IT HERE. - LD C,128 ; THIS IS ITS LENGTH. - JP DE2HL ; MOVE IT NOW AND RETURN. -; -; CHECK (FILEPOS) AND SET THE ZERO FLAG IF IT .EQUALS 0FFFFH. -; -CKFILPOS: - LD HL,FILEPOS - LD A,(HL) - INC HL - CP (HL) ; ARE BOTH BYTES THE SAME? - RET NZ - INC A ; YES, BUT ARE THEY EACH 0FFH? - RET -; -; SET LOCATION (FILEPOS) TO 0FFFFH. -; -STFILPOS: - LD HL,0FFFFH - LD (FILEPOS),HL - RET -; -; MOVE ON TO THE NEXT FILE POSITION WITHIN THE CURRENT -; DIRECTORY BUFFER. IF NO MORE EXIST, SET POINTER TO 0FFFFH -; AND THE CALLING ROUTINE WILL CHECK FOR THIS. ENTER WITH (C) -; .EQUAL TO 0FFH TO CAUSE THE CHECKSUM BYTE TO BE SET, ELSE WE -; WILL CHECK THIS DISK AND SET WRITE PROTECT IF CHECKSUMS ARE -; NOT THE SAME (APPLIES ONLY IF ANOTHER DIRECTORY SECTOR MUST -; BE READ). -; -NXENTRY:LD HL,(DIRSIZE) ; GET DIRECTORY ENTRY SIZE LIMIT. - EX DE,HL - LD HL,(FILEPOS) ; GET CURRENT COUNT. - INC HL ; GO ON TO THE NEXT ONE. - LD (FILEPOS),HL - CALL SUBHL ; (HL)=(DIRSIZE)-(FILEPOS) - JP NC,NXENT1 ; IS THERE MORE ROOM LEFT? - JP STFILPOS ; NO. SET THIS FLAG AND RETURN. -NXENT1: LD A,(FILEPOS) ; GET FILE POSITION WITHIN DIRECTORY. - AND 03H ; ONLY LOOK WITHIN THIS SECTOR (ONLY 4 ENTRIES FIT). - LD B,5 ; CONVERT TO RELATIVE POSITION (32 BYTES EACH). -NXENT2: ADD A,A ; NOTE THAT THIS IS NOT EFFICIENT CODE. - DEC B ; 5 'ADD A'S WOULD BE BETTER. - JP NZ,NXENT2 - LD (FCBPOS),A ; SAVE IT AS POSITION OF FCB. - OR A - RET NZ ; RETURN IF WE ARE WITHIN BUFFER. - PUSH BC - CALL TRKSEC ; WE NEED THE NEXT DIRECTORY SECTOR. - CALL DIRREAD - POP BC - JP CHECKDIR -; -; ROUTINE TO TO GET A BIT FROM THE DISK SPACE ALLOCATION -; MAP. IT IS RETURNED IN (A), BIT POSITION 0. ON ENTRY TO HERE, -; SET (BC) TO THE BLOCK NUMBER ON THE DISK TO CHECK. -; ON RETURN, (D) WILL CONTAIN THE ORIGINAL BIT POSITION FOR -; THIS BLOCK NUMBER AND (HL) WILL POINT TO THE ADDRESS FOR IT. -; -CKBITMAP: - LD A,C ; DETERMINE BIT NUMBER OF INTEREST. - AND 07H ; COMPUTE (D)=(E)=(C AND 7)+1. - INC A - LD E,A ; SAVE PARTICULAR BIT NUMBER. - LD D,A -; -; COMPUTE (BC)=(BC)/8. -; - LD A,C - RRCA ; NOW SHIFT RIGHT 3 BITS. - RRCA - RRCA - AND 1FH ; AND CLEAR BITS 7,6,5. - LD C,A - LD A,B - ADD A,A ; NOW SHIFT (B) INTO BITS 7,6,5. - ADD A,A - ADD A,A - ADD A,A - ADD A,A - OR C ; AND ADD IN (C). - LD C,A ; OK, (C) HA BEEN COMPLETED. - LD A,B ; IS THERE A BETTER WAY OF DOING THIS? - RRCA - RRCA - RRCA - AND 1FH - LD B,A ; AND NOW (B) IS COMPLETED. -; -; USE THIS AS AN OFFSET INTO THE DISK SPACE ALLOCATION -; TABLE. -; - LD HL,(ALOCVECT) - ADD HL,BC - LD A,(HL) ; NOW GET CORRECT BYTE. -CKBMAP1:RLCA ; GET CORRECT BIT INTO POSITION 0. - DEC E - JP NZ,CKBMAP1 - RET -; -; SET OR CLEAR THE BIT MAP SUCH THAT BLOCK NUMBER (BC) WILL BE MARKED -; AS USED. ON ENTRY, IF (E)=0 THEN THIS BIT WILL BE CLEARED, IF IT .EQUALS -; 1 THEN IT WILL BE SET (DON'T USE ANYOTHER VALUES). -; -STBITMAP: - PUSH DE - CALL CKBITMAP ; GET THE BYTE OF INTEREST. - AND 0FEH ; CLEAR THE AFFECTED BIT. - POP BC - OR C ; AND NOW SET IT ACORDING TO (C). -; -; ENTRY TO RESTORE THE ORIGINAL BIT POSITION AND THEN STORE -; IN TABLE. (A) CONTAINS THE VALUE, (D) CONTAINS THE BIT -; POSITION (1-8), AND (HL) POINTS TO THE ADDRESS WITHIN THE -; SPACE ALLOCATION TABLE FOR THIS BYTE. -; -STBMAP1:RRCA ; RESTORE ORIGINAL BIT POSITION. - DEC D - JP NZ,STBMAP1 - LD (HL),A ; AND STOR BYTE IN TABLE. - RET -; -; SET/CLEAR SPACE USED BITS IN ALLOCATION MAP FOR THIS FILE. -; ON ENTRY, (C)=1 TO SET THE MAP AND (C)=0 TO CLEAR IT. -; -SETFILE:CALL FCB2HL ; GET ADDRESS OF FCB - LD DE,16 - ADD HL,DE ; GET TO BLOCK NUMBER BYTES. - PUSH BC - LD C,17 ; CHECK ALL 17 BYTES (MAX) OF TABLE. -SETFL1: POP DE - DEC C ; DONE ALL BYTES YET? - RET Z - PUSH DE - LD A,(BIGDISK) ; CHECK DISK SIZE FOR 16 BIT BLOCK NUMBERS. - OR A - JP Z,SETFL2 - PUSH BC ; ONLY 8 BIT NUMBERS. SET (BC) TO THIS ONE. - PUSH HL - LD C,(HL) ; GET LOW BYTE FROM TABLE, ALWAYS - LD B,0 ; SET HIGH BYTE TO ZERO. - JP SETFL3 -SETFL2: DEC C ; FOR 16 BIT BLOCK NUMBERS, ADJUST COUNTER. - PUSH BC - LD C,(HL) ; NOW GET BOTH THE LOW AND HIGH BYTES. - INC HL - LD B,(HL) - PUSH HL -SETFL3: LD A,C ; BLOCK USED? - OR B - JP Z,SETFL4 - LD HL,(DSKSIZE) ; IS THIS BLOCK NUMBER WITHIN THE - LD A,L ; SPACE ON THE DISK? - SUB C - LD A,H - SBC A,B - CALL NC,STBITMAP ; YES, SET THE PROPER BIT. -SETFL4: POP HL ; POINT TO NEXT BLOCK NUMBER IN FCB. - INC HL - POP BC - JP SETFL1 -; -; CONSTRUCT THE SPACE USED ALLOCATION BIT MAP FOR THE ACTIVE -; DRIVE. IF A FILE NAME STARTS WITH '$' AND IT IS UNDER THE -; CURRENT USER NUMBER, THEN (STATUS) IS SET TO MINUS 1. OTHERWISE -; IT IS NOT SET AT ALL. -; -BITMAP: LD HL,(DSKSIZE) ; COMPUTE SIZE OF ALLOCATION TABLE. - LD C,3 - CALL SHIFTR ; (HL)=(HL)/8. - INC HL ; AT LEASE 1 BYTE. - LD B,H - LD C,L ; SET (BC) TO THE ALLOCATION TABLE LENGTH. -; -; INITIALIZE THE BITMAP FOR THIS DRIVE. RIGHT NOW, THE FIRST -; TWO BYTES ARE SPECIFIED BY THE DISK PARAMETER BLOCK. HOWEVER -; A PATCH COULD BE ENTERED HERE IF IT WERE NECESSARY TO SETUP -; THIS TABLE IN A SPECIAL MANNOR. FOR EXAMPLE, THE BIOS COULD -; DETERMINE LOCATIONS OF 'BAD BLOCKS' AND SET THEM AS ALREADY -; 'USED' IN THE MAP. -; - LD HL,(ALOCVECT) ; NOW ZERO OUT THE TABLE NOW. -BITMAP1:LD (HL),0 - INC HL - DEC BC - LD A,B - OR C - JP NZ,BITMAP1 - LD HL,(ALLOC0) ; GET INITIAL SPACE USED BY DIRECTORY. - EX DE,HL - LD HL,(ALOCVECT) ; AND PUT THIS INTO MAP. - LD (HL),E - INC HL - LD (HL),D -; -; END OF INITIALIZATION PORTION. -; - CALL HOMEDRV ; NOW HOME THE DRIVE. - LD HL,(SCRATCH1) - LD (HL),3 ; FORCE NEXT DIRECTORY REQUEST TO READ - INC HL ; IN A SECTOR. - LD (HL),0 - CALL STFILPOS ; CLEAR INITIAL FILE POSITION ALSO. -BITMAP2:LD C,0FFH ; READ NEXT FILE NAME IN DIRECTORY - CALL NXENTRY ; AND SET CHECKSUM BYTE. - CALL CKFILPOS ; IS THERE ANOTHER FILE? - RET Z - CALL FCB2HL ; YES, GET ITS ADDRESS. - LD A,0E5H - CP (HL) ; EMPTY FILE ENTRY? - JP Z,BITMAP2 - LD A,(USERNO) ; NO, CORRECT USER NUMBER? - CP (HL) - JP NZ,BITMAP3 - INC HL - LD A,(HL) ; YES, DOES NAME START WITH A '$'? - SUB '$' - JP NZ,BITMAP3 - DEC A ; YES, SET ATATUS TO MINUS ONE. - LD (STATUS),A -BITMAP3:LD C,1 ; NOW SET THIS FILE'S SPACE AS USED IN BIT MAP. - CALL SETFILE - CALL CHKNMBR ; KEEP (SCRATCH1) IN BOUNDS. - JP BITMAP2 -; -; SET THE STATUS (STATUS) AND RETURN. -; -STSTATUS: - LD A,(FNDSTAT) - JP SETSTAT -; -; CHECK EXTENTS IN (A) AND (C). SET THE ZERO FLAG IF THEY -; ARE THE SAME. THE NUMBER OF 16K CHUNKS OF DISK SPACE THAT -; THE DIRECTORY EXTENT COVERS IS EXPRESSAD IS (EXTMASK+1). -; NO REGISTERS ARE MODIFIED. -; -SAMEXT: PUSH BC - PUSH AF - LD A,(EXTMASK) ; GET EXTENT MASK AND USE IT TO - CPL ; TO COMPARE BOTH EXTENT NUMBERS. - LD B,A ; SAVE RESULTING MASK HERE. - LD A,C ; MASK FIRST EXTENT AND SAVE IN (C). - AND B - LD C,A - POP AF ; NOW MASK SECOND EXTENT AND COMPARE - AND B ; WITH THE FIRST ONE. - SUB C - AND 1FH ; (* ONLY CHECK BUTS 0-4 *) - POP BC ; THE ZERO FLAG IS SET IF THEY ARE THE SAME. - RET ; RESTORE (BC) AND RETURN. -; -; SEARCH FOR THE FIRST OCCURENCE OF A FILE NAME. ON ENTRY, -; REGISTER (C) SHOULD CONTAIN THE NUMBER OF BYTES OF THE FCB -; THAT MUST MATCH. -; -FINDFST:LD A,0FFH - LD (FNDSTAT),A - LD HL,COUNTER ; SAVE CHARACTER COUNT. - LD (HL),C - LD HL,(PARAMS) ; GET FILENAME TO MATCH. - LD (SAVEFCB),HL ; AND SAVE. - CALL STFILPOS ; CLEAR INITIAL FILE POSITION (SET TO 0FFFFH). - CALL HOMEDRV ; HOME THE DRIVE. -; -; ENTRY TO LOCATE THE NEXT OCCURENCE OF A FILENAME WITHIN THE -; DIRECTORY. THE DISK IS NOT EXPECTED TO HAVE BEEN CHANGED. IF -; IT WAS, THEN IT WILL BE WRITE PROTECTED. -; -FINDNXT:LD C,0 ; WRITE PROTECT THE DISK IF CHANGED. - CALL NXENTRY ; GET NEXT FILENAME ENTRY IN DIRECTORY. - CALL CKFILPOS ; IS FILE POSITION = 0FFFFH? - JP Z,FNDNXT6 ; YES, EXIT NOW THEN. - LD HL,(SAVEFCB) ; SET (DE) POINTING TO FILENAME TO MATCH. - EX DE,HL - LD A,(DE) - CP 0E5H ; EMPTY DIRECTORY ENTRY? - JP Z,FNDNXT1 ; (* ARE WE TRYING TO RESERECT ERASED ENTRIES? *) - PUSH DE - CALL MOREFLS ; MORE FILES IN DIRECTORY? - POP DE - JP NC,FNDNXT6 ; NO MORE. EXIT NOW. -FNDNXT1:CALL FCB2HL ; GET ADDRESS OF THIS FCB IN DIRECTORY. - LD A,(COUNTER) ; GET NUMBER OF BYTES (CHARACTERS) TO CHECK. - LD C,A - LD B,0 ; INITIALIZE BYTE POSITION COUNTER. -FNDNXT2:LD A,C ; ARE WE DONE WITH THE COMPARE? - OR A - JP Z,FNDNXT5 - LD A,(DE) ; NO, CHECK NEXT BYTE. - CP '?' ; DON'T CARE ABOUT THIS CHARACTER? - JP Z,FNDNXT4 - LD A,B ; GET BYTES POSITION IN FCB. - CP 13 ; DON'T CARE ABOUT THE THIRTEENTH BYTE EITHER. - JP Z,FNDNXT4 - CP 12 ; EXTENT BYTE? - LD A,(DE) - JP Z,FNDNXT3 - SUB (HL) ; OTHERWISE COMPARE CHARACTERS. - AND 7FH - JP NZ,FINDNXT ; NOT THE SAME, CHECK NEXT ENTRY. - JP FNDNXT4 ; SO FAR SO GOOD, KEEP CHECKING. -FNDNXT3:PUSH BC ; CHECK THE EXTENT BYTE HERE. - LD C,(HL) - CALL SAMEXT - POP BC - JP NZ,FINDNXT ; NOT THE SAME, LOOK SOME MORE. -; -; SO FAR THE NAMES COMPARE. BUMP POINTERS TO THE NEXT BYTE -; AND CONTINUE UNTIL ALL (C) CHARACTERS HAVE BEEN CHECKED. -; -FNDNXT4:INC DE ; BUMP POINTERS. - INC HL - INC B - DEC C ; ADJUST CHARACTER COUNTER. - JP FNDNXT2 -FNDNXT5:LD A,(FILEPOS) ; RETURN THE POSITION OF THIS ENTRY. - AND 03H - LD (STATUS),A - LD HL,FNDSTAT - LD A,(HL) - RLA - RET NC - XOR A - LD (HL),A - RET -; -; FILENAME WAS NOT FOUND. SET APPROPRIATE STATUS. -; -FNDNXT6:CALL STFILPOS ; SET (FILEPOS) TO 0FFFFH. - LD A,0FFH ; SAY NOT LOCATED. - JP SETSTAT -; -; ERASE FILES FROM THE DIRECTORY. ONLY THE FIRST BYTE OF THE -; FCB WILL BE AFFECTED. IT IS SET TO (E5). -; -ERAFILE:CALL CHKWPRT ; IS DISK WRITE PROTECTED? - LD C,12 ; ONLY COMPARE FILE NAMES. - CALL FINDFST ; GET FIRST FILE NAME. -ERAFIL1:CALL CKFILPOS ; ANY FOUND? - RET Z ; NOPE, WE MUST BE DONE. - CALL CHKROFL ; IS FILE READ ONLY? - CALL FCB2HL ; NOPE, GET ADDRESS OF FCB AND - LD (HL),0E5H ; SET FIRST BYTE TO 'EMPTY'. - LD C,0 ; CLEAR THE SPACE FROM THE BIT MAP. - CALL SETFILE - CALL DIRWRITE ; NOW WRITE THE DIRECTORY SECTOR BACK OUT. - CALL FINDNXT ; FIND THE NEXT FILE NAME. - JP ERAFIL1 ; AND REPEAT PROCESS. -; -; LOOK THROUGH THE SPACE ALLOCATION MAP (BIT MAP) FOR THE -; NEXT AVAILABLE BLOCK. START SEARCHING AT BLOCK NUMBER (BC-1). -; THE SEARCH PROCEDURE IS TO LOOK FOR AN EMPTY BLOCK THAT IS -; BEFORE THE STARTING BLOCK. IF NOT EMPTY, LOOK AT A LATER -; BLOCK NUMBER. IN THIS WAY, WE RETURN THE CLOSEST EMPTY BLOCK -; ON EITHER SIDE OF THE 'TARGET' BLOCK NUMBER. THIS WILL SPEED -; ACCESS ON RANDOM DEVICES. FOR SERIAL DEVICES, THIS SHOULD BE -; CHANGED TO LOOK IN THE FORWARD DIRECTION FIRST AND THEN START -; AT THE FRONT AND SEARCH SOME MORE. -; -; ON RETURN, (DE)= BLOCK NUMBER THAT IS EMPTY AND (HL) =0 -; IF NO EMPRY BLOCK WAS FOUND. -; -FNDSPACE: - LD D,B ; SET (DE) AS THE BLOCK THAT IS CHECKED. - LD E,C -; -; LOOK BEFORE TARGET BLOCK. REGISTERS (BC) ARE USED AS THE LOWER -; POINTER AND (DE) AS THE UPPER POINTER. -; -FNDSPA1:LD A,C ; IS BLOCK 0 SPECIFIED? - OR B - JP Z,FNDSPA2 - DEC BC ; NOPE, CHECK PREVIOUS BLOCK. - PUSH DE - PUSH BC - CALL CKBITMAP - RRA ; IS THIS BLOCK EMPTY? - JP NC,FNDSPA3 ; YES. USE THIS. -; -; NOTE THAT THE ABOVE LOGIC GETS THE FIRST BLOCK THAT IT FINDS -; THAT IS EMPTY. THUS A FILE COULD BE WRITTEN 'BACKWARD' MAKING -; IT VERY SLOW TO ACCESS. THIS COULD BE CHANGED TO LOOK FOR THE -; FIRST EMPTY BLOCK AND THEN CONTINUE UNTIL THE START OF THIS -; EMPTY SPACE IS LOCATED AND THEN USED THAT STARTING BLOCK. -; THIS SHOULD HELP SPEED UP ACCESS TO SOME FILES ESPECIALLY ON -; A WELL USED DISK WITH LOTS OF FAIRLY SMALL 'HOLES'. -; - POP BC ; NOPE, CHECK SOME MORE. - POP DE -; -; NOW LOOK AFTER TARGET BLOCK. -; -FNDSPA2:LD HL,(DSKSIZE) ; IS BLOCK (DE) WITHIN DISK LIMITS? - LD A,E - SUB L - LD A,D - SBC A,H - JP NC,FNDSPA4 - INC DE ; YES, MOVE ON TO NEXT ONE. - PUSH BC - PUSH DE - LD B,D - LD C,E - CALL CKBITMAP ; CHECK IT. - RRA ; EMPTY? - JP NC,FNDSPA3 - POP DE ; NOPE, CONTINUE SEARCHING. - POP BC - JP FNDSPA1 -; -; EMPTY BLOCK FOUND. SET IT AS USED AND RETURN WITH (HL) -; POINTING TO IT (TRUE?). -; -FNDSPA3:RLA ; RESET BYTE. - INC A ; AND SET BIT 0. - CALL STBMAP1 ; UPDATE BIT MAP. - POP HL ; SET RETURN REGISTERS. - POP DE - RET -; -; FREE BLOCK WAS NOT FOUND. IF (BC) IS NOT ZERO, THEN WE HAVE -; NOT CHECKED ALL OF THE DISK SPACE. -; -FNDSPA4:LD A,C - OR B - JP NZ,FNDSPA1 - LD HL,0 ; SET 'NOT FOUND' STATUS. - RET -; -; MOVE A COMPLETE FCB ENTRY INTO THE DIRECTORY AND WRITE IT. -; -FCBSET: LD C,0 - LD E,32 ; LENGTH OF EACH ENTRY. -; -; MOVE (E) BYTES FROM THE FCB POINTED TO BY (PARAMS) INTO -; FCB IN DIRECTORY STARTING AT RELATIVE BYTE (C). THIS UPDATED -; DIRECTORY BUFFER IS THEN WRITTEN TO THE DISK. -; -UPDATE: PUSH DE - LD B,0 ; SET (BC) TO RELATIVE BYTE POSITION. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - ADD HL,BC ; COMPUTE STARTING BYTE. - EX DE,HL - CALL FCB2HL ; GET ADDRESS OF FCB TO UPDATE IN DIRECTORY. - POP BC ; SET (C) TO NUMBER OF BYTES TO CHANGE. - CALL DE2HL -UPDATE1:CALL TRKSEC ; DETERMINE THE TRACK AND SECTOR AFFECTED. - JP DIRWRITE ; THEN WRITE THIS SECTOR OUT. -; -; ROUTINE TO CHANGE THE NAME OF ALL FILES ON THE DISK WITH A -; SPECIFIED NAME. THE FCB CONTAINS THE CURRENT NAME AS THE -; FIRST 12 CHARACTERS AND THE NEW NAME 16 BYTES INTO THE FCB. -; -CHGNAMES: - CALL CHKWPRT ; CHECK FOR A WRITE PROTECTED DISK. - LD C,12 ; MATCH FIRST 12 BYTES OF FCB ONLY. - CALL FINDFST ; GET FIRST NAME. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD A,(HL) ; GET USER NUMBER. - LD DE,16 ; MOVE OVER TO DESIRED NAME. - ADD HL,DE - LD (HL),A ; KEEP SAME USER NUMBER. -CHGNAM1:CALL CKFILPOS ; ANY MATCHING FILE FOUND? - RET Z ; NO, WE MUST BE DONE. - CALL CHKROFL ; CHECK FOR READ ONLY FILE. - LD C,16 ; START 16 BYTES INTO FCB. - LD E,12 ; AND UPDATE THE FIRST 12 BYTES OF DIRECTORY. - CALL UPDATE - CALL FINDNXT ; GET TE NEXT FILE NAME. - JP CHGNAM1 ; AND CONTINUE. -; -; UPDATE A FILES ATTRIBUTES. THE PROCEDURE IS TO SEARCH FOR -; EVERY FILE WITH THE SAME NAME AS SHOWN IN FCB (IGNORING BIT 7) -; AND THEN TO UPDATE IT (WHICH INCLUDES BIT 7). NO OTHER CHANGES -; ARE MADE. -; -SAVEATTR: - LD C,12 ; MATCH FIRST 12 BYTES. - CALL FINDFST ; LOOK FOR FIRST FILENAME. -SAVATR1:CALL CKFILPOS ; WAS ONE FOUND? - RET Z ; NOPE, WE MUST BE DONE. - LD C,0 ; YES, UPDATE THE FIRST 12 BYTES NOW. - LD E,12 - CALL UPDATE ; UPDATE FILENAME AND WRITE DIRECTORY. - CALL FINDNXT ; AND GET THE NEXT FILE. - JP SAVATR1 ; THEN CONTINUE UNTIL DONE. -; -; OPEN A FILE (NAME SPECIFIED IN FCB). -; -OPENIT: LD C,15 ; COMPARE THE FIRST 15 BYTES. - CALL FINDFST ; GET THE FIRST ONE IN DIRECTORY. - CALL CKFILPOS ; ANY AT ALL? - RET Z -OPENIT1:CALL SETEXT ; POINT TO EXTENT BYTE WITHIN USERS FCB. - LD A,(HL) ; AND GET IT. - PUSH AF ; SAVE IT AND ADDRESS. - PUSH HL - CALL FCB2HL ; POINT TO FCB IN DIRECTORY. - EX DE,HL - LD HL,(PARAMS) ; THIS IS THE USERS COPY. - LD C,32 ; MOVE IT INTO USERS SPACE. - PUSH DE - CALL DE2HL - CALL SETS2B7 ; SET BIT 7 IN 'S2' BYTE (UNMODIFIED). - POP DE ; NOW GET THE EXTENT BYTE FROM THIS FCB. - LD HL,12 - ADD HL,DE - LD C,(HL) ; INTO (C). - LD HL,15 ; NOW GET THE RECORD COUNT BYTE INTO (B). - ADD HL,DE - LD B,(HL) - POP HL ; KEEP THE SAME EXTENT AS THE USER HAD ORIGINALLY. - POP AF - LD (HL),A - LD A,C ; IS IT THE SAME AS IN THE DIRECTORY FCB? - CP (HL) - LD A,B ; IF YES, THEN USE THE SAME RECORD COUNT. - JP Z,OPENIT2 - LD A,0 ; IF THE USER SPECIFIED AN EXTENT GREATER THAN - JP C,OPENIT2 ; THE ONE IN THE DIRECTORY, THEN SET RECORD COUNT TO 0. - LD A,128 ; OTHERWISE SET TO MAXIMUM. -OPENIT2:LD HL,(PARAMS) ; SET RECORD COUNT IN USERS FCB TO (A). - LD DE,15 - ADD HL,DE ; COMPUTE RELATIVE POSITION. - LD (HL),A ; AND SET THE RECORD COUNT. - RET -; -; MOVE TWO BYTES FROM (DE) TO (HL) IF (AND ONLY IF) (HL) -; POINT TO A ZERO VALUE (16 BIT). -; RETURN WITH ZERO FLAG SET IT (DE) WAS MOVED. REGISTERS (DE) -; AND (HL) ARE NOT CHANGED. HOWEVER (A) IS. -; -MOVEWORD: - LD A,(HL) ; CHECK FOR A ZERO WORD. - INC HL - OR (HL) ; BOTH BYTES ZERO? - DEC HL - RET NZ ; NOPE, JUST RETURN. - LD A,(DE) ; YES, MOVE TWO BYTES FROM (DE) INTO - LD (HL),A ; THIS ZERO SPACE. - INC DE - INC HL - LD A,(DE) - LD (HL),A - DEC DE ; DON'T DISTURB THESE REGISTERS. - DEC HL - RET -; -; GET HERE TO CLOSE A FILE SPECIFIED BY (FCB). -; -CLOSEIT:XOR A ; CLEAR STATUS AND FILE POSITION BYTES. - LD (STATUS),A - LD (FILEPOS),A - LD (FILEPOS+1),A - CALL GETWPRT ; GET WRITE PROTECT BIT FOR THIS DRIVE. - RET NZ ; JUST RETURN IF IT IS SET. - CALL GETS2 ; ELSE GET THE 'S2' BYTE. - AND 80H ; AND LOOK AT BIT 7 (FILE UNMODIFIED?). - RET NZ ; JUST RETURN IF SET. - LD C,15 ; ELSE LOOK UP THIS FILE IN DIRECTORY. - CALL FINDFST - CALL CKFILPOS ; WAS IT FOUND? - RET Z ; JUST RETURN IF NOT. - LD BC,16 ; SET (HL) POINTING TO RECORDS USED SECTION. - CALL FCB2HL - ADD HL,BC - EX DE,HL - LD HL,(PARAMS) ; DO THE SAME FOR USERS SPECIFIED FCB. - ADD HL,BC - LD C,16 ; THIS MANY BYTES ARE PRESENT IN THIS EXTENT. -CLOSEIT1: - LD A,(BIGDISK) ; 8 OR 16 BIT RECORD NUMBERS? - OR A - JP Z,CLOSEIT4 - LD A,(HL) ; JUST 8 BIT. GET ONE FROM USERS FCB. - OR A - LD A,(DE) ; NOW GET ONE FROM DIRECTORY FCB. - JP NZ,CLOSEIT2 - LD (HL),A ; USERS BYTE WAS ZERO. UPDATE FROM DIRECTORY. -CLOSEIT2: - OR A - JP NZ,CLOSEIT3 - LD A,(HL) ; DIRECTORIES BYTE WAS ZERO, UPDATE FROM USERS FCB. - LD (DE),A -CLOSEIT3: - CP (HL) ; IF NEITHER ONE OF THESE BYTES WERE ZERO, - JP NZ,CLOSEIT7 ; THEN CLOSE ERROR IF THEY ARE NOT THE SAME. - JP CLOSEIT5 ; OK SO FAR, GET TO NEXT BYTE IN FCBS. -CLOSEIT4: - CALL MOVEWORD ; UPDATE USERS FCB IF IT IS ZERO. - EX DE,HL - CALL MOVEWORD ; UPDATE DIRECTORIES FCB IF IT IS ZERO. - EX DE,HL - LD A,(DE) ; IF THESE TWO VALUES ARE NO DIFFERENT, - CP (HL) ; THEN A CLOSE ERROR OCCURED. - JP NZ,CLOSEIT7 - INC DE ; CHECK SECOND BYTE. - INC HL - LD A,(DE) - CP (HL) - JP NZ,CLOSEIT7 - DEC C ; REMEMBER 16 BIT VALUES. -CLOSEIT5: - INC DE ; BUMP TO NEXT ITEM IN TABLE. - INC HL - DEC C ; THERE ARE 16 ENTRIES ONLY. - JP NZ,CLOSEIT1 ; CONTINUE IF MORE TO DO. - LD BC,0FFECH ; BACKUP 20 PLACES (EXTENT BYTE). - ADD HL,BC - EX DE,HL - ADD HL,BC - LD A,(DE) - CP (HL) ; DIRECTORY'S EXTENT ALREADY GREATER THAN THE - JP C,CLOSEIT6 ; USERS EXTENT? - LD (HL),A ; NO, UPDATE DIRECTORY EXTENT. - LD BC,3 ; AND UPDATE THE RECORD COUNT BYTE IN - ADD HL,BC ; DIRECTORIES FCB. - EX DE,HL - ADD HL,BC - LD A,(HL) ; GET FROM USER. - LD (DE),A ; AND PUT IN DIRECTORY. -CLOSEIT6: - LD A,0FFH ; SET 'WAS OPEN AND IS NOW CLOSED' BYTE. - LD (CLOSEFLG),A - JP UPDATE1 ; UPDATE THE DIRECTORY NOW. -CLOSEIT7: - LD HL,STATUS ; SET RETURN STATUS AND THEN RETURN. - DEC (HL) - RET -; -; ROUTINE TO GET THE NEXT EMPTY SPACE IN THE DIRECTORY. IT -; WILL THEN BE CLEARED FOR USE. -; -GETEMPTY: - CALL CHKWPRT ; MAKE SURE DISK IS NOT WRITE PROTECTED. - LD HL,(PARAMS) ; SAVE CURRENT PARAMETERS (FCB). - PUSH HL - LD HL,EMPTYFCB ; USE SPECIAL ONE FOR EMPTY SPACE. - LD (PARAMS),HL - LD C,1 ; SEARCH FOR FIRST EMPTY SPOT IN DIRECTORY. - CALL FINDFST ; (* ONLY CHECK FIRST BYTE *) - CALL CKFILPOS ; NONE? - POP HL - LD (PARAMS),HL ; RESTORE ORIGINAL FCB ADDRESS. - RET Z ; RETURN IF NO MORE SPACE. - EX DE,HL - LD HL,15 ; POINT TO NUMBER OF RECORDS FOR THIS FILE. - ADD HL,DE - LD C,17 ; AND CLEAR ALL OF THIS SPACE. - XOR A -GETMT1: LD (HL),A - INC HL - DEC C - JP NZ,GETMT1 - LD HL,13 ; CLEAR THE 'S1' BYTE ALSO. - ADD HL,DE - LD (HL),A - CALL CHKNMBR ; KEEP (SCRATCH1) WITHIN BOUNDS. - CALL FCBSET ; WRITE OUT THIS FCB ENTRY TO DIRECTORY. - JP SETS2B7 ; SET 'S2' BYTE BIT 7 (UNMODIFIED AT PRESENT). -; -; ROUTINE TO CLOSE THE CURRENT EXTENT AND OPEN THE NEXT ONE -; FOR READING. -; -GETNEXT:XOR A - LD (CLOSEFLG),A ; CLEAR CLOSE FLAG. - CALL CLOSEIT ; CLOSE THIS EXTENT. - CALL CKFILPOS - RET Z ; NOT THERE??? - LD HL,(PARAMS) ; GET EXTENT BYTE. - LD BC,12 - ADD HL,BC - LD A,(HL) ; AND INCREMENT IT. - INC A - AND 1FH ; KEEP WITHIN RANGE 0-31. - LD (HL),A - JP Z,GTNEXT1 ; OVERFLOW? - LD B,A ; MASK EXTENT BYTE. - LD A,(EXTMASK) - AND B - LD HL,CLOSEFLG ; CHECK CLOSE FLAG (0FFH IS OK). - AND (HL) - JP Z,GTNEXT2 ; IF ZERO, WE MUST READ IN NEXT EXTENT. - JP GTNEXT3 ; ELSE, IT IS ALREADY IN MEMORY. -GTNEXT1:LD BC,2 ; POINT TO THE 'S2' BYTE. - ADD HL,BC - INC (HL) ; AND BUMP IT. - LD A,(HL) ; TOO MANY EXTENTS? - AND 0FH - JP Z,GTNEXT5 ; YES, SET ERROR CODE. -; -; GET HERE TO OPEN THE NEXT EXTENT. -; -GTNEXT2:LD C,15 ; SET TO CHECK FIRST 15 BYTES OF FCB. - CALL FINDFST ; FIND THE FIRST ONE. - CALL CKFILPOS ; NONE AVAILABLE? - JP NZ,GTNEXT3 - LD A,(R.DWRTFLG) ; NO EXTENT PRESENT. CAN WE OPEN AN EMPTY ONE? - INC A ; 0FFH MEANS READING (SO NOT POSSIBLE). - JP Z,GTNEXT5 ; OR AN ERROR. - CALL GETEMPTY ; WE ARE WRITING, GET AN EMPTY ENTRY. - CALL CKFILPOS ; NONE? - JP Z,GTNEXT5 ; ERROR IF TRUE. - JP GTNEXT4 ; ELSE WE ARE ALMOST DONE. -GTNEXT3:CALL OPENIT1 ; OPEN THIS EXTENT. -GTNEXT4:CALL STRDATA ; MOVE IN UPDATED DATA (REC #, EXTENT #, ETC.) - XOR A ; CLEAR STATUS AND RETURN. - JP SETSTAT -; -; ERROR IN EXTENDING THE FILE. TOO MANY EXTENTS WERE NEEDED -; OR NOT ENOUGH SPACE ON THE DISK. -; -GTNEXT5:CALL IOERR1 ; SET ERROR CODE, CLEAR BIT 7 OF 'S2' - JP SETS2B7 ; SO THIS IS NOT WRITTEN ON A CLOSE. -; -; READ A S.EQUENTIAL FILE. -; -RDSEQ: LD A,1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -RDSEQ1: LD A,0FFH ; DON'T ALLOW READING UNWRITTEN SPACE. - LD (R.DWRTFLG),A - CALL STRDATA ; PUT REC# AND EXT# INTO FCB. - LD A,(SAVNREC) ; GET NEXT RECORD TO READ. - LD HL,SAVNXT ; GET NUMBER OF RECORDS IN EXTENT. - CP (HL) ; WITHIN THIS EXTENT? - JP C,RDSEQ2 - CP 128 ; NO. IS THIS EXTENT FULLY USED? - JP NZ,RDSEQ3 ; NO. END-OF-FILE. - CALL GETNEXT ; YES, OPEN THE NEXT ONE. - XOR A ; RESET NEXT RECORD TO READ. - LD (SAVNREC),A - LD A,(STATUS) ; CHECK ON OPEN, SUCCESSFUL? - OR A - JP NZ,RDSEQ3 ; NO, ERROR. -RDSEQ2: CALL COMBLK ; OK. COMPUTE BLOCK NUMBER TO READ. - CALL CHKBLK ; CHECK IT. WITHIN BOUNDS? - JP Z,RDSEQ3 ; NO, ERROR. - CALL LOGICAL ; CONVERT (BLKNMBR) TO LOGICAL SECTOR (128 BYTE). - CALL TRKSEC1 ; SET THE TRACK AND SECTOR FOR THIS BLOCK #. - CALL DOREAD ; AND READ IT. - JP SETNREC ; AND SET THE NEXT RECORD TO BE ACCESSED. -; -; READ ERROR OCCURED. SET STATUS AND RETURN. -; -RDSEQ3: JP IOERR1 -; -; WRITE THE NEXT S.EQUENTIAL RECORD. -; -WTSEQ: LD A,1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -WTSEQ1: LD A,0 ; ALLOW AN ADDITION EMPTY EXTENT TO BE OPENED. - LD (R.DWRTFLG),A - CALL CHKWPRT ; CHECK WRITE PROTECT STATUS. - LD HL,(PARAMS) - CALL CKROF1 ; CHECK FOR READ ONLY FILE, (HL) ALREADY SET TO FCB. - CALL STRDATA ; PUT UPDATED DATA INTO FCB. - LD A,(SAVNREC) ; GET RECORD NUMBER TO WRITE. - CP 128 ; WITHIN RANGE? - JP NC,IOERR1 ; NO, ERROR(?). - CALL COMBLK ; COMPUTE BLOCK NUMBER. - CALL CHKBLK ; CHECK NUMBER. - LD C,0 ; IS THERE ONE TO WRITE TO? - JP NZ,WTSEQ6 ; YES, GO DO IT. - CALL GETBLOCK ; GET NEXT BLOCK NUMBER WITHIN FCB TO USE. - LD (RELBLOCK),A ; AND SAVE. - LD BC,0 ; START LOOKING FOR SPACE FROM THE START - OR A ; IF NONE ALLOCATED AS YET. - JP Z,WTSEQ2 - LD C,A ; EXTRACT PREVIOUS BLOCK NUMBER FROM FCB - DEC BC ; SO WE CAN BE CLOSEST TO IT. - CALL EXTBLK - LD B,H - LD C,L -WTSEQ2: CALL FNDSPACE ; FIND THE NEXT EMPTY BLOCK NEAREST NUMBER (BC). - LD A,L ; CHECK FOR A ZERO NUMBER. - OR H - JP NZ,WTSEQ3 - LD A,2 ; NO MORE SPACE? - JP SETSTAT -WTSEQ3: LD (BLKNMBR),HL ; SAVE BLOCK NUMBER TO ACCESS. - EX DE,HL ; PUT BLOCK NUMBER INTO (DE). - LD HL,(PARAMS) ; NOW WE MUST UPDATE THE FCB FOR THIS - LD BC,16 ; NEWLY ALLOCATED BLOCK. - ADD HL,BC - LD A,(BIGDISK) ; 8 OR 16 BIT BLOCK NUMBERS? - OR A - LD A,(RELBLOCK) ; (* UPDATE THIS ENTRY *) - JP Z,WTSEQ4 ; ZERO MEANS 16 BIT ONES. - CALL ADDA2HL ; (HL)=(HL)+(A) - LD (HL),E ; STORE NEW BLOCK NUMBER. - JP WTSEQ5 -WTSEQ4: LD C,A ; COMPUTE SPOT IN THIS 16 BIT TABLE. - LD B,0 - ADD HL,BC - ADD HL,BC - LD (HL),E ; STUFF BLOCK NUMBER (DE) THERE. - INC HL - LD (HL),D -WTSEQ5: LD C,2 ; SET (C) TO INDICATE WRITING TO UN-USED DISK SPACE. -WTSEQ6: LD A,(STATUS) ; ARE WE OK SO FAR? - OR A - RET NZ - PUSH BC ; YES, SAVE WRITE FLAG FOR BIOS (REGISTER C). - CALL LOGICAL ; CONVERT (BLKNMBR) OVER TO LOICAL SECTORS. - LD A,(MODE) ; GET ACCESS MODE FLAG (1=S.EQUENTIAL, - DEC A ; 0=RANDOM, 2=SPECIAL?). - DEC A - JP NZ,WTSEQ9 -; -; SPECIAL RANDOM I/O FROM FUNCTION #40. MAYBE FOR M/PM, BUT THE -; CURRENT BLOCK, IF IT HAS NOT BEEN WRITTEN TO, WILL BE ZEROED -; OUT AND THEN WRITTEN (REASON?). -; - POP BC - PUSH BC - LD A,C ; GET WRITE STATUS FLAG (2=WRITING UNUSED SPACE). - DEC A - DEC A - JP NZ,WTSEQ9 - PUSH HL - LD HL,(DIRBUF) ; ZERO OUT THE DIRECTORY BUFFER. - LD D,A ; NOTE THAT (A) IS ZERO HERE. -WTSEQ7: LD (HL),A - INC HL - INC D ; DO 128 BYTES. - JP P,WTSEQ7 - CALL DIRDMA ; TELL THE BIOS THE DMA ADDRESS FOR DIRECTORY ACCESS. - LD HL,(LOGSECT) ; GET SECTOR THAT STARTS CURRENT BLOCK. - LD C,2 ; SET 'WRITING TO UNUSED SPACE' FLAG. -WTSEQ8: LD (BLKNMBR),HL ; SAVE SECTOR TO WRITE. - PUSH BC - CALL TRKSEC1 ; DETERMINE ITS TRACK AND SECTOR NUMBERS. - POP BC - CALL DOWRITE ; NOW WRITE OUT 128 BYTES OF ZEROS. - LD HL,(BLKNMBR) ; GET SECTOR NUMBER. - LD C,0 ; SET NORMAL WRITE FLAG. - LD A,(BLKMASK) ; DETERMINE IF WE HAVE WRITTEN THE ENTIRE - LD B,A ; PHYSICAL BLOCK. - AND L - CP B - INC HL ; PREPARE FOR THE NEXT ONE. - JP NZ,WTSEQ8 ; CONTINUE UNTIL (BLKMASK+1) SECTORS WRITTEN. - POP HL ; RESET NEXT SECTOR NUMBER. - LD (BLKNMBR),HL - CALL DEFDMA ; AND RESET DMA ADDRESS. -; -; NORMAL DISK WRITE. SET THE DESIRED TRACK AND SECTOR THEN -; DO THE ACTUAL WRITE. -; -WTSEQ9: CALL TRKSEC1 ; DETERMINE TRACK AND SECTOR FOR THIS WRITE. - POP BC ; GET WRITE STATUS FLAG. - PUSH BC - CALL DOWRITE ; AND WRITE THIS OUT. - POP BC - LD A,(SAVNREC) ; GET NUMBER OF RECORDS IN FILE. - LD HL,SAVNXT ; GET LAST RECORD WRITTEN. - CP (HL) - JP C,WTSEQ10 - LD (HL),A ; WE HAVE TO UPDATE RECORD COUNT. - INC (HL) - LD C,2 -; -;* THIS AREA HAS BEEN PATCHED TO CORRECT DISK UPDATE PROBLEM -;* WHEN USING BLOCKING AND DE-BLOCKING IN THE BIOS. -; -WTSEQ10:NOP ; WAS 'DCR C' - NOP ; WAS 'DCR C' - LD HL,0 ; WAS 'JNZ WTSEQ99' -; -; * END OF PATCH. -; - PUSH AF - CALL GETS2 ; SET 'EXTENT WRITTEN TO' FLAG. - AND 7FH ; (* CLEAR BIT 7 *) - LD (HL),A - POP AF ; GET RECORD COUNT FOR THIS EXTENT. -WTSEQ99:CP 127 ; IS IT FULL? - JP NZ,WTSEQ12 - LD A,(MODE) ; YES, ARE WE IN S.EQUENTIAL MODE? - CP 1 - JP NZ,WTSEQ12 - CALL SETNREC ; YES, SET NEXT RECORD NUMBER. - CALL GETNEXT ; AND GET NEXT EMPTY SPACE IN DIRECTORY. - LD HL,STATUS ; OK? - LD A,(HL) - OR A - JP NZ,WTSEQ11 - DEC A ; YES, SET RECORD COUNT TO -1. - LD (SAVNREC),A -WTSEQ11:LD (HL),0 ; CLEAR STATUS. -WTSEQ12:JP SETNREC ; SET NEXT RECORD TO ACCESS. -; -; FOR RANDOM I/O, SET THE FCB FOR THE DESIRED RECORD NUMBER -; BASED ON THE 'R0,R1,R2' BYTES. THESE BYTES IN THE FCB ARE -; USED AS FOLLOWS: -; -; FCB+35 FCB+34 FCB+33 -; | 'R-2' | 'R-1' | 'R-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | OVERFLOW | | EXTRA | EXTENT | RECORD # | -; | ______________| |_EXTENT|__NUMBER___|_____________| -; ALSO 'S2' -; -; ON ENTRY, REGISTER (C) CONTAINS 0FFH IF THIS IS A READ -; AND THUS WE CAN NOT ACCESS UNWRITTEN DISK SPACE. OTHERWISE, -; ANOTHER EXTENT WILL BE OPENED (FOR WRITING) IF REQUIRED. -; -POSITION: - XOR A ; SET RANDOM I/O FLAG. - LD (MODE),A -; -; SPECIAL ENTRY (FUNCTION #40). M/PM ? -; -POSITN1:PUSH BC ; SAVE READ/WRITE FLAG. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - EX DE,HL - LD HL,33 ; NOW GET BYTE 'R0'. - ADD HL,DE - LD A,(HL) - AND 7FH ; KEEP BITS 0-6 FOR THE RECORD NUMBER TO ACCESS. - PUSH AF - LD A,(HL) ; NOW GET BIT 7 OF 'R0' AND BITS 0-3 OF 'R1'. - RLA - INC HL - LD A,(HL) - RLA - AND 1FH ; AND SAVE THIS IN BITS 0-4 OF (C). - LD C,A ; THIS IS THE EXTENT BYTE. - LD A,(HL) ; NOW GET THE EXTRA EXTENT BYTE. - RRA - RRA - RRA - RRA - AND 0FH - LD B,A ; AND SAVE IT IN (B). - POP AF ; GET RECORD NUMBER BACK TO (A). - INC HL ; CHECK OVERFLOW BYTE 'R2'. - LD L,(HL) - INC L - DEC L - LD L,6 ; PREPARE FOR ERROR. - JP NZ,POSITN5 ; OUT OF DISK SPACE ERROR. - LD HL,32 ; STORE RECORD NUMBER INTO FCB. - ADD HL,DE - LD (HL),A - LD HL,12 ; AND NOW CHECK THE EXTENT BYTE. - ADD HL,DE - LD A,C - SUB (HL) ; SAME EXTENT AS BEFORE? - JP NZ,POSITN2 - LD HL,14 ; YES, CHECK EXTRA EXTENT BYTE 'S2' ALSO. - ADD HL,DE - LD A,B - SUB (HL) - AND 7FH - JP Z,POSITN3 ; SAME, WE ARE ALMOST DONE THEN. -; -; GET HERE WHEN ANOTHER EXTENT IS REQUIRED. -; -POSITN2:PUSH BC - PUSH DE - CALL CLOSEIT ; CLOSE CURRENT EXTENT. - POP DE - POP BC - LD L,3 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; CLOSE ERROR. - LD HL,12 ; PUT DESIRED EXTENT INTO FCB NOW. - ADD HL,DE - LD (HL),C - LD HL,14 ; AND STORE EXTRA EXTENT BYTE 'S2'. - ADD HL,DE - LD (HL),B - CALL OPENIT ; TRY AND GET THIS EXTENT. - LD A,(STATUS) ; WAS IT THERE? - INC A - JP NZ,POSITN3 - POP BC ; NO. CAN WE CREATE A NEW ONE (WRITING?). - PUSH BC - LD L,4 ; PREPARE FOR ERROR. - INC C - JP Z,POSITN4 ; NOPE, READING UNWRITTEN SPACE ERROR. - CALL GETEMPTY ; YES WE CAN, TRY TO FIND SPACE. - LD L,5 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; OUT OF SPACE? -; -; NORMAL RETURN LOCATION. CLEAR ERROR CODE AND RETURN. -; -POSITN3:POP BC ; RESTORE STACK. - XOR A ; AND CLEAR ERROR CODE BYTE. - JP SETSTAT -; -; ERROR. SET THE 'S2' BYTE TO INDICATE THIS (WHY?). -; -POSITN4:PUSH HL - CALL GETS2 - LD (HL),0C0H - POP HL -; -; RETURN WITH ERROR CODE (PRESENTLY IN L). -; -POSITN5:POP BC - LD A,L ; GET ERROR CODE. - LD (STATUS),A - JP SETS2B7 -; -; READ A RANDOM RECORD. -; -READRAN:LD C,0FFH ; SET 'READ' STATUS. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,RDSEQ1 ; AND READ IT AS USUAL (IF NO ERRORS). - RET -; -; WRITE TO A RANDOM RECORD. -; -WRITERAN: - LD C,0 ; SET 'WRITING' FLAG. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,WTSEQ1 ; AND WRITE AS USUAL (IF NO ERRORS). - RET -; -; COMPUTE THE RANDOM RECORD NUMBER. ENTER WITH (HL) POINTING -; TO A FCB AN (DE) CONTAINS A RELATIVE LOCATION OF A RECORD -; NUMBER. ON EXIT, (C) CONTAINS THE 'R0' BYTE, (B) THE 'R1' -; BYTE, AND (A) THE 'R2' BYTE. -; -; ON RETURN, THE ZERO FLAG IS SET IF THE RECORD IS WITHIN -; BOUNDS. OTHERWISE, AN OVERFLOW OCCURED. -; -COMPRAND: - EX DE,HL ; SAVE FCB POINTER IN (DE). - ADD HL,DE ; COMPUTE RELATIVE POSITION OF RECORD #. - LD C,(HL) ; GET RECORD NUMBER INTO (BC). - LD B,0 - LD HL,12 ; NOW GET EXTENT. - ADD HL,DE - LD A,(HL) ; COMPUTE (BC)=(RECORD #)+(EXTENT)*128. - RRCA ; MOVE LOWER BIT INTO BIT 7. - AND 80H ; AND IGNORE ALL OTHER BITS. - ADD A,C ; ADD TO OUR RECORD NUMBER. - LD C,A - LD A,0 ; TAKE CARE OF ANY CARRY. - ADC A,B - LD B,A - LD A,(HL) ; NOW GET THE UPPER BITS OF EXTENT INTO - RRCA ; BIT POSITIONS 0-3. - AND 0FH ; AND IGNORE ALL OTHERS. - ADD A,B ; ADD THIS IN TO 'R1' BYTE. - LD B,A - LD HL,14 ; GET THE 'S2' BYTE (EXTRA EXTENT). - ADD HL,DE - LD A,(HL) - ADD A,A ; AND SHIFT IT LEFT 4 BITS (BITS 4-7). - ADD A,A - ADD A,A - ADD A,A - PUSH AF ; SAVE CARRY FLAG (BIT 0 OF FLAG BYTE). - ADD A,B ; NOW ADD EXTRA EXTENT INTO 'R1'. - LD B,A - PUSH AF ; AND SAVE CARRY (OVERFLOW BYTE 'R2'). - POP HL ; BIT 0 OF (L) IS THE OVERFLOW INDICATOR. - LD A,L - POP HL ; AND SAME FOR FIRST CARRY FLAG. - OR L ; EITHER ONE OF THESE SET? - AND 01H ; ONLY CHECK THE CARRY FLAGS. - RET -; -; ROUTINE TO SETUP THE FCB (BYTES 'R0', 'R1', 'R2') TO -; REFLECT THE LAST RECORD USED FOR A RANDOM (OR OTHER) FILE. -; THIS READS THE DIRECTORY AND LOOKS AT ALL EXTENTS COMPUTING -; THE LARGERST RECORD NUMBER FOR EACH AND KEEPING THE MAXIMUM -; VALUE ONLY. THEN 'R0', 'R1', AND 'R2' WILL REFLECT THIS -; MAXIMUM RECORD NUMBER. THIS IS USED TO COMPUTE THE SPACE USED -; BY A RANDOM FILE. -; -RANSIZE:LD C,12 ; LOOK THRU DIRECTORY FOR FIRST ENTRY WITH - CALL FINDFST ; THIS NAME. - LD HL,(PARAMS) ; ZERO OUT THE 'R0, R1, R2' BYTES. - LD DE,33 - ADD HL,DE - PUSH HL - LD (HL),D ; NOTE THAT (D)=0. - INC HL - LD (HL),D - INC HL - LD (HL),D -RANSIZ1:CALL CKFILPOS ; IS THERE AN EXTENT TO PROCESS? - JP Z,RANSIZ3 ; NO, WE ARE DONE. - CALL FCB2HL ; SET (HL) POINTING TO PROPER FCB IN DIR. - LD DE,15 ; POINT TO LAST RECORD IN EXTENT. - CALL COMPRAND ; AND COMPUTE RANDOM PARAMETERS. - POP HL - PUSH HL ; NOW CHECK THESE VALUES AGAINST THOSE - LD E,A ; ALREADY IN FCB. - LD A,C ; THE CARRY FLAG WILL BE SET IF THOSE - SUB (HL) ; IN THE FCB REPRESENT A LARGER SIZE THAN - INC HL ; THIS EXTENT DOES. - LD A,B - SBC A,(HL) - INC HL - LD A,E - SBC A,(HL) - JP C,RANSIZ2 - LD (HL),E ; WE FOUND A LARGER (IN SIZE) EXTENT. - DEC HL ; STUFF THESE VALUES INTO FCB. - LD (HL),B - DEC HL - LD (HL),C -RANSIZ2:CALL FINDNXT ; NOW GET THE NEXT EXTENT. - JP RANSIZ1 ; CONTINUE TIL ALL DONE. -RANSIZ3:POP HL ; WE ARE DONE, RESTORE THE STACK AND - RET ; RETURN. -; -; FUNCTION TO RETURN THE RANDOM RECORD POSITION OF A GIVEN -; FILE WHICH HAS BEEN READ IN S.EQUENTIAL MODE UP TO NOW. -; -SETRAN: LD HL,(PARAMS) ; POINT TO FCB. - LD DE,32 ; AND TO LAST USED RECORD. - CALL COMPRAND ; COMPUTE RANDOM POSITION. - LD HL,33 ; NOW STUFF THESE VALUES INTO FCB. - ADD HL,DE - LD (HL),C ; MOVE 'R0'. - INC HL - LD (HL),B ; AND 'R1'. - INC HL - LD (HL),A ; AND LASTLY 'R2'. - RET -; -; THIS ROUTINE SELECT THE DRIVE SPECIFIED IN (ACTIVE) AND -; UPDATE THE LOGIN VECTOR AND BITMAP TABLE IF THIS DRIVE WAS -; NOT ALREADY ACTIVE. -; -LOGINDRV: - LD HL,(LOGIN) ; GET THE LOGIN VECTOR. - LD A,(ACTIVE) ; GET THE DEFAULT DRIVE. - LD C,A - CALL SHIFTR ; POSITION ACTIVE BIT FOR THIS DRIVE - PUSH HL ; INTO BIT 0. - EX DE,HL - CALL SELECT ; SELECT THIS DRIVE. - POP HL - CALL Z,SLCTERR ; VALID DRIVE? - LD A,L ; IS THIS A NEWLY ACTIVATED DRIVE? - RRA - RET C - LD HL,(LOGIN) ; YES, UPDATE THE LOGIN VECTOR. - LD C,L - LD B,H - CALL SETBIT - LD (LOGIN),HL ; AND SAVE. - JP BITMAP ; NOW UPDATE THE BITMAP. -; -; FUNCTION TO SET THE ACTIVE DISK NUMBER. -; -SETDSK: LD A,(EPARAM) ; GET PARAMETER PASSED AND SEE IF THIS - LD HL,ACTIVE ; REPRESENTS A CHANGE IN DRIVES. - CP (HL) - RET Z - LD (HL),A ; YES IT DOES, LOG IT IN. - JP LOGINDRV -; -; THIS IS THE 'AUTO DISK SELECT' ROUTINE. THE FIRSST BYTE -; OF THE FCB IS EXAMINED FOR A DRIVE SPECIFICATION. IF NON -; ZERO THEN THE DRIVE WILL BE SELECTED AND LOGED IN. -; -AUTOSEL:LD A,0FFH ; SAY 'AUTO-SELECT ACTIVATED'. - LD (AUTO),A - LD HL,(PARAMS) ; GET DRIVE SPECIFIED. - LD A,(HL) - AND 1FH ; LOOK AT LOWER 5 BITS. - DEC A ; ADJUST FOR (1=A, 2=B) ETC. - LD (EPARAM),A ; AND SAVE FOR THE SELECT ROUTINE. - CP 1EH ; CHECK FOR 'NO CHANGE' CONDITION. - JP NC,AUTOSL1 ; YES, DON'T CHANGE. - LD A,(ACTIVE) ; WE MUST CHANGE, SAVE CURRENTLY ACTIVE - LD (OLDDRV),A ; DRIVE. - LD A,(HL) ; AND SAVE FIRST BYTE OF FCB ALSO. - LD (AUTOFLAG),A ; THIS MUST BE NON-ZERO. - AND 0E0H ; WHATS THIS FOR (BITS 6,7 ARE USED FOR - LD (HL),A ; SOMETHING)? - CALL SETDSK ; SELECT AND LOG IN THIS DRIVE. -AUTOSL1:LD A,(USERNO) ; MOVE USER NUMBER INTO FCB. - LD HL,(PARAMS) ; (* UPPER HALF OF FIRST BYTE *) - OR (HL) - LD (HL),A - RET ; AND RETURN (ALL DONE). -; -; FUNCTION TO RETURN THE CURRENT CP/M VERSION NUMBER. -; -GETVER: LD A,022H ; VERSION 2.2 - JP SETSTAT -; -; FUNCTION TO RESET THE DISK SYSTEM. -; -RSTDSK: LD HL,0 ; CLEAR WRITE PROTECT STATUS AND LOG - LD (WRTPRT),HL ; IN VECTOR. - LD (LOGIN),HL - XOR A ; SELECT DRIVE 'A'. - LD (ACTIVE),A - LD HL,TBUFF ; SETUP DEFAULT DMA ADDRESS. - LD (USERDMA),HL - CALL DEFDMA - JP LOGINDRV ; NOW LOG IN DRIVE 'A'. -; -; FUNCTION TO OPEN A SPECIFIED FILE. -; -OPENFIL:CALL CLEARS2 ; CLEAR 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DISK. - JP OPENIT ; AND OPEN THE FILE. -; -; FUNCTION TO CLOSE A SPECIFIED FILE. -; -CLOSEFIL: - CALL AUTOSEL ; SELECT PROPER DISK. - JP CLOSEIT ; AND CLOSE THE FILE. -; -; FUNCTION TO RETURN THE FIRST OCCURENCE OF A SPECIFIED FILE -; NAME. IF THE FIRST BYTE OF THE FCB IS '?' THEN THE NAME WILL -; NOT BE CHECKED (GET THE FIRST ENTRY NO MATTER WHAT). -; -GETFST: LD C,0 ; PREPARE FOR SPECIAL SEARCH. - EX DE,HL - LD A,(HL) ; IS FIRST BYTE A '?'? - CP '?' - JP Z,GETFST1 ; YES, JUST GET VERY FIRST ENTRY (ZERO LENGTH MATCH). - CALL SETEXT ; GET THE EXTENSION BYTE FROM FCB. - LD A,(HL) ; IS IT '?'? IF YES, THEN WE WANT - CP '?' ; AN ENTRY WITH A SPECIFIC 'S2' BYTE. - CALL NZ,CLEARS2 ; OTHERWISE, LOOK FOR A ZERO 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DRIVE. - LD C,15 ; COMPARE BYTES 0-14 IN FCB (12&13 EXCLUDED). -GETFST1:CALL FINDFST ; FIND AN ENTRY AND THEN MOVE IT INTO - JP MOVEDIR ; THE USERS DMA SPACE. -; -; FUNCTION TO RETURN THE NEXT OCCURENCE OF A FILE NAME. -; -GETNXT: LD HL,(SAVEFCB) ; RESTORE POINTERS. NOTE THAT NO - LD (PARAMS),HL ; OTHER .DBOS CALLS ARE ALLOWED. - CALL AUTOSEL ; NO ERROR WILL BE RETURNED, BUT THE - CALL FINDNXT ; RESULTS WILL BE WRONG. - JP MOVEDIR -; -; FUNCTION TO DELETE A FILE BY NAME. -; -DELFILE:CALL AUTOSEL ; SELECT PROPER DRIVE. - CALL ERAFILE ; ERASE THE FILE. - JP STSTATUS ; SET STATUS AND RETURN. -; -; FUNCTION TO EXECUTE A S.EQUENTIAL READ OF THE SPECIFIED -; RECORD NUMBER. -; -READSEQ:CALL AUTOSEL ; SELECT PROPER DRIVE THEN READ. - JP RDSEQ -; -; FUNCTION TO WRITE THE NET S.EQUENTIAL RECORD. -; -WRTSEQ: CALL AUTOSEL ; SELECT PROPER DRIVE THEN WRITE. - JP WTSEQ -; -; CREATE A FILE FUNCTION. -; -FCREATE:CALL CLEARS2 ; CLEAR THE 'S2' BYTE ON ALL CREATES. - CALL AUTOSEL ; SELECT PROPER DRIVE AND GET THE NEXT - JP GETEMPTY ; EMPTY DIRECTORY SPACE. -; -; FUNCTION TO RENAME A FILE. -; -RENFILE:CALL AUTOSEL ; SELECT PROPER DRIVE AND THEN SWITCH - CALL CHGNAMES ; FILE NAMES. - JP STSTATUS -; -; FUNCTION TO RETURN THE LOGIN VECTOR. -; -GETLOG: LD HL,(LOGIN) - JP GETPRM1 -; -; FUNCTION TO RETURN THE CURRENT DISK ASSIGNMENT. -; -GETCRNT:LD A,(ACTIVE) - JP SETSTAT -; -; FUNCTION TO SET THE DMA ADDRESS. -; -PUTDMA: EX DE,HL - LD (USERDMA),HL ; SAVE IN OUR SPACE AND THEN GET TO - JP DEFDMA ; THE BIOS WITH THIS ALSO. -; -; FUNCTION TO RETURN THE ALLOCATION VECTOR. -; -GETALOC:LD HL,(ALOCVECT) - JP GETPRM1 -; -; FUNCTION TO RETURN THE READ-ONLY STATUS VECTOR. -; -GETROV: LD HL,(WRTPRT) - JP GETPRM1 -; -; FUNCTION TO SET THE FILE ATTRIBUTES (READ-ONLY, SYSTEM). -; -SETATTR:CALL AUTOSEL ; SELECT PROPER DRIVE THEN SAVE ATTRIBUTES. - CALL SAVEATTR - JP STSTATUS -; -; FUNCTION TO RETURN THE ADDRESS OF THE DISK PARAMETER BLOCK -; FOR THE CURRENT DRIVE. -; -GETPARM:LD HL,(DISKPB) -GETPRM1:LD (STATUS),HL - RET -; -; FUNCTION TO GET OR SET THE USER NUMBER. IF (E) WAS (FF) -; THEN THIS IS A REQUEST TO RETURN THE CURRENT USER NUMBER. -; ELSE SET THE USER NUMBER FROM (E). -; -GETUSER:LD A,(EPARAM) ; GET PARAMETER. - CP 0FFH ; GET USER NUMBER? - JP NZ,SETUSER - LD A,(USERNO) ; YES, JUST DO IT. - JP SETSTAT -SETUSER:AND 1FH ; NO, WE SHOULD SET IT INSTEAD. KEEP LOW - LD (USERNO),A ; BITS (0-4) ONLY. - RET -; -; FUNCTION TO READ A RANDOM RECORD FROM A FILE. -; -RDRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND READ. - JP READRAN -; -; FUNCTION TO COMPUTE THE FILE SIZE FOR RANDOM FILES. -; -WTRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND WRITE. - JP WRITERAN -; -; FUNCTION TO COMPUTE THE SIZE OF A RANDOM FILE. -; -FILESIZE: - CALL AUTOSEL ; SELECT PROPER DRIVE AND CHECK FILE LENGTH - JP RANSIZE -; -; FUNCTION #37. THIS ALLOWS A PROGRAM TO LOG OFF ANY DRIVES. -; ON ENTRY, SET (DE) TO CONTAIN A WORD WITH BITS SET FOR THOSE -; DRIVES THAT ARE TO BE LOGGED OFF. THE LOG-IN VECTOR AND THE -; WRITE PROTECT VECTOR WILL BE UPDATED. THIS MUST BE A M/PM -; SPECIAL FUNCTION. -; -LOGOFF: LD HL,(PARAMS) ; GET DRIVES TO LOG OFF. - LD A,L ; FOR EACH BIT THAT IS SET, WE WANT - CPL ; TO CLEAR THAT BIT IN (LOGIN) - LD E,A ; AND (WRTPRT). - LD A,H - CPL - LD HL,(LOGIN) ; RESET THE LOGIN VECTOR. - AND H - LD D,A - LD A,L - AND E - LD E,A - LD HL,(WRTPRT) - EX DE,HL - LD (LOGIN),HL ; AND SAVE. - LD A,L ; NOW DO THE WRITE PROTECT VECTOR. - AND E - LD L,A - LD A,H - AND D - LD H,A - LD (WRTPRT),HL ; AND SAVE. ALL DONE. - RET -; -; GET HERE TO RETURN TO THE USER. -; -GOBACK: LD A,(AUTO) ; WAS AUTO SELECT ACTIVATED? - OR A - JP Z,GOBACK1 - LD HL,(PARAMS) ; YES, BUT WAS A CHANGE MADE? - LD (HL),0 ; (* RESET FIRST BYTE OF FCB *) - LD A,(AUTOFLAG) - OR A - JP Z,GOBACK1 - LD (HL),A ; YES, RESET FIRST BYTE PROPERLY. - LD A,(OLDDRV) ; AND GET THE OLD DRIVE AND SELECT IT. - LD (EPARAM),A - CALL SETDSK -GOBACK1:LD HL,(USRSTACK) ; RESET THE USERS STACK POINTER. - LD SP,HL - LD HL,(STATUS) ; GET RETURN STATUS. - LD A,L ; FORCE VERSION 1.4 COMPATABILITY. - LD B,H - RET ; AND GO BACK TO USER. -; -; FUNCTION #40. THIS IS A SPECIAL ENTRY TO DO RANDOM I/O. -; FOR THE CASE WHERE WE ARE WRITING TO UNUSED DISK SPACE, THIS -; SPACE WILL BE ZEROED OUT FIRST. THIS MUST BE A M/PM SPECIAL -; PURPOSE FUNCTION, BECAUSE WHY WOULD ANY NORMAL PROGRAM EVEN -; CARE ABOUT THE PREVIOUS CONTENTS OF A SECTOR ABOUT TO BE -; WRITTEN OVER. -; -WTSPECL:CALL AUTOSEL ; SELECT PROPER DRIVE. - LD A,2 ; USE SPECIAL WRITE MODE. - LD (MODE),A - LD C,0 ; SET WRITE INDICATOR. - CALL POSITN1 ; POSITION THE FILE. - CALL Z,WTSEQ1 ; AND WRITE (IF NO ERRORS). - RET -; -;************************************************************** -;* -;* BDOS DATA STORAGE POOL. -;* -;************************************************************** -; -EMPTYFCB: - .DB 0E5H ; EMPTY DIRECTORY SEGMENT INDICATOR. -WRTPRT: .DW 0 ; WRITE PROTECT STATUS FOR ALL 16 DRIVES. -LOGIN: .DW 0 ; DRIVE ACTIVE WORD (1 BIT PER DRIVE). -USERDMA:.DW 080H ; USER'S DMA ADDRESS (DEFAULTS TO 80H). -; -; SCRATCH AREAS FROM PARAMETER BLOCK. -; -SCRATCH1: - .DW 0 ; RELATIVE POSITION WITHIN DIR SEGMENT FOR FILE (0-3). -SCRATCH2: - .DW 0 ; LAST SELECTED TRACK NUMBER. -SCRATCH3: - .DW 0 ; LAST SELECTED SECTOR NUMBER. -; -; DISK STORAGE AREAS FROM PARAMETER BLOCK. -; -DIRBUF: .DW 0 ; ADDRESS OF DIRECTORY BUFFER TO USE. -DISKPB: .DW 0 ; CONTAINS ADDRESS OF DISK PARAMETER BLOCK. -CHKVECT:.DW 0 ; ADDRESS OF CHECK VECTOR. -ALOCVECT: - .DW 0 ; ADDRESS OF ALLOCATION VECTOR (BIT MAP). -; -; PARAMETER BLOCK RETURNED FROM THE BIOS. -; -SECTORS:.DW 0 ; SECTORS PER TRACK FROM BIOS. -BLKSHFT:.DB 0 ; BLOCK SHIFT. -BLKMASK:.DB 0 ; BLOCK MASK. -EXTMASK:.DB 0 ; EXTENT MASK. -DSKSIZE:.DW 0 ; DISK SIZE FROM BIOS (NUMBER OF BLOCKS-1). -DIRSIZE:.DW 0 ; DIRECTORY SIZE. -ALLOC0: .DW 0 ; STORAGE FOR FIRST BYTES OF BIT MAP (DIR SPACE USED). -ALLOC1: .DW 0 -OFFSET: .DW 0 ; FIRST USABLE TRACK NUMBER. -XLATE: .DW 0 ; SECTOR TRANSLATION TABLE ADDRESS. -; -; -CLOSEFLG: - .DB 0 ; CLOSE FLAG (=0FFH IS EXTENT WRITTEN OK). -R.DWRTFLG: - .DB 0 ; READ/WRITE FLAG (0FFH=READ, 0=WRITE). -FNDSTAT:.DB 0 ; FILENAME FOUND STATUS (0=FOUND FIRST ENTRY). -MODE: .DB 0 ; I/O MODE SELECT (0=RANDOM, 1=S.EQUENTIAL, 2=SPECIAL RANDOM). -EPARAM: .DB 0 ; STORAGE FOR REGISTER (E) ON ENTRY TO BDOS. -RELBLOCK: - .DB 0 ; RELATIVE POSITION WITHIN FCB OF BLOCK NUMBER WRITTEN. -COUNTER:.DB 0 ; BYTE COUNTER FOR DIRECTORY NAME SEARCHES. -SAVEFCB:.DW 0,0 ; SAVE SPACE FOR ADDRESS OF FCB (FOR DIRECTORY SEARCHES). -BIGDISK:.DB 0 ; IF =0 THEN DISK IS > 256 BLOCKS LONG. -AUTO: .DB 0 ; IF NON-ZERO, THEN AUTO SELECT ACTIVATED. -OLDDRV: .DB 0 ; ON AUTO SELECT, STORAGE FOR PREVIOUS DRIVE. -AUTOFLAG: - .DB 0 ; IF NON-ZERO, THEN AUTO SELECT CHANGED DRIVES. -SAVNXT: .DB 0 ; STORAGE FOR NEXT RECORD NUMBER TO ACCESS. -SAVEXT: .DB 0 ; STORAGE FOR EXTENT NUMBER OF FILE. -SAVNREC:.DW 0 ; STORAGE FOR NUMBER OF RECORDS IN FILE. -BLKNMBR:.DW 0 ; BLOCK NUMBER (PHYSICAL SECTOR) USED WITHIN A FILE OR LOGICAL SEC -LOGSECT:.DW 0 ; STARTING LOGICAL (128 BYTE) SECTOR OF BLOCK (PHYSICAL SECTOR). -FCBPOS: .DB 0 ; RELATIVE POSITION WITHIN BUFFER FOR FCB OF FILE OF INTEREST. -FILEPOS:.DW 0 ; FILES POSITION WITHIN DIRECTORY (0 TO MAX ENTRIES -1). -; -; DISK DIRECTORY BUFFER CHECKSUM BYTES. ONE FOR EACH OF THE -; 16 POSSIBLE DRIVES. -; -CKSUMTBL: - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; -BIOS: .EQU BIOSO ;BIOS ORIGIN -; -BOOT: .EQU BIOS ;(BOOT) Cold boot entry -WBOOT: .EQU BIOS+3 ;Warm boot entry -CONST: .EQU BIOS+6 ;Console status -CONIN: .EQU BIOS+9 ;Console char in -CONOUT: .EQU BIOS+12 ;Console char out -LIST: .EQU BIOS+15 ;List char out -PUNCH: .EQU BIOS+18 ;Punch char out -READER: .EQU BIOS+21 ;Reader char in -HOME: .EQU BIOS+24 ;Home disk -SELDSK: .EQU BIOS+27 ;Select disk -SETTRK: .EQU BIOS+30 ;Set disk track addr -SETSEC: .EQU BIOS+33 ;Set disk sector addr -SETDMA: .EQU BIOS+36 ;Set DMA buffer addr -READ: .EQU BIOS+39 ;Read sector -WRITE: .EQU BIOS+42 ;Write sector -SECTRN: .EQU BIOS+48 ;Sector translation routine -; - .IF ENDFIL - .FILL ((BDOSO + 0E00H) - $),055H - .ENDIF - - .END diff --git a/branches/s100/Source/bioshdr.inc b/branches/s100/Source/bioshdr.inc deleted file mode 100644 index 4ee1e8e1..00000000 --- a/branches/s100/Source/bioshdr.inc +++ /dev/null @@ -1,131 +0,0 @@ -; bioshdr.inc 5/10/2012 dwg - offsets into the BIOS Header data - -B_BOOT .equ 0e600h -B_WBOOT .equ 0e603h -B_CONST .equ 0e606h -B_CONIN .equ 0e609h -B_CONOUT .equ 0e60ch -B_LIST .equ 0e60fh -B_PUNCH .equ 0e612h -B_READER .equ 0e615h -B_HOME .equ 0e618h -B_SELDSK .equ 0e61bh -B_SETTRK .equ 0e61eh -B_SETSEC .equ 0e621h -B_SETDMA .equ 0e624h -B_READ .equ 0e627h -B_WRITE .equ 0e62ah -B_LISTST .equ 0e62dh -B_SECTRN .equ 0e630h -B_BNKSEL .equ 0e633h -B_GETLU .equ 0e636h -B_SETLU .equ 0e639h -B_GETINFO .equ 0e63ch -B_RSVD1 .equ 0e63fh -B_RSVD2 .equ 0e642h -B_RSVD3 .equ 0e645h -B_RSVD4 .equ 0e648h - -B_CNFGDATA .equ 0e64bh - -B_RMJ .equ 0e64bh -B_RMN .equ 0e64ch -B_RUP .equ 0e64dh -B_RTP .equ 0e64eh -B_DSKBOOT .equ 0e64fh -B_BOOTDRV .equ 0e650h - -B_MONTH .equ 0e651h -B_DAY .equ 0e652h -B_YEAR .equ 0e653h - -B_HOUR .equ 0e654h -B_MIN .equ 0e655h -B_SEC .equ 0e656h - -; Config Proper Start Here - -B_FREQ .equ 0e657h -B_PLATFORM .equ B_FREQ+1 -B_DIOPLAT .equ B_PLATFORM+1 -B_VDUMODE .equ B_DIOPLAT+1 -B_ROMSIZE .equ B_VDUMODE+1 -B_RAMSIZE .equ B_ROMSIZE+2 -B_CLRRAMDSK .equ B_RAMSIZE+2 -B_DSKYENABLE .equ B_CLRRAMDSK+1 -B_UARTENABLE .equ B_DSKYENABLE+1 -B_VDUENABLE .equ B_UARTENABLE+1 -B_FDENABLE .equ B_VDUENABLE+1 -B_FDTRACE .equ B_FDENABLE+1 -B_FDMEDIA .equ B_FDTRACE+1 -B_FDMEDIAALT .equ B_FDMEDIA+1 -B_FDMAUTO .equ B_FDMEDIAALT+1 -B_IDEENABLE .equ B_FDMAUTO+1 -B_IDETRACE .equ B_IDEENABLE+1 -B_IDE8BIT .equ B_IDETRACE+1 -B_IDECAPACITY .equ B_IDE8BIT+1 -B_PPIDEENABLE .equ B_IDECAPACITY+2 -B_PPIDETRACE .equ B_PPIDEENABLE+1 -B_PPIDE8BIT .equ B_PPIDETRACE+1 -B_PPIDECAPACITY .equ B_PPIDE8BIT+1 -B_PPIDESLOW .equ B_PPIDECAPACITY+2 -B_BOOTTYPE .equ B_PPIDESLOW+1 -B_BAUDRATE .equ B_BOOTTYPE+1 -B_CLKDIV .equ B_BAUDRATE+2 - -B_MEMWAIT .equ B_CLKDIV+1 -B_IOWAIT .equ B_MEMWAIT+1 -B_CNTLB0 .equ B_IOWAIT+1 -B_CNTLB1 .equ B_CNTLB0+1 -B_SDCAPACITY .equ B_CNTLB1+1 -B_SDCSIO .equ B_SDCAPACITY+2 -B_SDCSIOFAST .equ B_SDCSIO+1 -B_DEFIOBYTE .equ B_SDCSIOFAST+1 -B_TERMTYPE .equ B_DEFIOBYTE+1 -B_REVISION .equ B_TERMTYPE+1 -B_PRPSDENABLE .equ B_REVISION+2 -B_PRPSDTRACE .equ B_PRPSDENABLE+1 -B_PRPSDCAPACITY .equ B_PRPSDTRACE+1 -B_PRPCONENABLE .equ B_PRPSDCAPACITY+2 -B_DATASIZE .equ B_PRPCONENABLE+1 - - -B_INFOVER .equ 0 -B_STRBANNER .equ B_INFOVER+2 -B_VARLOC .equ B_STRBANNER+2 -B_TSTLOC .equ B_VARLOC+2 -B_SECADR .equ B_TSTLOC+2 -B_SEKDSK .equ B_SECADR+2 -B_SEKTRK .equ B_SEKDSK+2 -B_SEKSEC .equ B_SEKTRK+2 -B_DSKOP .equ B_SEKSEC+2 -B_DMAADR .equ B_DSKOP+2 -B_DPHADR .equ B_DMAADR+2 -B_XLT .equ B_DPHADR+2 -B_HST .equ B_XLT+2 -B_DIRBF .equ B_HST+2 -B_DPBMAP .equ B_DIRBF+2 -B_DSKMAP .equ B_DPBMAP+2 -B_DPHMAP .equ B_DSKMAP+2 -B_CIOMAP .equ B_DPHMAP+2 -B_SECBUF .equ B_CIOMAP+2 -B_ORGFDDATA .equ B_SECBUF+2 -B_ORGIDEDATA .equ B_ORGFDDATA+2 -B_ORGSDDATA .equ B_ORGIDEDATA+2 -B_ORGPRPSDDATA .equ B_ORGSDDATA+2 -B_ORGPPPSDDATA .equ B_ORGPRPSDDATA+2 -B_INFOTBLSIZE .equ B_ORGPPPSDDATA+2 - -;;;;;;;;;;;;;;;;;;;;; -; eof - bioshdr.inc ; -;;;;;;;;;;;;;;;;;;;;; - - - - - - - - - - diff --git a/branches/s100/Source/blank1024KB.dat b/branches/s100/Source/blank1024KB.dat deleted file mode 100644 index d4f7033b..00000000 --- a/branches/s100/Source/blank1024KB.dat +++ /dev/null @@ -1 +0,0 @@ -åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå \ No newline at end of file diff --git a/branches/s100/Source/blank512KB.dat b/branches/s100/Source/blank512KB.dat deleted file mode 100644 index f353b2bb..00000000 --- a/branches/s100/Source/blank512KB.dat +++ /dev/null @@ -1 +0,0 @@ -åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå \ No newline at end of file diff --git a/branches/s100/Source/bootapp.asm b/branches/s100/Source/bootapp.asm deleted file mode 100644 index a38f3ef3..00000000 --- a/branches/s100/Source/bootapp.asm +++ /dev/null @@ -1,144 +0,0 @@ -;___BOOTAPP____________________________________________________________________________________________________________ -; -; APPLICATION BOOT MANAGER -; -; USED TO LOAD AN APPLICATION IMAGE BASED COPY OF THE SYSTEM -; REFER TO BANKEDBIOS.TXT FOR MORE INFORMATION. -;______________________________________________________________________________________________________________________ -; -; -#INCLUDE "std.asm" -; - .ORG $100 -; - DI ; NO INTERRUPTS - IM 1 ; INTERRUPT MODE 1 - LD SP,$FF00 ; START WITH SP BELOW HBIOS PROXY LOCATION -; -; LD BC,0 -;XXX: -; DJNZ XXX -; DEC C -; JR NZ,XXX -; -; PERFORM MINIMAL Z180 SPECIFIC INITIALIZATION -; -#IF (PLATFORM == PLT_N8) - ; SET BASE FOR CPU IO REGISTERS - LD A,CPU_BASE - OUT0 (CPU_ICR),A - - ; SET CPU CLOCK DIV - LD A,Z180_CLKDIV << 7 - OUT0 (CPU_CCR),A - - ; SET WAIT STATES - LD A,0 + (Z180_MEMWAIT << 6) | (Z180_IOWAIT << 4) - OUT0 (CPU_DCNTL),A - - ; MMU SETUP - LD A,80H - OUT0 (CPU_CBAR),A ; SETUP FOR 32K/32K BANK CONFIG - XOR A - OUT0 (CPU_BBR),A ; BANK BASE = 0 - LD A,(RAMSIZE - 64) >> 2 - OUT0 (CPU_CBR),A ; COMMON BASE = LAST (TOP) BANK -#ENDIF -; -; EMIT FIRST SIGN OF LIFE TO SERIAL PORT -; - CALL XIO_INIT ; INIT SERIAL PORT - LD HL,STR_BOOT ; POINT TO MESSAGE - CALL XIO_OUTS ; SAY HELLO -; -; RELOCATE MONITOR/OS CODE FROM 8000H TO C000H -; - HBIOS PROXY AT $FF00 IS OVERLAID, BUT WE DON'T CARE -; ABOUT IT ANYMORE, IT WILL BE REFRESHED DURING HBIOS -; INIT LATER. -; -; NOTE: STACK IS WIPED OUT, STACK IS ASSUMED TO BE EMPTY HERE!!!! -; - LD HL,$8000 ; COPY MEMORY FROM 8000 - LD DE,$C000 ; TO C000 - LD BC,$4000 ; COPY 16K - LDIR -; - CALL XIO_DOT ; MARK PROGRESS -; -; COPY FIRST $1000 BYTES TO $8000 (UPPER, NON-BANKED MEMORY) -; THIS INCLUDES OURSELVES AND THE LOADER CODE -; -; RELOCATE BOOT PHASE 2 AND LOADER CODE FROM 0000H TO 8000H -; - LD HL,$0000 ; COPY MEMORY FROM 0000 - LD DE,$8000 ; TO 8000H - LD BC,$1000 ; COPY 1000H BYTES - LDIR -; - CALL XIO_DOT ; MARK PROGRESS -; - JP PHASE2 ; JUMP TO PHASE 2 BOOT IN UPPER MEMORY -; -STR_BOOT .DB "Boot$" -; -; IMBED DIRECT SERIAL I/O ROUTINES -; -#INCLUDE "xio.asm" -; -;______________________________________________________________________________________________________________________ -; -; THIS IS THE PHASE 2 CODE THAT MUST EXECUTE IN UPPER MEMORY -; - .ORG $ + $8000 ; WE ARE NOW EXECUTING IN UPPER MEMORY -; -PHASE2: - CALL XIO_DOT ; MARK PROGRESS -; -; COPY RAMPG0 TO RAMPG1 -; - LD HL,0 ; HL = LOCATION IN LOMEM TO COPY FROM/TO -LOOP: - LD DE,$9000 ; DE = BUFFER ADDRESS - LD BC,$1000 ; BYTES TO COPY (4K CHUNKS) - PUSH BC ; SAVE COPY SIZE - PUSH DE ; SAVE COPY DEST - PUSH HL ; SAVE COPY SOURCE - LD A,0 ; SELECT PAGE 1 - CALL RAMPG ; OF ROM FOR COPY - LDIR ; COPY ROM -> BUFFER - POP DE ; RESTORE SOURCE AS NEW DESTINATION - POP HL ; RESTORE DESTINATION AS NEW SOURCE - POP BC ; RESTORE COPY SIZE - LD A,1 ; SELECT PAGE 1 - CALL RAMPG ; OF RAM FOR COPY - LDIR ; COPY BUFFER -> RAM - EX DE,HL ; GET LOMEM POINTER BACK TO HL - LD A,H ; HIGH BYTE OF POINTER TO A - CP $80 ; HIGH BYTE WILL BE 80H WHEN WE ARE DONE - JP NZ,LOOP ; IF NOT DONE, LOOP TO DO NEXT 4K CHUNK -; - CALL XIO_DOT ; MARK PROGRESS -; -; INITIALIZE HBIOS AND JUMP TO LOADER -; - ; CALL HBIOS HARDWARE INITIALIZATION - CALL $1000 ; CALL HBIOS INITIALIZATION -; - ; CALL HBIOS PROXY INITIALIZATION - CALL RAMPGZ ; MAKE SURE RAM PAGE ZERO IS MAPPED TO LOWER 32K - CALL $FF20 ; CALL HBIOS PROXY INITIALIZATION -; - JP $8400 ; JUMP TO LOADER -;______________________________________________________________________________________________________________________ -; -; NOTE THAT MEMORY MANAGER CODE IS IN UPPER MEMORY! -; -#INCLUDE "memmgr.asm" -;______________________________________________________________________________________________________________________ -; -; PAD OUT REMAINDER OF PAGE -; - .ORG $ - $8000 ; ORG BACK TO LOWER MEMORY - .FILL $0200 - $,$FF ; PAD OUT REMAINDER OF PAGE -; - .END diff --git a/branches/s100/Source/bootgen.asm b/branches/s100/Source/bootgen.asm deleted file mode 100644 index 973d476e..00000000 --- a/branches/s100/Source/bootgen.asm +++ /dev/null @@ -1,424 +0,0 @@ -;___BOOTGEN___________________________________________________________________________________________________________ -; -; COPY THE SYSTEM TO THE BOOT SECTORS OF AN IDE HDD -; -; CREATED BY : DAN WERNER 09 12.2009 -; -; -; -; -;__CONSTANTS_________________________________________________________________________________________________________________________ -; -CR: .EQU 0DH ; ASCII CARRIAGE RETURN CHARACTER -LF: .EQU 0AH ; ASCII LINE FEED CHARACTER -ESC: .EQU 1BH ; ASCII ESCAPE CHARACTER -BS: .EQU 08H ; ASCII BACKSPACE CHARACTER - -; -; -; -;__MAIN_PROGRAM_____________________________________________________________________________________________________________________ -; - .ORG 00100h ; FOR DEBUG IN CP/M (AS .COM) - - - LD HL,(0001H) ; GET WBOOT ADDRESS - LD BC,1603H ; GET CP/M TOP - SBC HL,BC ; - LD (CPMSTART),HL ; SET IT - DEC HL ; - LD SP,HL ; SETUP STACK - - -; PARSE COMMAND LINE - LD HL,0081H ; SET INDEX POINTER - LD B,(0080H) ; NUMBER OF BYTES -PARSECMD: - LD A,(HL) ; GET DRIVE LETTER ON COMMAND LINE - INC HL - CP 20H ; IS SPACE? - JP NZ,PARSEGOT ; JUMP ON NON-BLANK - DJNZ PARSECMD ; LOOP -PARSEERR: - LD DE,MSG_VALID ; - LD C,09H ; CP/M WRITE START STRING TO CONSOLE CALL - CALL 0005H - JP EXIT ; EXIT -PARSEGOT: - SUB 'A' ; TURN IT INTO A NUMERIC - JP C,PARSEERR ; - CP 16 ; VALID CP/M DRIVE? - JP P,PARSEERR ; - LD (DEVICENUMBER),A ; DEVICE ID - ; GET NUMBER OF SECTORS PER TRACK - LD L,A ; L=DISK NUMBER 0,1,2,3,4 - LD H,0 ; HIGH ORDER ZERO - ADD HL,HL ; *2 - ADD HL,HL ; *4 - ADD HL,HL ; *8 - ADD HL,HL ; *16 (SIZE OF EACH HEADER) - PUSH HL ; - POP DE - LD HL,(0001H) ; - LD BC,0058 ; - ADD HL,BC ; - ADD HL,DE ; HL= DPBASE(DISKNO*16) - EX DE,HL ; - LD A,(DE) ; - LD L,A ; - INC DE ; - LD A,(DE) ; - LD H,A ; - EX DE,HL ; - LD A,(DE) ; - LD (SECTRACK),A ; - INC DE ; - LD A,(DE) ; - LD (SECTRACK+1),A ; - - LD DE,DRIVE_MSG ; - LD C,09H ; CP/M WRITE START STRING TO CONSOLE CALL - CALL 0005H - LD A,(DEVICENUMBER) ; - ADD A,'A' ; - CALL COUT ; - LD A,':' ; - CALL COUT ; - CALL CRLF ; - - - LD DE,BASE_MSG ; - LD C,09H ; CP/M WRITE START STRING TO CONSOLE CALL - CALL 0005H - LD HL,(CPMSTART) ; - CALL PHL ; - LD DE,END_MSG ; - LD C,09H ; CP/M WRITE START STRING TO CONSOLE CALL - CALL 0005H - LD HL,(CPMEND) ; - CALL PHL ; - CALL CRLF ; - - LD DE,SECTOR_MSG ; - LD C,09H ; CP/M WRITE START STRING TO CONSOLE CALL - CALL 0005H - LD HL,(SECTRACK) ; - CALL PHL ; - CALL CRLF ; - - -; RUN WITH GOOD OUTPUT - - LD A,(DEVICENUMBER) ; SET DEVICE NUMBER - LD C,A - CALL SELDSK ; SELECT DISK - - LD HL,000CH ; SET INITIAL SECTOR - LD (CURSECTOR),HL - - LD HL,0000H ; SET INITIAL TRACK - LD (CURTRACK),HL ; - - LD HL,(CPMSTART) ; SET BEGINNING OF CPM - LD (CURADDRESS),HL ; - - LD BC,(DMAAD) ; SETUP THE DMA AREA - CALL SETDMA ; - -LOOP: - LD BC,(CURSECTOR) ; SET SECTOR - CALL SETSEC ; - LD BC,(CURTRACK) ; - CALL SETTRK ; - CALL COPYTODMA ; COPY BYTES TO DMA - CALL WRITE ; WRITE SECTOR - - LD HL,(CURADDRESS) ; IF IX>CPMEND, EXIT PROGRAM - LD BC,(CPMEND) ; - LD A,H ; - CP B ; - JP NZ,CONTINUE ; - LD A,L ; - CP C ; - JP M,ENDLOOP ; -CONTINUE: - LD HL,(CURSECTOR) ; GET NEXT TRACK & SECTOR - INC HL ; - LD (CURSECTOR),HL ; - LD BC,(SECTRACK) ; - LD A,H ; - CP B ; - JP NZ,LOOP ; - LD A,L ; - CP C ; - JP NZ,LOOP ; - - LD HL,(CURTRACK) ; - INC HL ; - LD (CURTRACK),HL ; - LD HL,0000H ; - LD (CURSECTOR),HL ; - JP LOOP ; - -ENDLOOP: -; WRITE CP/M BOOT START AND END ADDRESSES IN LAST TWO WORDS OF MEDIA INFO SECTOR - LD BC,000BH ; SET SECTOR - CALL SETSEC ; - LD BC,0000H ; - CALL SETTRK ; - CALL READ ; - LD HL,(DMAAD) ; SET ADDRESS IN BUFFER TO LAST TWO WORDS - LD BC,122 ; - ADD HL,BC ; - LD A,(CPMSTART) ; - LD (HL),A ; - LD A,(CPMSTART+1) ; - INC HL - LD (HL),A ; - LD A,(CPMEND) ; - INC HL - LD (HL),A ; - LD A,(CPMEND+1) ; - INC HL - LD (HL),A ; - LD A,(0001H) ; - DEC A ; - DEC A ; - DEC A ; - INC HL - LD (HL),A ; - LD A,(0002H) ; - INC HL - LD (HL),A ; - CALL WRITE ; WRITE SECTOR - -EXIT: - - LD DE,MSG_END ; - LD C,09H ; CP/M WRITE END STRING TO CONSOLE CALL - CALL 0005H ; - ; - LD C,00H ; CP/M SYSTEM RESET CALL - CALL 0005H ; RETURN TO PROMPT - - - - - -;___COPYTODMA_____________________________________________________________________________________ -; -; COPY CURRENT ADDRESS BLOCK TO DMA -;_________________________________________________________________________________________________ -COPYTODMA: - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,(CURADDRESS) ; GET RAM ADDRESS TO COPY - LD BC,128 ; BC IS COUNTER FOR FIXED SIZE TRANSFER (128 BYTES) - LDIR ; TRANSFER - LD HL,(CURADDRESS) ; INCREMENT ADDRESS POINTER BY COPY SIZE - LD BC,128 ; - ADD HL,BC ; - LD (CURADDRESS),HL ; - RET - - - - - - - -;__HXOUT_________________________________________________________________________________________________________________________ -; -; PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -HXOUT: - PUSH BC ; SAVE BC - LD B,A ; - RLC A ; DO HIGH NIBBLE FIRST - RLC A ; - RLC A ; - RLC A ; - AND 0FH ; ONLY THIS NOW - ADD A,30H ; TRY A NUMBER - CP 3AH ; TEST IT - JR C,OUT1 ; IF CY SET PRINT 'NUMBER' - ADD A,07H ; MAKE IT AN ALPHA -OUT1: - CALL COUT ; SCREEN IT - LD A,B ; NEXT NIBBLE - AND 0FH ; JUST THIS - ADD A,30H ; TRY A NUMBER - CP 3AH ; TEST IT - JR C,OUT2 ; PRINT 'NUMBER' - ADD A,07H ; MAKE IT ALPHA -OUT2: - CALL COUT ; SCREEN IT - POP BC ; RESTORE BC - RET ; - - -;__SPACE_________________________________________________________________________________________________________________________ -; -; PRINT A SPACE CHARACTER ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -SPACE: - PUSH AF ; STORE AF - LD A,20H ; LOAD A "SPACE" - CALL COUT ; SCREEN IT - POP AF ; RESTORE AF - RET ; DONE - -;__CRLF_________________________________________________________________________________________________________________________ -; -; PRINT A CR/LF -;________________________________________________________________________________________________________________________________ -; -CRLF: - PUSH AF ; STORE AF - LD A,0DH ; LOAD A "SPACE" - CALL COUT ; SCREEN IT - LD A,0AH ; LOAD A "SPACE" - CALL COUT ; SCREEN IT - POP AF ; RESTORE AF - RET ; DONE - -;__COUT_________________________________________________________________________________________________________________________ -; -; PRINT CONTENTS OF A -;________________________________________________________________________________________________________________________________ -; -COUT: - PUSH BC ; - PUSH AF ; - PUSH HL ; - PUSH DE ; - - LD (COUT_BUFFER),A ; - LD DE,COUT_BUFFER ; - LD C,09H ; CP/M WRITE START STRING TO CONSOLE CALL - CALL 0005H - POP DE ; - POP HL ; - POP AF ; - POP BC ; - RET ; DONE - - - - -;__PHL_________________________________________________________________________________________________________________________ -; -; PRINT THE HL REG ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -PHL: - LD A,H ; GET HI BYTE - CALL HXOUT ; DO HEX OUT ROUTINE - LD A,L ; GET LOW BYTE - CALL HXOUT ; HEX IT - CALL SPACE ; - RET ; DONE - -COUT_BUFFER: - .DB 00 - .DB "$" - -BASE_MSG: - .TEXT "CP/M IMAGE=" - .db "$" -END_MSG: - .TEXT "TO " - .db "$" -SECTOR_MSG: - .TEXT "SECTORS/TRACK=" - .db "$" - -DRIVE_MSG: - .TEXT "DRIVE=" - .db "$" - - -;__CBIOS_________________________________________________________________________________________________________________________ -; -; CBIOS JUMP TABLE -;________________________________________________________________________________________________________________________________ -; - -SELDSK: ;SELECT DISK - PUSH BC ; - LD HL,(0001H) ; - LD BC,0024 ; - ADD HL,BC ; - POP BC ; - JP (HL) ; -SETTRK: ;SET DISK TRACK ADDR - PUSH BC ; - LD HL,(0001H) ; - LD BC,0027 ; - ADD HL,BC ; - POP BC ; - JP (HL) ; -SETSEC: ;SET DISK SECTOR ADDR - PUSH BC ; - LD HL,(0001H) ; - LD BC,0030 ; - ADD HL,BC ; - POP BC ; - JP (HL) ; -SETDMA: ;SET DMA BUFFER ADDR - PUSH BC ; - LD HL,(0001H) ; - LD BC,0033 ; - ADD HL,BC ; - POP BC ; - JP (HL) ; -READ: ;READ SECTOR - PUSH BC ; - LD HL,(0001H) ; - LD BC,0036 ; - ADD HL,BC ; - POP BC ; - JP (HL) ; -WRITE: ;WRITE SECTOR - PUSH BC ; - LD HL,(0001H) ; - LD BC,0039 ; - ADD HL,BC ; - POP BC ; - JP (HL) ; - - - -CURTRACK: .DW 0 ; CURRENT TRACK -CURSECTOR: .DW 0 ; CURRENT SECTOR -CURADDRESS: .DW 0 ; CURRENT CP/M ADDRESS -DMAAD: .DW 5000H ; DIRECT MEMORY ADDRESS - -CPMEND: .DW 0FDFFH ; END OF CP/M -SECTRACK: .DW 0100H ; SECTORS PER TRACK -CPMSTART: .DW 0D000H ; START OF CP/M -DEVICENUMBER: .DB 2 ; DEVICE ID - - - -MSG_END: - .DB LF, CR ; LINE FEED AND CARRIAGE RETURN - .TEXT "BOOTGEN COMPLETED." - .DB LF, CR ; LINE FEED AND CARRIAGE RETURN - .DB "$" ; LINE TERMINATOR -MSG_VALID: - .DB LF, CR ; LINE FEED AND CARRIAGE RETURN - .TEXT "USAGE: BOOTGEN (DRIVE):" - .DB LF, CR ; LINE FEED AND CARRIAGE RETURN - .TEXT "(DRIVE) IS ANY VALID CP/M DRIVE:" - .DB LF, CR ; LINE FEED AND CARRIAGE RETURN - .DB "$" ; LINE TERMINATOR - - - .END - - - \ No newline at end of file diff --git a/branches/s100/Source/bootrom.asm b/branches/s100/Source/bootrom.asm deleted file mode 100644 index 81220311..00000000 --- a/branches/s100/Source/bootrom.asm +++ /dev/null @@ -1,127 +0,0 @@ -;___BOOTROM____________________________________________________________________________________________________________ -; -; ROM BOOT MANAGER -; -; HARDWARE COLD START WILL JUMP HERE FOR INITIALIZATION -; REFER TO BANKEDBIOS.TXT FOR MORE INFORMATION. -;______________________________________________________________________________________________________________________ -; -; -#INCLUDE "std.asm" -; - .ORG $100 -; - DI ; NO INTERRUPTS - IM 1 ; INTERRUPT MODE 1 - LD SP,$FF00 ; START WITH SP BELOW HBIOS PROXY LOCATION -; -; PERFORM MINIMAL Z180 SPECIFIC INITIALIZATION -; -#IF (PLATFORM == PLT_N8) - ; SET BASE FOR CPU IO REGISTERS - LD A,CPU_BASE - OUT0 (CPU_ICR),A - - ; SET CPU CLOCK DIV - LD A,Z180_CLKDIV << 7 - OUT0 (CPU_CCR),A - - ; SET WAIT STATES - LD A,0 + (Z180_MEMWAIT << 6) | (Z180_IOWAIT << 4) - OUT0 (CPU_DCNTL),A - - ; MMU SETUP - LD A,$80 - OUT0 (CPU_CBAR),A ; SETUP FOR 32K/32K BANK CONFIG - XOR A - OUT0 (CPU_BBR),A ; BANK BASE = 0 - LD A,(RAMSIZE - 64) >> 2 - OUT0 (CPU_CBR),A ; COMMON BASE = LAST (TOP) BANK -#ENDIF -; -; EMIT FIRST SIGN OF LIFE TO SERIAL PORT -; - CALL XIO_INIT ; INIT SERIAL PORT - LD HL,STR_BOOT ; POINT TO MESSAGE - CALL XIO_OUTS ; SAY HELLO -; -; COPY ENTIRE CONTENTS OF ROM BANK 0 TO HI RAM -; THIS INCLUDES OURSELVES AND THE LOADER CODE -; - HBIOS PROXY AT $FF00 IS OVERLAID, BUT WE DON'T CARE -; BECAUSE IT WILL BE REFRESHED DURING HBIOS -; INIT LATER. -; -; NOTE: STACK IS WIPED OUT, STACK IS ASSUMED TO BE EMPTY HERE!!!! -; - LD HL,$0000 ; COPY MEMORY FROM LOMEM (0000H) - LD DE,$8000 ; TO HIMEM (8000H) - LD BC,$8000 ; COPY ENTIRE BANK, 8000H BYTES - LDIR -; - CALL XIO_DOT ; MARK PROGRESS -; - JP PHASE2 ; JUMP TO PHASE 2 BOOT IN UPPER MEMORY -; -STR_BOOT .DB "Boot$" -; -; IMBED DIRECT SERIAL I/O ROUTINES -; -#INCLUDE "xio.asm" -; -;______________________________________________________________________________________________________________________ -; -; THIS IS THE PHASE 2 CODE THAT MUST EXECUTE IN UPPER MEMORY -; - .ORG $ + $8000 ; WE ARE NOW EXECUTING IN UPPER MEMORY -; -PHASE2: - CALL XIO_DOT ; MARK PROGRESS -; -; COPY ROMPG1 TO RAMPG1 -; - LD HL,0 ; HL = LOCATION IN LOMEM TO COPY FROM/TO -LOOP: - LD DE,$9000 ; DE = BUFFER ADDRESS - LD BC,$1000 ; BYTES TO COPY (4K CHUNKS) - PUSH BC ; SAVE COPY SIZE - PUSH DE ; SAVE COPY DEST - PUSH HL ; SAVE COPY SOURCE - LD A,1 ; SELECT PAGE 1 - CALL ROMPG ; OF ROM FOR COPY - LDIR ; COPY ROM -> BUFFER - POP DE ; RESTORE SOURCE AS NEW DESTINATION - POP HL ; RESTORE DESTINATION AS NEW SOURCE - POP BC ; RESTORE COPY SIZE - LD A,1 ; SELECT PAGE 1 - CALL RAMPG ; OF RAM FOR COPY - LDIR ; COPY BUFFER -> RAM - EX DE,HL ; GET LOMEM POINTER BACK TO HL - LD A,H ; HIGH BYTE OF POINTER TO A - CP $80 ; HIGH BYTE WILL BE $80 WHEN WE ARE DONE - JP NZ,LOOP ; IF NOT DONE, LOOP TO DO NEXT 4K CHUNK -; - CALL XIO_DOT ; MARK PROGRESS -; -; INITIALIZE HBIOS AND JUMP TO LOADER -; - ; CALL HBIOS HARDWARE INITIALIZATION - CALL $1000 ; CALL HBIOS INITIALIZATION -; - ; CALL HBIOS PROXY INITIALIZATION - CALL RAMPGZ ; MAKE SURE RAM PAGE ZERO IS MAPPED TO LOWER 32K - CALL $FF20 ; CALL HBIOS PROXY INITIALIZATION -; - JP $8400 ; JUMP TO LOADER -;______________________________________________________________________________________________________________________ -; -; NOTE THAT MEMORY MANAGER CODE IS IN UPPER MEMORY! -; -#INCLUDE "memmgr.asm" -;______________________________________________________________________________________________________________________ -; -; PAD OUT REMAINDER OF PAGE -; - .ORG $ - $8000 ; ORG BACK TO LOWER MEMORY - .FILL $200 - $,$FF ; PAD OUT REMAINDER OF PAGE -; - .END diff --git a/branches/s100/Source/btromwbw.inc b/branches/s100/Source/btromwbw.inc deleted file mode 100644 index 46a7c56f..00000000 --- a/branches/s100/Source/btromwbw.inc +++ /dev/null @@ -1,111 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; btromwbw.inc 2/17/2013 dwg - boot up CP/M, RomWBW Style ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Unlike the Monahan style of booting, the RomWBW loading ; -; is performed by reading in the metadata sector and using ; -; the three words at the end of the sector to determine the ; -; loading address and starting location. ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;-------------- BOOT UP CPM FROM HARD DISK ON S100COMPUTERS IDR BOARD ---------------- - -;BOOT UP THE 8255/IDE Board HARD DISK/Flash Memory Card -;NOTE CODE IS ALL HERE IN CASE A 2716 IS USED - -HBOOTWBW: - POP HL ;CLEAN UP STACK - - CALL INITILIZE_IDE_BOARD ;Initilze the 8255 and drive (again just in case) - - LD D,11100000B ;Data for IDE SDH reg (512bytes, LBA mode,single drive) - LD E,REGshd ;00001110,(0EH) CS0,A2,A1, - CALL IDEwr8D ;Write byte to select the MASTER device - - LD B,0FFH ;Delay time to allow a Hard Disk to get up to speed -WaitInitX: - LD E,REGstatus ;Get status after initilization - CALL IDErd8D ;Check Status (info in [D]) - BIT 7,D - JR Z,SECREADX ;Zero, so all is OK to write to drive - ;Delay to allow drive to get up to speed - PUSH BC - LD BC,0FFFFH -DXLAY2X: LD D,2 ;May need to adjust delay time to allow cold drive to -DXLAY1X: DEC D ;to speed - JR NZ,DXLAY1X - DEC BC - LD A,C - OR B - JR NZ,DXLAY2X - POP BC - DJNZ WaitInitX ;If after 0FFH, 0FEH, 0FDH... 0, then drive initilization problem -IDErrorX: - LD HL,DRIVE_NR_ERR ;Drive not ready - JP ABORT_ERR_MSG - -SECREADX: ;Note CPMLDR will ALWAYS be on TRK 0,SEC 1,Head 0 - CALL IDEwaitnotbusy ;Make sure drive is ready - JR C,IDErrorX ;NC if ready - LD D,1 ;Load track 0,sec 1, head 0 - LD E,REGsector ;Send info to drive - CALL IDEwr8D - - LD D,0 ;Send Low TRK# - LD E,REGcyLSB - CALL IDEwr8D - - LD D,0 ;Send High TRK# - LD E,REGcyMSB - CALL IDEwr8D - - LD D,SEC_COUNT ;Count of CPM sectors we wish to read - LD E,REGcnt - CALL IDEwr8D - - LD D,CMDread ;Send read CMD - LD E,REGCMD - CALL IDEwr8D ;Send sec read CMD to drive. - CALL IDEwdrq ;Wait until it's got the data - - LD HL,CPM_ADDRESS ;DMA address where the CPMLDR resides in RAM - LD B,0 ;256X2 bytes - LD C,SEC_COUNT ;Count of sectors X 512 -MoreRD16X: - LD A,REGdata ;REG regsiter address - OUT (IDECport),A - - OR IDErdline ;08H+40H, Pulse RD line - OUT (IDECport),A - - IN A,(IDEAport) ;read the LOWER byte - LD (HL),A - INC HL - IN A,(IDEBport) ;read the UPPER byte - LD (HL),A - INC HL - - LD A,REGdata ;Deassert RD line - OUT (IDECport),A - DJNZ MoreRD16X - DEC C - JR NZ,MoreRD16X - - LD E,REGstatus ;Check the R/W status when done - CALL IDErd8D - BIT 0,D - JR NZ,IDEerr1X ;Z if no errors - LD HL,STARTCPM - LD A,(HL) - CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H - JP Z,STARTCPM ;AS THE FIRST INSTRUCTION. IF OK JP to 100H in RAM - JP ERR_LD1 ;Boot Sector Data incorrect - -IDEerr1X: - LD HL,IDE_RW_ERROR ;Drive R/W Error - JP ABORT_ERR_MSG - -;;;;;;;;;;;;;;;;;;;;;; -; eof - btromwbw.inc ; -;;;;;;;;;;;;;;;;;;;;;; - diff --git a/branches/s100/Source/cbios.asm b/branches/s100/Source/cbios.asm deleted file mode 100644 index d7cd2569..00000000 --- a/branches/s100/Source/cbios.asm +++ /dev/null @@ -1,2123 +0,0 @@ -;__________________________________________________________________________________________________ -; -; CBIOS FOR N8VEM -; -; BY ANDREW LYNCH, WITH INPUT FROM MANY SOURCES -;__________________________________________________________________________________________________ -; -; cbios.asm 6/04/2012 dwg - added BOOTLU -; cbios.asm 5/21/2012 dwg - added peek and poke for bank 1 frame 0 -; cbios.asm 5/16/2012 dwg - new architecture for 2.0.0.0 Beta 3 -; - -; The std.asm file contains the majority of the standard equates -; that describe data sructures, magic values and bit fields used -; by the CBIOS. - -#INCLUDE "std.asm" -; -#INCLUDE "syscfg.exp" -; - .ORG CBIOS_LOC ; DEFINED IN STD.ASM -; -;================================================================================================== -; CP/M JUMP VECTOR TABLE FOR INDIVIDUAL SUBROUTINES -;================================================================================================== -; These jumps are defined in the CP/M-80 v2.2 system guide and comprise -; the invariant part of the BIOS. - - JP BOOT ; #0 - COLD START -WBOOTE JP WBOOT ; #1 - WARM START - JP CONST ; #2 - CONSOLE STATUS - JP CONIN ; #3 - CONSOLE CHARACTER IN - JP CONOUT ; #4 - CONSOLE CHARACTER OUT - JP LIST ; #5 - LIST CHARACTER OUT - JP PUNCH ; #6 - PUNCH CHARACTER OUT - JP READER ; #7 - READER CHARACTER OUT - JP HOME ; #8 - MOVE HEAD TO HOME POSITION - JP SELDSK ; #9 - SELECT DISK - JP SETTRK ; #10 - SET TRACK NUMBER - JP SETSEC ; #11 - SET SECTOR NUMBER - JP SETDMA ; #12 - SET DMA ADDRESS - JP READ ; #13 - READ DISK - JP WRITE ; #14 - WRITE DISK - JP LISTST ; #15 - RETURN LIST STATUS - JP SECTRN ; #16 - SECTOR TRANSLATE -;------------------------------------------------------------------------ -; These jumps are enhancements, added for the benefit of the RomWBW BIOS -; and are located following the invariant jump table so they can be -; easily located by external programs. They transfger control to routines -; that are located somewhere within the main section of the CBIOS. - - JP BNKSEL ; #17 - SEL. RAM BANK FOR LOW32K (obsolete, use HBIOS) - JP GETDSK ; #18 - Get Disk Info (device/unit/lu) - JP SETDSK ; #19 - Set Disk Into (device/unit/lu) - JP GETINFO ; #20 - Get BIOS Info Base Ptr -; Expansion area for future enhancements - In order not to shift the -; subsequent data and break local and external code, space is set aside for -; four additional jumps. Until implemented, an invocation will result in -; a system panic. - CALL PANIC ; #21 - reserved for JP - CALL PANIC ; #22 - reserved for JP - CALL PANIC ; #23 - reserved for JP - CALL PANIC ; #24 - reserved for JP -; -;================================================================================================== -; CONFIGURATION DATA -;================================================================================================== -; -; The following RomWBW specific configuration data is located at this -; offset so they can be located by code in the CBIOS. The declarations -; are based on the selected configuration file used at build-time. The -; data is included from an external file so as to not clutter the main -; BIOS code. The size of the configuration data is available by virtue -; of the SIZ_CNFGDATA equate (see below). - -ORG_INFOLIST .EQU $ - - .DB RMJ - .DB RMN - .DB RUP - .DB RTP - -#INCLUDE "infolist.inc" - -SIZ_INFOLIST .EQU $ - ORG_INFOLIST ; - .ECHO "INFOLIST occupies " - .ECHO SIZ_INFOLIST - .ECHO " bytes.\n" -; -;================================================================================================== -; BIOS FUNCTIONS -;================================================================================================== -; -;__________________________________________________________________________________________________ -BOOT: - JP INIT ; GO TO COLD BOOT CODE -; -;__________________________________________________________________________________________________ -WBOOT: - DI - IM 1 - - LD SP,ISTACK ; STACK FOR INITIALIZATION - - ; RELOAD COMMAND PROCESSOR FROM CACHE - LD A,1 - CALL RAMPG - LD HL,0800H ; LOCATION IN RAM1 OF COMMAND PROCESSOR CACHE - LD DE,CPM_LOC ; LOCATION OF ACTIVE COMMAND PROCESSOR - LD BC,CCPSIZ ; SIZE OF COMMAND PROCESSOR - LDIR - CALL RAMPGZ - - ; FALL THRU TO INVOKE CP/M -; -;__________________________________________________________________________________________________ -GOCPM: - ; SETUP DISK XFR BUFFER LOCATION - LD HL,SECBUF - LD (BUFADR),HL - LD B,BF_DIOSETBUF - RST 08 - - LD A,0C3H ; LOAD A WITH 'JP' INSTRUCTION (USED BELOW) - - ; CPU RESET / RST 0 -> WARM START CP/M - LD (0000H),A - LD HL,WBOOTE - LD (0001H),HL - -; ; INT / RST 38 -> INVOKE MONITOR -; LD (0038H),A -; LD HL,GOMON -; LD (0039H),HL - -; ; INT / RST 38 -> PANIC -; LD (0038H),A -; LD HL,PANIC ; PANIC ROUTINE ADDRESS -; LD (0039H),HL ; POKE IT - - ; CALL 5 -> INVOKE BDOS - LD (0005H),A - LD HL,BDOS - LD (0006H),HL - - ; RESET (DE)BLOCKING ALGORITHM - CALL BLKRES - - ; DEFAULT DMA ADDRESS - LD BC,80H - CALL SETDMA - - ; ENSURE VALID DISK AND JUMP TO CCP - LD A,(CDISK) ; GET CURRENT USER/DISK - AND 0FH ; ISOLATE DISK PART - LD C,A ; SETUP C WITH CURRENT USER/DISK, ASSUME IT IS OK - CALL DSK_STATUS ; CHECK DISK STATUS - JR Z,CURDSK ; ZERO MEANS OK - LD A,(DEFDRIVE) ; CURRENT DRIVE NOT READY, USE DEFAULT - JR GOCCP -CURDSK: - LD A,(CDISK) ; GET CURRENT USER/DISK -GOCCP: - LD C,A ; SETUP C WITH CURRENT USER/DISK, ASSUME IT IS OK - JP CCP -; -;__________________________________________________________________________________________________ -GOMON: - CALL PANIC -; -; DI -; IM 1 -; -; LD SP,STACK -; -; ; RELOAD MONITOR INTO RAM (IN CASE IT HAS BEEN OVERWRITTEN) -; CALL ROMPGZ -; LD HL,MON_IMG -; LD DE,MON_LOC -; LD BC,MON_SIZ -; LDIR -; CALL RAMPGZ - -; ; JUMP TO MONITOR WARM ENTRY -; JP MON_UART -; -;__________________________________________________________________________________________________ -CONST: -; CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT -; - LD B,BF_CIOIST ; B = FUNCTION - LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE - JR CONIO -; -;__________________________________________________________________________________________________ -CONIN: -; CONSOLE CHARACTER INTO REGISTER A -; - LD B,BF_CIOIN ; B = FUNCTION - LD HL,CIOIN ; HL = ADDRESS OF COMPLETION ROUTINE - JR CONIO - -;__________________________________________________________________________________________________ -CONOUT: -; CONSOLE CHARACTER OUTPUT FROM REGISTER C -; - LD B,BF_CIOOUT ; B = FUNCTION - LD HL,CIOOUT ; HL = ADDRESS OF COMPLETION ROUTINE - LD E,C ; E = CHARACTER TO SEND -; JR CONIO ; COMMENTED OUT, FALL THROUGH OK -; -;__________________________________________________________________________________________________ -CONIO: -; - LD A,(IOBYTE) ; GET IOBYTE - AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR CONSOLE - OR $00 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C - JP CIO_DISP -; -;__________________________________________________________________________________________________ -LIST: -; LIST CHARACTER FROM REGISTER C -; - LD B,BF_CIOOUT ; B = FUNCTION - LD HL,CIOOUT ; HL = ADDRESS OF COMPLETION ROUTINE - LD E,C ; E = CHARACTER TO SEND - JR LISTIO -; -;__________________________________________________________________________________________________ -LISTST: -; RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) -; - LD B,BF_CIOOST ; B = FUNCTION - LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE -; JR LISTIO ; COMMENTED OUT, FALL THROUGH OK -; -;__________________________________________________________________________________________________ -LISTIO: -; - LD A,(IOBYTE) ; GET IOBYTE - RLCA ; SHIFT RELEVANT BITS TO BITS 0-1 - RLCA - AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR LST: - OR $0C ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C - JP CIO_DISP -; -;__________________________________________________________________________________________________ -PUNCH: -; PUNCH CHARACTER FROM REGISTER C -; - LD B,BF_CIOOUT ; B = FUNCTION - LD HL,CIOOUT ; HL = ADDRESS OF COMPLETION ROUTINE - LD E,C ; E = CHARACTER TO SEND -; JR PUNCHIO ; COMMENTED OUT, FALL THROUGH OK -; -;__________________________________________________________________________________________________ -PUNCHIO: -; - LD A,(IOBYTE) ; GET IOBYTE - RLCA ; SHIFT RELEVANT BITS TO BITS 0-1 - RLCA - RLCA - RLCA - AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR PUN: - OR $08 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C - JP CIO_DISP -; -;__________________________________________________________________________________________________ -READER: -; READ CHARACTER INTO REGISTER A FROM READER DEVICE -; - LD B,BF_CIOIN ; B = FUNCTION - LD HL,CIOIN ; HL = ADDRESS OF COMPLETION ROUTINE - JR READERIO -; -;__________________________________________________________________________________________________ -READERST: -; RETURN READER STATUS (0 IF NOT READY, 1 IF READY) -; - LD B,BF_CIOIST ; B = FUNCTION - LD HL,CIOST ; HL = ADDRESS OF COMPLETION ROUTINE -; JR READERIO ; COMMENTED OUT, FALL THROUGH OK -; -;__________________________________________________________________________________________________ -READERIO: -; - LD A,(IOBYTE) ; GET IOBYTE - RRCA ; SHIFT RELEVANT BITS TO BITS 0-1 - RRCA - AND $03 ; ISOLATE RELEVANT IOBYTE BITS FOR RDR: - OR $04 ; PUT LOGICAL DEVICE IN BITS 2-3 (CON:=$00, RDR:=$04, PUN:=$08, LST:=$0C - JP CIO_DISP -; -;__________________________________________________________________________________________________ -CIOIN: -; COMPLETION ROUTINE FOR CHARACTER INPUT FUNCTIONS -; - LD A,E ; MOVE CHARACTER RETURNED TO A -; RET ; FALL THRU -; -;__________________________________________________________________________________________________ -CIOOUT: -; COMPLETION ROUTINE FOR CHARACTER OUTPUT FUNCTIONS -; - RET -; -;__________________________________________________________________________________________________ -CIOST: -; COMPLETION ROUTINE FOR CHARACTER STATUS FUNCTIONS (IST/OST) -; - OR A ; SET FLAGS - RET Z ; NO CHARACTERS WAITING (IST) OR OUTPUT BUF FULL (OST) - OR 0FFH ; $FF SIGNALS READY TO READ (IST) OR WRITE (OST) - RET -;__________________________________________________________________________________________________ -SELDSK: -; SELECT DISK NUMBER FOR SUBSEQUENT DISK OPS -#IF DSKTRACE - CALL PRTSELDSK ; *DEBUG* -#ENDIF - JP DSK_SELECT -; -;__________________________________________________________________________________________________ -HOME: -; SELECT TRACK 0 (BC = 0) AND FALL THRU TO SETTRK -#IF DSKTRACE - CALL PRTHOME ; *DEBUG* -#ENDIF - - LD A,(HSTWRT) ; CHECK FOR PENDING WRITE - OR A - JR NZ,HOMED - LD (HSTACT),A ; CLEAR HOST ACTIVE FLAG - -HOMED: - LD BC,0 -; -;__________________________________________________________________________________________________ -SETTRK: -; SET TRACK GIVEN BY REGISTER BC - LD (SEKTRK),BC - RET -; -;__________________________________________________________________________________________________ -SETSEC: -; SET SECTOR GIVEN BY REGISTER BC - LD (SEKSEC),BC - RET -; -;__________________________________________________________________________________________________ -SECTRN: -; SECTOR TRANSLATION FOR SKEW, HARD CODED 1:1, NO SKEW IMPLEMENTED - LD H,B - LD L,C - RET -; -;__________________________________________________________________________________________________ -SETDMA: - LD (DMAADR),BC - RET -; -;__________________________________________________________________________________________________ -READ: - LD A,DOP_READ - JR READWRITE -; -;__________________________________________________________________________________________________ -WRITE: - LD A,C - LD (WRTYPE),A ; SAVE WRITE TYPE - LD A,DOP_WRITE - JR READWRITE -; -;__________________________________________________________________________________________________ -BNKSEL: -; - LD A,C - JP RAMPG -; -;__________________________________________________________________________________________________ -GETDSK: -; -; INPUT: C=DRIVE # (0=A, 1=B, ... P=16) -; OUTPUT: A=RESULT (0=OK, 1=INVALID DRIVE #) -; B=DEVICE/UNIT -; DE=CURRENT LU -; HL=LU COUNT SUPPORTED ON DEVICE/UNIT (0 = NO SUPPORT) -; - ; C HAS CPM DRIVE, LOOKUP DPH (INCLUDES INVALID DRIVE CHECK) - CALL DSK_GETDPH ; HL = DPH (0 IF INVALID DRIVE) - RET NZ ; A=1 AND NZ SET IF INVALID DRIVE - - ; HL HAS DPH POINTER, LOOKUP LU INFO (ERROR IF NO LU SUPPORT) - CALL DSK_GETLU ; HL = ADDRESS OF START OF LU DATA - JR NZ,GETDSK1 ; NO LU SUPPORT, BAIL OUT - - ; HL POINTS TO START OF LU DATA, FILL IN LU VALUES - LD E,(HL) - INC HL - LD D,(HL) ; DE NOW HAS CURRENT SLICE NUMBER - INC HL - LD A,(HL) - INC HL - LD H,(HL) - LD L,A ; HL NOW HAS SLICE COUNT FOR DEVICE - -GETDSK1: - XOR A ; A=0 FOR SUCCESS (EVEN IF NO LU SUPPORT) - RET -; -;__________________________________________________________________________________________________ -SETDSK: -; -; INPUT: C=DRIVE # (0=A, 1=B, ... P=16) -; B=DEVICE/UNIT -; DE=CURRENT LU -; HL=LU COUNT SUPPORTED ON DEVICE/UNIT -; OUTPUT: A=RESULT (0=OK, 1=INVALID DRIVE #) -; B=DEVICE/UNIT -; DE=CURRENT LU -; HL=LU COUNT SUPPORTED ON DEVICE/UNIT (0 = NO SUPPORT) -; -; NOTES: -; PARMS ARE NOT VALUE CHECKED. A NON-EXISTENT DEVICE/UNIT/LU COULD -; BE SET AS A RESULT. CALLER IS RESPONSIBLE FOR THIS. -; - ; SAVE INCOMING LU VALUES FOR LATER - PUSH BC - PUSH HL - PUSH DE - - ; MAKE SURE NEW DEVICE/UNIT IS A MASS STORAGE DEVICE - LD A,B ; LOAD THE REQEUSTED DEVICE/UNIT - CP $20 ; MASS STORAGE DEVICES START AT DEV/UNIT $20 - JR C,SETDSK2 ; IF NOT, BAIL OUT - - ; C HAS CPM DRIVE, LOOKUP DPH (INCLUDES INVALID DRIVE CHECK) - PUSH BC - CALL DSK_GETDPH ; HL = DPH (0 IF INVALID DRIVE) - POP BC - JR NZ,SETDSK2 ; A=1 AND NZ SET IF INVALID DRIVE - - ; UPDATE DEVICE/UNIT (CHECK NEW DEVICE IS VALID) - DEC HL ; POINT TO DEVICE/UNIT BYTE - LD A,(HL) ; LOAD CURRENT DEVICE/UNIT - CP $20 ; MASS STORAGE DEVICES START AT DEV/UNIT $20 - JR C,SETDSK2 ; IF NOT, BAIL OUT - LD A,B ; LOAD NEW DEVICE/UNIT VALUE - LD (HL),A ; SAVE IT - INC HL ; POINT HL BACK TO START OF DPH - - ; HL HAS DPH POINTER, LOOKUP LU INFO (ERROR IF NO LU SUPPORT) - CALL DSK_GETLU ; HL = ADDRESS OF START OF LU DATA - - ; RECOVER THE NEW SLICE AND SLICE COUNT - POP DE ; DE = NEW SLICE - POP BC ; BC = NEW SLICE COUNT - - ; CHECK IF DRIVE IS LU CAPABLE, BYPASS LU SETTING IF NOT - JR NZ,SETDSK1 - - ; PLUG IN THE NEW VALUES - LD (HL),E - INC HL - LD (HL),D ; CURRENT SLICE NOW SET TO DE - INC HL ; POINT TO SLICE COUNT - LD (HL),C - INC HL - LD (HL),B ; SLICE COUNT NOW SET TO HL - -SETDSK1: - ; SUCCESS EXIT (USE GETDSK TO RETURN DATA) - CALL BLKRES ; RESET (DE)BLOCKING ALGORITHM FOR SAFETY - POP BC - JR GETDSK - -SETDSK2: - ; ERROR EXIT - POP DE - POP HL - POP BC - XOR A - INC A - RET -; -;__________________________________________________________________________________________________ -GETINFO: -; -; The purpose of the GETINFO BIOS entry point is to return a -; base pointer to a table of pointers. These pointers are used -; by utility programs to locate BIOS internals that are not able -; to be located by normal means specified in the system guide. -; -; The pointers are defined in an included file so as to not clutter -; the main code. The contents are used by external utilties and are -; not used in any manner by the CBIOS code specifically. -; - LD HL,INFOLIST - RET -; -;__________________________________________________________________________________________________ -READWRITE: - LD (DSKOP),A ; SET THE ACTIVE DISK OPERATION -#IF DSKTRACE - CALL PRTDSKOP ; *DEBUG* -#ENDIF - LD A,(SEKDU) ; GET DEVICE/UNIT - AND 0F0H ; ISOLATE DEVICE NIBBLE - JR Z,DIRRW ; DEVICE = 0 = MD, SO DIRECT R/W - JP BLKRW ; OTHERWISE, (DE)BLOCKING R/W - -; -;================================================================================================== -; DIRECT READ/WRITE (NO (DE)BLOCKING, NO BUFFERING, 128 BYTE SECTOR) -;================================================================================================== -; -DIRRW: - CALL BLKFLSH ; FLUSH ANY PENDING WRITES SO WE CAN USE SEC BUF - RET NZ ; RETURN ON ERROR - - CALL BLKRES ; RESET (DE)BLOCKING ALG, BUF IS NO LONGER VALID - - ; AT THIS POINT THE ACCESS IS HARDCODED TO POINT TO MEMORY DISK DRIVER - ; SINCE THERE IS NO OTHER DIRECT READ/WRITE DEVICE - - LD A,(DSKOP) - - CP DOP_READ - JP Z,MD_READ - - CP DOP_WRITE - JP Z,MD_WRITE - - CALL PANIC -; -;================================================================================================== -; BLOCKED READ/WRITE (BLOCK AND BUFFER FOR 512 BYTE SECTOR) -;================================================================================================== -; -;__________________________________________________________________________________________________ -; -; RESET (DE)BLOCKING ALGORITHM - JUST MARK BUFFER INVALID -; NOTE: BUFFER CONTENTS INVALIDATED, BUT RETAIN ANY PENDING WRITE -; -BLKRES: - XOR A - LD (HSTACT),A ; BUFFER NO LONGER VALID - LD (UNACNT),A ; CLEAR UNALLOC COUNT - - RET - -;__________________________________________________________________________________________________ -; -; FLUSH (DE)BLOCKING ALGORITHM - DO PENDING WRITES -; -BLKFLSH: - ; CHECK FOR BUFFER WRITTEN (DIRTY) - LD A,(HSTWRT) ; GET BUFFER WRITTEN FLAG - OR A - RET Z ; NOT DIRTY, RETURN WITH A=0 AND Z SET - - ; CLEAR THE BUFFER WRITTEN FLAG (EVEN IF A WRITE ERROR OCCURS) - XOR A ; Z = 0 - LD (HSTWRT),A ; SAVE IT - - ; DO THE WRITE AND RETURN RESULT - JP DSK_WRITE - -#IF WRTCACHE - -WRT_ALL .EQU 0 ; WRITE TO ALLOCATED -WRT_DIR .EQU 1 ; WRITE TO DIRECTORY -WRT_UAL .EQU 2 ; WRITE TO UNALLOCATED - -; -;__________________________________________________________________________________________________ -; -; (DE)BLOCKING READ/WRITE ROUTINE. MANAGES PHYSICAL DISK BUFFER AND CALLS -; PHYSICAL READ/WRITE ROUTINES APPROPRIATELY. -; -BLKRW: - ; FIX!!! WE ABORT ON FIRST ERROR, DRI SEEMS TO PASS ERROR STATUS TO THE END!!! - - ; IF WRITE OPERATION, GO TO SPECIAL WRITE PROCESSING - LD A,(DSKOP) ; GET REQUESTED OPERATION - CP DOP_WRITE ; WRITE - JR Z,BLKRW1 ; GO TO WRITE PROCESSING - - ; OTHERWISE, CLEAR OUT ANY SEQUENTIAL, UNALLOC WRITE PROCESSING - ; AND GO DIRECTLY TO MAIN I/O - XOR A ; ZERO TO A - LD (WRTYPE),A ; SET WRITE TYPE = 0 (WRT_ALL) TO ENSURE READ OCCURS - LD (UNACNT),A ; SET UNACNT TO ABORT SEQ WRITE PROCESSING - - JR BLKRW4 ; GO TO I/O - -BLKRW1: - ; WRITE PROCESSING - ; CHECK FOR FIRST WRITE TO UNALLOCATED BLOCK - LD A,(WRTYPE) ; GET WRITE TYPE - CP WRT_UAL ; IS IT WRITE TO UNALLOC? - JR NZ,BLKRW2 ; NOPE, BYPASS - - ; INITIALIZE START OF SEQUENTIAL WRITING TO UNALLOCATED BLOCK - ; AND THEN TREAT SUBSEQUENT PROCESSING AS A NORMAL WRITE - CALL UNA_INI ; INITIALIZE SEQUENTIAL WRITE TRACKING - XOR A ; A = 0 = WRT_ALL - LD (WRTYPE),A ; NOW TREAT LIKE WRITE TO ALLOCATED - -BLKRW2: - ; IF WRTYPE = WRT_ALL AND SEQ WRITE, GOTO BLKRW7 (SKIP READ) - OR A ; NOTE: A WILL ALREADY HAVE THE WRITE TYPE HERE - JR NZ,BLKRW3 ; NOT TYPE = 0 = WRT_ALL, SO MOVE ON - - CALL UNA_CHK ; CHECK FOR CONTINUATION OF SEQ WRITES TO UNALLOCATED BLOCK - JR NZ,BLKRW3 ; NOPE, ABORT - - ; WE MATCHED EVERYTHING, TREAT AS WRITE TO UNALLOCATED BLOCK - LD A,WRT_UAL ; WRITE TO UNALLOCATED - LD (WRTYPE),A ; SAVE WRITE TYPE - - CALL UNA_INC ; INCREMENT SEQUENTIAL WRITE TRACKING - JR BLKRW4 ; PROCEED TO I/O PROCESSING - -BLKRW3: - ; NON-SEQUENTIAL WRITE DETECTED, STOP ANY FURTHER CHECKING - XOR A ; ZERO - LD (UNACNT),A ; CLEAR UNALLOCATED WRITE COUNT - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; IS A FLUSH NEEDED HERE??? - ; FLUSH CURRENT BUFFER CONTENTS IF NEEDED - ;CALL BLKFLSH ; FLUSH PENDING WRITES - ;RET NZ ; ABORT ON ERROR - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -BLKRW4: - ; START OF ACTUAL I/O PROCESSING - CALL BLK_XLT ; DO THE LOGICAL TO PHYSICAL MAPPING: SEK... -> XLT... - CALL BLK_CMP ; IS THE DESIRED PHYSICAL BLOCK IN BUFFER? - JR Z,BLKRW6 ; BLOCK ALREADY IN ACTIVE BUFFER, NO READ REQUIRED - - ; AT THIS POINT, WE KNOW WE NEED TO READ THE TARGET PHYSICAL SECTOR - ; IT MAY ACTUALLY BE A PREREAD FOR A SUBSEQUENT WRITE, BUT THAT IS OK - - ; FIRST, FLUSH CURRENT BUFFER CONTENTS - CALL BLKFLSH ; FLUSH PENDING WRITES - RET NZ ; ABORT ON ERROR - - ; IMPLEMENT THE TRANSLATED VALUES - CALL BLK_SAV ; SAVE XLAT VALUES: XLT... -> HST... - - ; IF WRITE TO UNALLOC BLOCK, BYPASS READ, LEAVES BUFFER UNDEFINED - LD A,(WRTYPE) - CP 2 - JR Z,BLKRW6 - - ; DO THE ACTUAL READ - CALL DSK_READ ; READ PHYSICAL SECTOR INTO BUFFER - JR Z,BLKRW6 ; GOOD READ, CONTINUE - - ; IF READ FAILED, RESET (DE)BLOCKING ALGORITHM AND RETURN ERROR - PUSH AF ; SAVE ERROR STATUS - CALL BLKRES ; INVALIDATE (DE)BLOCKING BUFFER - POP AF ; RECOVER ERROR STATUS - RET ; ERROR RETURN - -BLKRW6: - ; CHECK TYPE OF OPERATIONS, IF WRITE, THEN GO TO WRITE PROCESSING - LD A,(DSKOP) ; GET PENDING OPERATION - CP DOP_WRITE ; IS IT A WRITE? - JR Z,BLKRW7 ; YES, GO TO WRITE PROCESSING - - ; THIS IS A READ OPERATION, WE ALREADY DID THE I/O, NOW JUST DEBLOCK AND RETURN - CALL BLK_DEBLOCK ; EXTRACT DATA FROM BLOCK - XOR A ; NO ERROR - RET ; ALL DONE - -BLKRW7: - ; THIS IS A WRITE OPERATION, INSERT DATA INTO BLOCK - CALL BLK_BLOCK ; INSERT DATA INTO BLOCK - - ; MARK THE BUFFER AS WRITTEN - LD A,TRUE ; BUFFER DIRTY = TRUE - LD (HSTWRT),A ; SAVE IT - - ; CHECK WRITE TYPE, IF WRT_DIR, FORCE THE PHYSICAL WRITE - LD A,(WRTYPE) ; GET WRITE TYPE - CP WRT_DIR ; 1 = DIRECTORY WRITE - JP Z,BLKFLSH ; FLUSH PENDING WRITES AND RETURN STATUS - - XOR A ; ALL IS WELL, SET RETURN CODE 0 - RET ; RETURN -; -;__________________________________________________________________________________________________ -; -; INITIALIZE TRACKING OF SEQUENTIAL WRITES INTO UNALLOCATED BLOCK -; SETUP UNA... VARIABLES -; -UNA_INI: - ; COPY SEKDSK/TRK/SEC TO UNA... - LD HL,SEK - LD DE,UNA - LD BC,UNASIZ - LDIR - - ; SETUP UNACNT AND UNASPT - LD HL,(SEKDPH) ; HL POINTS TO DPH - LD DE,10 ; OFFSET OF DPB ADDRESS IN DPH - ADD HL,DE ; DPH POINTS TO DPB ADDRESS - LD A,(HL) - INC HL - LD H,(HL) - LD L,A ; HL POINTS TO DPB - LD C,(HL) - INC HL - LD B,(HL) ; BC HAS SPT - LD (UNASPT),BC ; SAVE SECTORS PER TRACK - DEC HL - DEC HL ; HL POINTS TO RECORDS PER BLOCK (BYTE IN FRONT OF DPB) - LD A,(HL) ; GET IT - LD (UNACNT),A ; SAVE IT - -; CALL NEWLINE ; *DEBUG* -; CALL PRTHEXBYTE ; *DEBUG* -; CALL PC_SPACE ; *DEBUG* -; CALL PRTHEXWORD ; *DEBUG* -; CALL PC_SPACE ; *DEBUG* -; LD BC,(UNASPT) ; *DEBUG* -; CALL PRTHEXWORD ; *DEBUG* - - RET -; -;__________________________________________________________________________________________________ -; -; CHECK FOR CONTINUATION OF SEQUENTIAL WRITES TO UNALLOCATED BLOCK -; SEE IF UNACNT > 0 AND UNA... VARIABLES MATCH SEK... VARIABLES -; -UNA_CHK: - LD A,(UNACNT) ; GET THE COUNTER - OR A - JR NZ,UNA_CHK1 ; IF NOT DONE WITH BLOCK, KEEP CHECKING - - ; CNT IS NOW ZERO, EXHAUSTED RECORDS IN ONE BLOCK! - DEC A ; HACK TO SET NZ - RET ; RETURN WITH NZ - -UNA_CHK1: - ; COMPARE UNA... VARIABLES WITH SEK... VARIABLES - LD HL,SEK - LD DE,UNA - LD B,UNASIZ - JR BLK_CMPLOOP -; -;__________________________________________________________________________________________________ -; -; INCREMENT THE SEQUENTIAL WRITE TRACKING VARIABLES -; TO REFLECT THE NEXT RECORD (TRK/SEC) WE EXPECT -; -UNA_INC: - ; DECREMENT THE BLOCK RECORD COUNT - LD HL,UNACNT - DEC (HL) - - ; INCREMENT THE SECTOR - LD DE,(UNASEC) - INC DE - LD (UNASEC),DE - - ; CHECK FOR END OF TRACK - LD HL,(UNASPT) - XOR A - SBC HL,DE - RET NZ - - ; HANDLE END OF TRACK - LD (UNASEC),HL ; SECTOR BACK TO 0 (NOTE: HL=0 AT THIS POINT) - LD HL,(UNATRK) ; GET CURRENT TRACK - INC HL ; BUMP IT - LD (UNATRK),HL ; SAVE IT - - RET -#ELSE -; -;__________________________________________________________________________________________________ -; -; (DE)BLOCKING READ/WRITE ROUTINE. MANAGES PHYSICAL DISK BUFFER AND CALLS -; PHYSICAL READ/WRITE ROUTINES APPROPRIATELY. -; -BLKRW: - CALL BLK_XLT ; SECTOR XLAT: SEK... -> XLT... - CALL BLK_CMP ; IN BUFFER? - JR Z,BLKRW1 ; YES, BYPASS READ - CALL BLK_SAV ; SAVE XLAT VALUES: XLT... -> HST... - LD A,FALSE ; ASSUME FAILURE, INVALIDATE BUFFER - LD (HSTACT),A ; SAVE IT - CALL DSK_READ ; READ PHYSICAL SECTOR INTO BUFFER - RET NZ ; BAIL OUT ON ERROR - -BLKRW1: - LD A,(DSKOP) ; GET PENDING OPERATION - CP DOP_WRITE ; IS IT A WRITE? - JR Z,BLKRW2 ; YES, GO TO WRITE ROUTINE - - CALL BLK_DEBLOCK ; EXTRACT DATA FROM BLOCK - XOR A ; NO ERROR - RET ; ALL DONE - -BLKRW2: - CALL BLK_BLOCK ; INSERT DATA INTO BLOCK - CALL DSK_WRITE ; WRITE PHYSICAL SECTOR FROM BUFFER - RET NZ ; BAIL OUT ON ERROR - - LD A,TRUE ; BUFFER IS NOW VALID - LD (HSTACT),A ; SAVE IT - - XOR A ; ALL IS WELL, SET RETURN CODE 0 - RET ; RETURN -#ENDIF -; -;__________________________________________________________________________________________________ -; -; TRANSLATE FROM CP/M DSK/TRK/SEC TO PHYSICAL -; SEK... -> XLT... -; -BLK_XLT: - ; FIRST, DO A BYTE COPY OF SEK... TO XLT... - LD HL,SEK - LD DE,XLT - LD BC,XLTSIZ - LDIR - - ; NOW UPDATE XLTSEC BASED ON (DE)BLOCKING FACTOR (ALWAYS 4:1) - LD BC,(SEKSEC) ; SECTOR IS FACTORED DOWN (4:1) DUE TO BLOCKING - SRL B ; 16 BIT RIGHT SHIFT TWICE TO DIVIDE BY 4 - RR C - SRL B - RR C - LD (XLTSEC),BC - - RET -; -;__________________________________________________________________________________________________ -; -; SAVE RESULTS OF TRANSLATION: XLT... -> HST... -; IMPLICITLY SETS HSTACT TO TRUE! -; -BLK_SAV: - LD HL,XLT - LD DE,HST - LD BC,XLTSIZ - LDIR - RET -; -;__________________________________________________________________________________________________ -; -; COMPARE RESULTS OF TRANSLATION TO CURRENT BUF (XLT... TO HST...) -; NOTE THAT HSTACT IS COMPARED TO XLTACT IMPLICITLY! XLTACT IS ALWAYS TRUE, SO -; HSTACT MUST BE TRUE FOR COMPARE TO SUCCEED. -; -BLK_CMP: - LD HL,XLT - LD DE,HST - LD B,XLTSIZ -BLK_CMPLOOP: - LD A,(DE) - CP (HL) - RET NZ ; BAD COMPARE, RETURN WITH NZ - INC HL - INC DE - DJNZ BLK_CMPLOOP - RET ; RETURN WITH Z -; -;__________________________________________________________________________________________________ -; -; BLOCK DATA - INSERT CPM DMA BUF INTO PROPER PART OF PHYSICAL SECTOR BUFFER -; -BLK_BLOCK: - CALL BLK_SETUP ; SETUP SOURCE AND DESTINATION - EX DE,HL ; SWAP HL/DE FOR BLOCK OPERATION - LD BC,128 ; DMA BUFFER SIZE - LDIR ; COPY THE DATA - RET -; -;__________________________________________________________________________________________________ -; -; DEBLOCK DATA - EXTRACT DESIRED CPM DMA BUF FROM PHYSICAL SECTOR BUFFER -; -BLK_DEBLOCK: - CALL BLK_SETUP ; SETUP SOURCE AND DESTINATION - LD BC,128 ; DMA BUFFER SIZE - LDIR ; COPY THE DATA - RET -; -;__________________________________________________________________________________________________ -; -; SETUP SOURCE AND DESTINATION POINTERS FOR BLOCK COPY OPERATION -; AT EXIT, HL = ADDRESS OF DESIRED BLOCK IN SECTOR BUFFER, DE = DMA -; -BLK_SETUP: - LD BC,(SEKSEC) - LD A,C - AND 3 ; A = INDEX OF CPM BUF IN SEC BUF - RRCA ; MULTIPLY BY 64 - RRCA - LD E,A ; INTO LOW ORDER BYTE OF DESTINATION - LD D,0 ; HIGH ORDER BYTE IS ZERO - LD HL,(BUFADR) ; HL = START OF SEC BUF - ADD HL,DE ; ADD IN COMPUTED OFFSET - ADD HL,DE ; HL NOW = INDEX * 128 (SOURCE) - LD DE,(DMAADR) ; DE = DESTINATION = DMA BUF - RET -; -;================================================================================================== -; CHARACTER DEVICE INTERFACE -;================================================================================================== -; -; ROUTING FOR CHARACTER DEVICE FUNCTIONS -; A = INDEX INTO CIO_MAP BASED ON IOBYTE BIOS REQUEST -; B = FUNCTION REQUESTED: BF_CIO(IN/OUT/IST/OST) -; E = CHARACTER (IF APPLICABLE TO FUNCTION) -; HL = ADDRESS OF COMPLETION ROUTINE -; -CIO_DISP: - PUSH HL ; PUT COMPLETION ROUTINE ON STACK - - ; LOOKUP IOBYTE MAPPED DEVICE CODE - ; WARNING: CIO_MAP MUST NOT CROSS PAGE BOUNDARY!!! - AND 0FH ; ISOLATE INDEX INTO CIO_MAP - - LD HL,CIO_MAP ; HL = ADDRESS OF CIO_MAP - ADD A,L ; ADD LOW BYTE TO OFFSET - LD L,A ; GET RESULT BACK TO L - - LD A,(HL) ; LOOKUP DEVICE CODE - LD C,A ; SAVE IN C FOR BIOS USAGE - - CP CIODEV_BAT ; CHECK FOR SPECIAL DEVICE (BAT, NUL) - JR NC,CIO_DISP1 ; HANDLE SPECIAL DEVICE - RST 08 ; OTHERWISE HANDLE VIA HBIOS - RET ; RETURN VIA COMPLETION ROUTINE SET AT START - -CIO_DISP1: - ; HANDLE SPECIAL DEVICES - AND 0F0H ; ISOLATE DEVICE - CP CIODEV_BAT ; BAT: ? - JR Z,CIO_BAT ; YES, GO TO BAT DEVICE HANDLER - CP CIODEV_NUL ; NUL: ? - JR Z,CIO_NUL ; YES, GO TO NUL DEVICE HANDLER - CALL PANIC ; SOMETHING BAD HAPPENED -; -; BAT: IS A PSEUDO DEVICE REDIRECTING INPUT TO READER AND OUTPUT TO LIST -; -CIO_BAT: - LD C,E ; PUT CHAR BACK IN C - LD A,B ; GET REQUESTED FUNCTION - CP BF_CIOIN ; INPUT? - JP Z,READER ; -> READER - CP BF_CIOIST ; INPUT STATUS? - JP Z,READERST ; -> READER - CP BF_CIOOUT ; OUTPUT? - JP Z,LIST ; -> LIST - CP BF_CIOOST ; OUTPUT STATUS? - JP Z,LISTST ; -> LIST - CALL PANIC -; -; NUL: IS A DUMMY DEVICE THAT DOES NOTHING -; -CIO_NUL: - LD A,B ; FUNCTION - CP BF_CIOIN - JR Z,NUL_IN - CP BF_CIOIST - JR Z,NUL_IST - CP BF_CIOOUT - JR Z,NUL_OUT - CP BF_CIOOST - JR Z,NUL_OST - CALL PANIC -; -NUL_IN: - LD E,$1B ; RETURN EOF -NUL_OUT: - RET -; -NUL_IST: -NUL_OST: - OR $FF ; A=$FF & NZ SET - RET -; -;================================================================================================== -; PHYSICAL DISK INTERFACE -;================================================================================================== -; -DSK_DISP: - LD A,C ; GET DEVICE/UNIT TO A - AND 0F0H ; ISOLATE DEVICE - CP DIODEV_MD ; MEMORY DISK? (RAM/ROM) - JP Z,MD_DISPATCH ; YES, GO TO MEMORY DISK DISPATCH - - RST 08 ; OTHERWISE, HANDLE IN HBIOS - RET ; AND RETURN -; -; LOOKUP DPH BASED ON DPM DRIVE NUMBER -; ENTER WITH C=CPM DRIVE NUMBER -; RETURNS WITH HL = DPH ADDRESS (0 ON ERROR) -; A=0 ON SUCCESS, A=1 ON ERROR -; NOTE: DE IS NOT MODIFIED!!! -; -DSK_GETDPH: - ; CHECK FOR INVALID DRIVE NUMBER - LD A,C ; A = CPM DRIVE NUMBER - CP DPH_CNT ; COMPARE TO NUMBER OF DRIVES CONFIGURED - JR C,DSK_GETDPH1 ; IN RANGE, CONTINUE - XOR A ; ZERO ACCUMULATOR - LD H,A ; HL = 0 FOR FAILURE - LD L,A ; HL = 0 FOR FAILURE - INC A ; A = 1, NZ SET FOR INVALID DRIVE - RET ; FAILURE RETURN - - ; LOOKUP DPH FOR CPM DRIVE - ; WARNING: DPH_MAP MUST NOT CROSS PAGE BOUNDARY!!! -DSK_GETDPH1: - LD A,C ; GET CPM DRIVE NUMBER BACK - LD HL,DPH_MAP ; POINT TO START OF DPH_MAP - RLCA ; DOUBLE A TO USE AS OFFSET INTO DPH_MAP - ADD A,L ; ADD LOW BYTE TO OFFSET - LD L,A ; HL = ADDRESS OF DESIRED ENTRY IN DPH_MAP - LD A,(HL) ; DEREFERENCE - INC HL ; HL - LD H,(HL) ; TO GET - LD L,A ; DPHADR IN HL - - ; FILL IN DEVICE/UNIT - DEC HL ; POINT TO DEVICE CODE (BYTE IN FRONT OF DPH) - LD B,(HL) ; B = DEVICE/UNIT - INC HL ; HL = DPH AGAIN - - ; RETURN SUCCESS - XOR A ; A=0, Z SET - RET ; SUCCESS RETURN -; -; SET HL TO START OF LU DATA FOR DRIVE GIVEN DRIVE DPH POINTER IN HL -; ENTER WITH HL=POINTER TO DPH OF DRIVE -; RETURNS WITH HL = LU DATA ADDRESS (0 ON NO SUPPORT) -; Z SET IF LU SUPPORT, NZ IF NOT -; -DSK_GETLU: - ; CHECK FOR LU SUPPORT - LD DE,16 ; DPH + 16 IS "LU' MARKER LOCATION - ADD HL,DE ; HL POINTS TO MARKER LOCATION NOW - LD A,(HL) ; LOAD FIRST BYTE - INC HL ; POINT TO NEXT BYTE - CP 'L' ; IS IT 'L' - JR NZ,DSK_GETLU1 ; NOPE, BAIL OUT - LD A,(HL) ; LOAD SECOND BYTE - INC HL ; POINT TO NEXT BYTE - CP 'U' ; IS SECOND BYTE 'U'? - JR NZ,DSK_GETLU1 ; NOPE, BAIL OUT - RET ; SUCCESS, EXIT WITH Z SET - -DSK_GETLU1: - LD HL,0 ; OTHERWISE, HL=0 - RET ; AND RETURN WITH NZ SET -; -; -; -DSK_SELECT: - ; C HAS CPM DRIVE, SAVE IT - LD A,C - LD (SEKDSK),A - - ; LOOKUP DPH (INCLUDES INVALID DRIVE CHECK) - CALL DSK_GETDPH ; HL = DPH (0 IF INVALID DRIVE) - RET NZ ; A=1 AND NZ SET IF INVALID DRIVE - - ; FIX: WE COULD RETURN DUE TO INVALID DRIVE WITH ALL OF THE - ; REMAINING SEK... VARS SET TO PREVIOUS DRIVE? - - ; SAVE CURRENT DEVICE/UNIT AND DPH ADDRESS - LD A,B ; A = DEVIE/UNIT - LD (SEKDU),A ; SAVE DEVICE/UNIT - LD (SEKDPH),HL ; SAVE DPH POINTER - - ; SETUP IX AS INDEX INTO DPH - PUSH IX ; SAVE IX - LD IX,(SEKDPH) ; IX=DPH ADDRESS - - ; CHECK IF THIS IS LOGIN, IF NOT, BYPASS MEDIA DETECTION - ; FIX: WHAT IF PREVIOUS MEDIA DETECTION FAILED??? - BIT 0,E ; TEST DRIVE LOGIN BIT - JR NZ,DSK_SELECT2 ; BYPASS MEDIA DETECTION -; -DSK_SELECT1: - ; DETERMINE MEDIA IN DRIVE - LD A,(SEKDU) ; GET DEVICE/UNIT - LD C,A ; STORE IN C - LD B,BF_DIOMED ; DRIVER FUNCTION = DISK MEDIA - CALL DSK_DISP ; CALL DRIVER, RETURNS WITH A=MEDIA ID - - ; CHECK FOR NO MEDIA - LD HL,0 ; ASSUME NO MEDIA FAILURE, HL = 0 - OR A ; SET FLAGS - JR Z,DSK_SELECT4 ; IF Z, NO MEDIA, BAIL OUT WITH HL=0 - - ; A HAS MEDIA ID, SET HL TO CORRESPONDING DPB_MAP ENTRY - LD HL,DPB_MAP ; HL = DPB_MAP - RLCA ; DPB_MAP ENTRIES ARE 2 BYTES EACH - ADD A,L ; ADD LOW BYTE TO OFFSET - LD L,A ; GET RESULT BACK TO L - - ; LOOKUP THE ACTUAL DPB ADDRESS NOW - LD E,(HL) ; DEREFERENCE HL... - INC HL ; INTO DE... - LD D,(HL) ; DE = ADDRESS OF DESIRED DPB - - ; PLUG APPROPRIATE DPB INTO THE ACTIVE DPH - LD (IX+10),E ; DPH.DPB := DPB ADDRESS (LSB) - LD (IX+11),D ; DPH.DPB := DPB ADDRESS (MSB) - -DSK_SELECT2: - ; CHECK FOR SLICE SUPPORT, BYPASS LU OFFSET CALC IF NOT - LD HL,(SEKDPH) ; LOAD DPH - CALL DSK_GETLU ; CHECK FOR LU SUPPORT - JR NZ,DSK_SELECT3 ; IF NOT (NZ), BYPASS LU OFFSET CALC - - ; RECOMPUTE TRACK OFFSET BASED ON SLICE NUMBER - LD E,65 ; FIX: FIXME!!! HARDCODED!!! E = TRACKS PER SLICE - LD H,(IX+18) ; H = SLICE VALUE - CALL MULT8 ; HL = TOTAL OFFSET - -DSK_SELECT3: - LD (SEKOFF),HL ; SAVE LU TRACK OFFSET - LD HL,(SEKDPH) ; HL = DPH ADDRESS FOR CP/M - -DSK_SELECT4: - POP IX ; RESTORE IX - RET -; -; -; -DSK_STATUS: - ; C HAS CPM DRIVE, LOOKUP DEVICE/UNIT AND CHECK FOR INVLAID DRIVE - CALL DSK_GETDPH ; B = DEVICE/UNIT - RET NZ ; INVALID DRIVE ERROR - - ; VALID DRIVE, DISPATCH TO DRIVER - LD C,B ; C=DEVICE/UNIT - LD B,BF_DIOST ; SET B = FUNCTION: STATUS - JP DSK_DISP ; DISPATCH -; -; -; -DSK_READ: - ; SET B = FUNCTION: READ - LD B,BF_DIORD - JR DSK_IO -; -; -; -DSK_WRITE: - ; SET B = FUNCTION: WRITE - LD B,BF_DIOWR - JR DSK_IO -; -; -; -DSK_IO: - ; SET HL=TRACK (ADD IN TRACK OFFSET) - LD DE,(HSTOFF) ; DE = TRACK OFFSET FOR LU SUPPORT - LD HL,(HSTTRK) ; HL = TRACK # - ADD HL,DE ; HL = TRACK # TO READ TAKING LU SUPPORT INTO ACCOUNT - ; SET DE=SECTOR - LD DE,(HSTSEC) ; DE = SECTOR # - ; SET C = DEVICE/UNIT - LD A,(HSTDU) ; LOAD DEVICE/UNIT VALUE - LD C,A ; SAVE IN C - ; DISPATCH TO DRIVER - CALL DSK_DISP ; CALL DRIVER - OR A ; SET FLAGS BASED ON RESULT - RET -; -;================================================================================================== -; IN MEMORY DISK DRIVERS (ROM/RAM) -;================================================================================================== -; -; USES ROM/RAM STORAGE NOT USED BY SYSTEM/OS FOR DISK STORAGE -; ROM DRIVE: -; FIRST 32KB OF ROM RESERVED FOR SYSTEM BOOT AREA. REMAINDER IS ALLOCATED -; AS READ-ONLY DISK STORAGE. -; RAM DRIVE: -; FIRST AND LAST 32KB OF RAM IS RESERVED AND MAPPED TO FIRST AND LAST 32KB -; OF CPU MEMORY SPACE (FOR 64KB TOTAL). EVERYTHING ELSE IS ALLOCATED AS -; READ/WRITE DISK STORAGE. -; ROUTINES BELOW TRANSLATE REQUESTS FOR RAM/ROM STORAGE ACCESS BY CP/M BY -; TEMPORARILY MAPPING RAM/ROM INTO LOWER 32KB OF CPU MEMORY SPACE AND COPYING -; THE REQUESTED 128 BYTE BLOCK INTO THE CP/M DMA BUFFER. -; -MD_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JR Z,MD_READ - DEC A - JR Z,MD_WRITE - DEC A - JR Z,MD_READY - DEC A - JR Z,MD_SELECT - CALL PANIC -; -;__________________________________________________________________________________________________ -MD_INIT: -; -; INITIALIZE RAM DISK BY FILLING DIRECTORY WITH 'E5' BYTES -; FILL FIRST 8K OF RAM DISK TRACK 1 WITH 'E5' -; -#IF (CLRRAMDISK != CLR_NEVER) - LD A,2 ; START OF RAM DISK (SECOND 32KB) - CALL RAMPG ; SELECT RAM DISK - -#IF (CLRRAMDISK == CLR_AUTO) - ; CHECK FIRST 32 DIRECTORY ENTRIES. IF ANY START WITH AN INVALID - ; VALUE, INIT THE RAM DISK. VALID ENTRIES ARE E5 (EMPTY ENTRY) OR - ; 0-15 (USER NUMBER). - LD HL,0 - LD DE,32 - LD B,32 -CLRRAM0: - LD A,(HL) - CP 0E5H - JR Z,CLRRAM1 ; E5 IS VALID - CP 16 - JR C,CLRRAM1 ; 0-15 IS ALSO VALID - JR CLRRAM2 ; INVALID ENTRY! JUMP TO INIT -CLRRAM1: - ADD HL,DE ; LOOP FOR 32 ENTRIES - DJNZ CLRRAM0 -; JR CLRRAM2 ; *DEBUG* - JR CLRRAM3 ; ALL ENTRIES VALID, BYPASS INIT -CLRRAM2: -#ENDIF - CALL RAMPGZ - LD DE,STR_INITRAMDISK - CALL WRITESTR - LD A,2 - CALL RAMPG - - LD HL,0 ; SOURCE OF FILL IN HL - LD BC,2000H - 1 ; LENGTH OF FILL - 1 - LD A,0E5H ; FILL VALUE IN A - LD E,L ; DE = HL - LD D,H ; " - INC DE ; THEN OFFSET BY ONE - LD (HL),A ; FILL INITIAL BYTE - LDIR ; COMPLETE THE FILL -CLRRAM3: - CALL RAMPGZ -#ENDIF - RET -; -;__________________________________________________________________________________________________ -MD_READY: - LD A,TRUE - RET -; -;__________________________________________________________________________________________________ -MD_SELECT: - LD A,C - AND 0FH - ADD A,MID_MDROM - RET -; -;__________________________________________________________________________________________________ -MD_READ: - CALL MD_PGSEL ; SET PAGER BASED ON DRIVE AND TRACK - LD DE,(BUFADR) ; SETUP SECTOR BUF AS DESTINATION - CALL MD_SECADR ; SETUP RAM/ROM PAGE ADDRESS IN HL - CALL MD_DMACPY ; MOVE SECTOR TO SECBUF - CALL RAMPGZ ; RESTORE NORMAL 32K LOWER CPU RAM - LD DE,(DMAADR) ; SETUP FOR COPY TO DMA ADDRESS - LD HL,(BUFADR) ; FROM BUFFER - CALL MD_DMACPY ; COPY FROM BUF TO DMA - LD A,00H ; SIGNAL SUCCESS - RET -; -;__________________________________________________________________________________________________ -MD_WRITE: - ; CHECK FOR WRITE ACCESS TO ROM - LD A,(SEKDU) ; GET DRIVE - OR A ; DEVICE = 0, UNIT = 0 MEANS ROM DISK (READ ONLY!) - JR Z,MD_RDONLY - - LD DE,(BUFADR) ; GET SECTOR BUF ADDRESS - LD HL,(DMAADR) ; GET DMA BUF ADDRESS - CALL MD_DMACPY ; MOVE FROM DMA BUF TO SECTOR BUF - CALL MD_PGSEL ; SET PAGER BASED ON DRIVE AND TRACK - CALL MD_SECADR ; SETUP PAGE ADDRESS IN HL - LD DE,(BUFADR) ; SECTOR BUF ADDRESS IN DE - EX DE,HL ; REVERSE THEM TO... - CALL MD_DMACPY ; COPY FROM SECTOR BUF TO RAM PAGE - CALL RAMPGZ ; RESTORE NORMAL 32K LOWER CPU RAM - LD A,00H ; SIGNAL SUCCESS - RET - -MD_RDONLY: - LD DE,STR_READONLY ; SET DE TO START OF ERROR MESSAGE - CALL WRITESTR ; PRINT ERROR MESSAGE - LD A,1 ; SEND BAD SECTOR ERROR BACK - RET ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE -; -;__________________________________________________________________________________________________ -MD_SECADR: -; DETERMINE MEMORY ADDRESS CORRESPONDING TO CURRENT SECTOR -; SECTOR SIZE = 128, SO JUST MULTIPLY BY 128 -; RETURNS ADDRESS IN HL - LD HL,(SEKSEC) ; GET SECTOR INTO HL - LD B,7 -MD_SECADR1: - ADD HL,HL - DJNZ MD_SECADR1 - RET -;__________________________________________________________________________________________________ -MD_PGSEL: -; SELECT MEMORY PAGE BASED ON DRIVE AND TRACK -; DRIVE UNIT 0 = ROM, OTHERWISE RAM - - LD A,(SEKTRK) - INC A ; OFFSET PAST RESERVED 32KB SYSTEM AREA OF RAM/ROM! - INC A ; OFFSET ANOTHER 32K PAST DRIVER BANK - LD C,A - LD A,(SEKDU) - OR A - LD A,C - JP Z,ROMPG ; DEVICE/UNIT = 0? YES, ROM PAGE - JP RAMPG ; ELSE RAM PAGE -; -;__________________________________________________________________________________________________ -MD_DMACPY: -; COPIES ONE CPM SECTOR FROM ONE MEMORY ADDRESS TO ANOTHER -; INPUT DE=SOURCE ADDRESS, HL=TARGET ADDRESS, USES BC - LD BC,128 ; BC IS COUNTER FOR FIXED SIZE TRANSFER (128 BYTES) - LDIR ; TRANSFER - RET -; -#INCLUDE "memmgr.asm" -; -;================================================================================================== -; UTILITY FUNCTIONS -;================================================================================================== -; -#DEFINE CIOMODE_CBIOS -ORG_UTIL .EQU $ -#INCLUDE "util.asm" -SIZ_UTIL .EQU $ - ORG_UTIL - .ECHO "UTIL occupies " - .ECHO SIZ_UTIL - .ECHO " bytes.\n" -; -;================================================================================================== -; DIAGNOSTICS -;================================================================================================== -; -#IF DSKTRACE -;__________________________________________________________________________________________________ -PRTSELDSK: - CALL NEWLINE - PUSH BC - PUSH DE - LD B,E - LD DE,STR_SELDSK - CALL WRITESTR - CALL PC_SPACE - LD DE,STR_DSK - LD A,C - CALL PRTHEXBYTE - CALL PC_SPACE - CALL PC_LBKT - LD A,B - CALL PRTHEXBYTE - CALL PC_RBKT - POP DE - POP BC - RET -; -;__________________________________________________________________________________________________ -PRTHOME: - CALL NEWLINE - LD DE,STR_HOME - CALL WRITESTR - RET -; -;__________________________________________________________________________________________________ -PRTDSKOP: - - LD (XSTKSAV),SP - LD SP,XSTK - - CALL NEWLINE - LD A,(DSKOP) - LD DE,STR_READ - CP DOP_READ - CALL Z,WRITESTR - LD DE,STR_WRITE - CP DOP_WRITE - CALL Z,WRITESTR - LD A,C - CALL Z,PRTHEXBYTE - LD DE,STR_DSK - CALL WRITESTR - LD A,(SEKDSK) - CALL PRTHEXBYTE - LD DE,STR_TRK - CALL WRITESTR - LD BC,(SEKTRK) - CALL PRTHEXWORD - LD DE,STR_SEC - CALL WRITESTR - LD BC,(SEKSEC) - CALL PRTHEXWORD - - LD SP,(XSTKSAV) - - RET - - RET - -XSTKSAV .DW 0 - .FILL $20 -XSTK .EQU $ -; -STR_SELDSK .DB "SELDSK$" -STR_HOME .DB "HOME$" -STR_READ .DB "READ$" -STR_WRITE .DB "WRITE$" -STR_DSK .DB " DSK=$" -STR_TRK .DB " TRK=$" -STR_SEC .DB " SEC=$" -; -#ENDIF -; -;================================================================================================== -; DATA -;================================================================================================== -; -STR_BANNER .DB OSLBL, " for ", PLATFORM_NAME, " (CBIOS v", BIOSVER, ")$" -VAR_LOC .DB VARIANT -TST_LOC .DB TIMESTAMP -; -STR_INITRAMDISK .DB "\r\nFormatting RAMDISK...$" -STR_READONLY .DB "\r\nCBIOS Err: Read Only Drive$" -STR_STALE .DB "\r\nCBIOS Err: Stale Drive$" -; -SECADR: .DW 0 ; ADDRESS OF SECTOR IN ROM/RAM PAGE -DEFDRIVE .DB 0 ; DEFAULT DRIVE -; -; DOS DISK VARIABLES -; -DSKOP: .DB 0 ; DISK OPERATION (DOP_READ/DOP_WRITE) -WRTYPE: .DB 0 ; WRITE TYPE (0=NORMAL, 1=DIR (FORCE), 2=FIRST RECORD OF BLOCK) -DMAADR: .DW 0 ; DIRECT MEMORY ADDRESS -HSTWRT: .DB 0 ; TRUE = BUFFER IS DIRTY -BUFADR: .DW $8000 ; ADDRESS OF PHYSICAL SECTOR BUFFER (DEFAULT MATCHES HBIOS) -; -; DISK I/O REQUEST PENDING -; -SEK: -SEKDSK: .DB 0 ; DISK NUMBER 0-15 -SEKTRK: .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -SEKSEC: .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) -SEKDU: .DB 0 ; DEVICE/UNIT -SEKDPH: .DW 0 ; ADDRESS OF ACTIVE (SELECTED) DPH -SEKOFF: .DW 0 ; TRACK OFFSET IN EFFECT FOR LU -SEKACT: .DB TRUE ; ALWAYS TRUE! -; -; RESULT OF TRANSLATION CPM TO PHYSICAL TRANSLATION -; -XLT: -XLTDSK .DB 0 -XLTTRK .DW 0 -XLTSEC .DW 0 -XLTDU .DB 0 -XLTDPH .DW 0 -XLTOFF: .DW 0 -XLTACT .DB TRUE ; ALWAYS TRUE! -; -XLTSIZ .EQU $ - XLT -; -; DSK/TRK/SEC IN BUFFER (VALID WHEN HSTACT=TRUE) -; -HST: -HSTDSK .DB 0 ; DISK IN BUFFER -HSTTRK .DW 0 ; TRACK IN BUFFER -HSTSEC .DW 0 ; SECTOR IN BUFFER -HSTDU .DB 0 ; DEVICE/UNIT IN BUFFER -HSTDPH .DW 0 ; CURRENT DPH ADDRESS -HSTOFF .DW 0 ; TRACK OFFSET IN EFFECT FOR LU -HSTACT .DB 0 ; TRUE = BUFFER HAS VALID DATA -; -; SEQUENTIAL WRITE TRACKING FOR UNALLOCATED BLOCK -; -UNA: -UNADSK: .DB 0 ; DISK NUMBER 0-15 -UNATRK: .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -UNASEC: .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) -; -UNASIZ .EQU $ - UNA -; -UNACNT: .DB 0 ; COUNT DOWN UNALLOCATED RECORDS IN BLOCK -UNASPT: .DW 0 ; SECTORS PER TRACK -; -DIRBF: .FILL 128,00H ; SCRATCH DIRECTORY AREA -; -; DRIVER STORAGE -; -; MEMORY DISK 00: ROM DISK -; -ROMBLKS .EQU ((ROMSIZE - 64) / 2) -; - .DB DIODEV_MD + 0 -MDDPH0 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_ROM - .DW MDCSV0,MDALV0 -; -CKS_ROM .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -ALS_ROM .EQU ((ROMBLKS + 7) / 8) ; ALS: BLKS / 8 (ROUNDED UP) -; -; MEMORY DISK 01: RAM DISK -; -RAMBLKS .EQU ((RAMSIZE - 96) / 2) -; - .DB DIODEV_MD + 1 -MDDPH1 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_RAM - .DW MDCSV1,MDALV1 -; -CKS_RAM .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -ALS_RAM .EQU ((RAMBLKS + 7) / 8) ; ALS: BLKS / 8 (ROUNDED UP) -; -MDCSV0: .FILL 0 ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -MDALV0: .FILL ALS_ROM,00H ; MAX OF 512 DATA BLOCKS -MDCSV1: .FILL 0 ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -MDALV1: .FILL ALS_RAM,00H ; MAX OF 256 DATA BLOCKS -; -#IF (FDENABLE) -ORG_FD_DATA .EQU $ - #INCLUDE "fd_data.asm" -SIZ_FD_DATA .EQU $ - ORG_FD_DATA - .ECHO "FD_DATA occupies " - .ECHO SIZ_FD_DATA - .ECHO " bytes.\n" -#ENDIF - -#IF (IDEENABLE) -ORG_IDE_DATA .EQU $ - #INCLUDE "ide_data.asm" -SIZ_IDE_DATA .EQU $ - ORG_IDE_DATA - .ECHO "IDE_DATA occupies " - .ECHO SIZ_IDE_DATA - .ECHO " bytes.\n" -#ENDIF - -#IF (PPIDEENABLE) -ORG_PPIDE_DATA .EQU $ - #INCLUDE "ppide_data.asm" -SIZ_PPIDE_DATA .EQU $ - ORG_PPIDE_DATA - .ECHO "PPIDE_DATA occupies " - .ECHO SIZ_PPIDE_DATA - .ECHO " bytes.\n" -#ENDIF - -#IF (SDENABLE) -ORG_SD_DATA .EQU $ - #INCLUDE "sd_data.asm" -SIZ_SD_DATA .EQU $ - ORG_SD_DATA - .ECHO "SD_DATA occupies " - .ECHO SIZ_SD_DATA - .ECHO " bytes.\n" -#ENDIF - -#IF (PRPENABLE & PRPSDENABLE) -ORG_PRPSD_DATA .EQU $ - #INCLUDE "prp_data.asm" -SIZ_PRPSD_DATA .EQU $ - ORG_PRPSD_DATA - .ECHO "PRPSD_DATA occupies " - .ECHO SIZ_PRPSD_DATA - .ECHO " bytes.\n" -#ENDIF -#IF (PPPENABLE & PPPSDENABLE) -ORG_PPPSD_DATA .EQU $ - #INCLUDE "ppp_data.asm" -SIZ_PPPSD_DATA .EQU $ - ORG_PPPSD_DATA - .ECHO "PPPSD_DATA occupies " - .ECHO SIZ_PPPSD_DATA - .ECHO " bytes.\n" -#ENDIF -#IF (HDSKENABLE) -ORG_HDSK_DATA .EQU $ - #INCLUDE "hdsk_data.asm" -SIZ_HDSK_DATA .EQU $ - ORG_HDSK_DATA - .ECHO "HDSK_DATA occupies " - .ECHO SIZ_HDSK_DATA - .ECHO " bytes.\n" -#ENDIF -; -; DISK PARAMETER BLOCKS -; -; BLS BSH BLM EXM (DSM<256) EXM (DSM>255) -; ---------- --- --- ------------- ------------- -; 1,024 3 7 0 N/A -; 2,048 4 15 1 0 -; 4,096 5 31 3 1 -; 8,192 6 63 7 3 -; 16,384 7 127 15 7 -; -; AL0/1: EACH BIT SET ALLOCATES A BLOCK OF DIR ENTRIES. EACH DIR ENTRY -; IS 32 BYTES. BIT COUNT = (((DRM + 1) * 32) / BLS) -; -; CKS = (DIR ENT / 4), ZERO FOR NON-REMOVABLE MEDIA -; -; ALS = TOTAL BLKS (DSM + 1) / 8 -;__________________________________________________________________________________________________ -; -; ROM DISK: 256 SECS/TRK, 128 BYTES/SEC -; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -; ROM DISK SIZE = TOTAL ROM - 32K RESERVED FOR SYSTEM USE -; - .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_ROM: - .DW 256 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK -#IF (ROMBLKS < 256) - .DB 1 ; EXM: EXTENT MASK -#ELSE - .DB 0 ; EXM: EXTENT MASK -#ENDIF - .DW ROMBLKS - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1 - .DW 255 ; DRM: DIR ENTRIES - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: ROM DISK HAS NO SYSTEM AREA -;__________________________________________________________________________________________________ -; -; RAM DISK: 256 SECS/TRK, 128 BYTES/SEC -; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -; RAM DISK SIZE = TOTAL RAM - 64K RESERVED FOR SYSTEM USE -; - .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_RAM: - .DW 256 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK -#IF (RAMBLKS < 256) - .DB 1 ; EXM: EXTENT MASK -#ELSE - .DB 0 ; EXM: EXTENT MASK -#ENDIF - .DW RAMBLKS - 1 ; DSM: TOTAL STORAGE IN BLOCKS - 1 - .DW 255 ; DRM: DIR ENTRIES - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: ZERO FOR NON-REMOVABLE MEDIA - .DW 0 ; OFF: RESERVED TRACKS = 0 TRK -;__________________________________________________________________________________________________ -; -; 8MB HARD DISK DRIVE, 65 TRKS, 1024 SECS/TRK, 128 BYTES/SEC -; BLOCKSIZE (BLS) = 4K, DIRECTORY ENTRIES = 128 -; SEC/TRK ENGINEERED SO THAT AFTER DEBLOCKING, SECTOR NUMBER OCCUPIES 1 BYTE (0-255) -; - .DB (4096 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_HD: - .DW 1024 ; SPT: SECTORS PER TRACK - .DB 5 ; BSH: BLOCK SHIFT FACTOR - .DB 31 ; BLM: BLOCK MASK - .DB 1 ; EXM: EXTENT MASK - .DW 2047 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((8MB - 128K OFF) / 4K BLS) - 1 = 2047 - .DW 511 ; DRM: DIR ENTRIES - 1 = 512 - 1 = 511 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 0 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 1 ; OFF: RESERVED TRACKS = 1 TRKS * (512 B/SEC * 1024 SEC/TRK) = 128K -;__________________________________________________________________________________________________ -; -; IBM 720KB 3.5" FLOPPY DRIVE, 80 TRKS, 36 SECS/TRK, 512 BYTES/SEC -; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 128 -; - .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_FD720: - .DW 36 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 350 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((720K - 18K OFF) / 2K BLS) - 1 = 350 - .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 - .DB 11000000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 - .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K -;__________________________________________________________________________________________________ -; -; IBM 1.44MB 3.5" FLOPPY DRIVE, 80 TRKS, 72 SECS/TRK, 512 BYTES/SEC -; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -; - .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_FD144: - .DW 72 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 710 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,440K - 18K OFF) / 2K BLS) - 1 = 710 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 72 SEC/TRK) = 18K -;__________________________________________________________________________________________________ -; -; IBM 360KB 5.25" FLOPPY DRIVE, 40 TRKS, 9 SECS/TRK, 512 BYTES/SEC -; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 128 -; - .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_FD360: - .DW 36 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 170 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((360K - 18K OFF) / 2K BLS) - 1 = 170 - .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 - .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K -;__________________________________________________________________________________________________ -; -; IBM 1.20MB 5.25" FLOPPY DRIVE, 80 TRKS, 60 SECS/TRK, 512 BYTES/SEC -; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -; - .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_FD120: - .DW 60 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 591 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,200K - 15K OFF) / 2K BLS) - 1 = 591 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K -;__________________________________________________________________________________________________ -; -; IBM 1.11MB 8" FLOPPY DRIVE, 74 TRKS, 60 SECS/TRK, 512 BYTES/SEC -; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -; - .DB (2048 / 128) ; RECORDS PER BLOCK (BLS / 128) -DPB_FD111: - .DW 60 ; SPT: SECTORS PER TRACK - .DB 4 ; BSH: BLOCK SHIFT FACTOR - .DB 15 ; BLM: BLOCK MASK - .DB 0 ; EXM: EXTENT MASK - .DW 546 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,110K - 15K OFF) / 2K BLS) - 1 = 546 - .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 - .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE - .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE - .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 - .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K -; -;================================================================================================== -; START OF HIMEM AREA -;================================================================================================== -; -; THE FOLLOWING DATA STRUCTURES MUST NOT CROSS A PAGE BOUNDARY DUE TO OPTIMIZATION OF -; LOOKUP CODE. SO, HERE WE ORG SO THAT THERE IS JUST ENOUGH SPACE AT THE TOP OF THE -; CBIOS FOR THE DATA STRUCTURES. OBVIOUSLY, FOR THIS TO WORK, CBIOS MUST BE SET TO -; END AT A PAGE BOUNDARY, WHICH IS INTENDED -; -SLACK .EQU (CBIOS_END - $ - 32 - 32 - 16 - 512) - .FILL SLACK,00H -; - .ECHO "CBIOS space remaining: " - .ECHO SLACK - .ECHO " bytes.\n" -; -;================================================================================================== -; DPB MAPPING TABLE -;================================================================================================== -; -; MAP MEDIA ID'S TO APPROPRIATE DPB ADDRESSEES -; THE ENTRIES IN THIS TABLE MUST CONCIDE WITH THE VALUES -; OF THE MEDIA ID'S (SAME SEQUENCE, NO GAPS) -; -DPB_MAP: - .DW 0 ; MID_NONE (NO MEDIA) - .DW DPB_ROM ; MID_MDROM - .DW DPB_RAM ; MID_MDRAM - .DW DPB_HD ; MID_HD - .DW DPB_FD720 ; MID_FD720 - .DW DPB_FD144 ; MID_FD144 - .DW DPB_FD360 ; MID_FD360 - .DW DPB_FD120 ; MID_FD120 - .DW DPB_FD111 ; MID_FD111 -; -DPB_CNT .EQU ($ - DPB_MAP) / 2 -; -;================================================================================================== -; DRIVE LETTER MAPPING TABLE -;================================================================================================== -; -; THE DISK MAP TABLE BELOW MAPS DRIVE LETTERS TO PHYSICAL STORAGE DEVICES. -; CP/M DRIVE LETTERS ARE ASSIGNED BASED ON THE ORDER OF ENTRIES IN THE TABLE, -; SO THE FIRST ENTRY IS A:, THE SECOND ENTRY IS B:, ETC. -; EACH ENTRY IS A COMBINATION (OR) OF THE DEVICE AND THE UNIT. -; DIODEV_MD = MEMORY DISKS (ROM/RAM) (UNIT 0 = ROM, UNIT 1 = RAM) -; DIODEV_FD = FLOPPY DISKS (TWO UNITS (0/1) SUPPORTED) -; DIODEV_IDE = IDE DISKS (TWO UNITS (0/1) MASTER/SLAVE SUPPORTED) -; DIODEV_PPIDE = PPIDE DISKS (TWO UNITS (0/1) MASTER/SLAVE SUPPORTED) -; DIODEV_SD = SD CARD (ONE UNIT SUPPORTED) -; DIODEV_PRPSD = PROPIO SD CARD (ONE UNIT SUPPORTED) -; DIODEV_PPPSD = PROPIO SD CARD (ONE UNIT SUPPORTED) -; DIODEV_HDDSK = SIMH HARD DISK (TWO UNITS SUPPORTED) -; -; DRIVE LETTERS ARE ASSIGNED SEQUENTIALLY. -; -; ALTERNATIVELY, YOU CAN DEFINE A MACRO CALLED CUSTOM_DPHMAP THAT -; DEFINES AN ENTIRELY CUSTOM MAPPING -; -DPH_MAP: -#IFDEF CUSTOM_DPHMAP - CUSTOM_DPHMAP -#ELSE - #IF (DSKMAP == DM_ROM) - .DW MDDPH0 - #ENDIF - #IF (DSKMAP == DM_RAM) - .DW MDDPH1 - #ENDIF - #IF (DSKMAP == DM_FD) - .DW FDDPH0 - .DW FDDPH1 - #ENDIF - #IF (DSKMAP == DM_IDE) - .DW IDEDPH0 - .DW IDEDPH1 - .DW IDEDPH2 - .DW IDEDPH3 - #ENDIF - #IF (DSKMAP == DM_PPIDE) - .DW PPIDEDPH0 - .DW PPIDEDPH1 - .DW PPIDEDPH2 - .DW PPIDEDPH3 - #ENDIF - #IF (DSKMAP == DM_SD) - .DW SDDPH0 - .DW SDDPH1 - .DW SDDPH2 - .DW SDDPH3 - #ENDIF - #IF (DSKMAP == DM_PRPSD) - .DW PRPSDDPH0 - .DW PRPSDDPH1 - .DW PRPSDDPH2 - .DW PRPSDDPH3 - #ENDIF - #IF (DSKMAP == DM_PPPSD) - .DW PPPSDDPH0 - .DW PPPSDDPH1 - .DW PPPSDDPH2 - .DW PPPSDDPH3 - #ENDIF - #IF (DSKMAP == DM_HDSK) - .DW HDSKDPH0 - .DW HDSKDPH1 - .DW HDSKDPH2 - .DW HDSKDPH3 - #ENDIF - #IF (DSKMAP != DM_ROM) - .DW MDDPH0 - #ENDIF - #IF (DSKMAP != DM_RAM) - .DW MDDPH1 ; was MDDHP1 - #ENDIF - #IF ((DSKMAP != DM_FD) & FDENABLE) - .DW FDDPH0 - .DW FDDPH1 - #ENDIF - #IF ((DSKMAP != DM_IDE) & IDEENABLE) - .DW IDEDPH0 - .DW IDEDPH1 - .DW IDEDPH2 - .DW IDEDPH3 - #ENDIF - #IF ((DSKMAP != DM_PPIDE) & PPIDEENABLE) - .DW PPIDEDPH0 - .DW PPIDEDPH1 - .DW PPIDEDPH2 - .DW PPIDEDPH3 - #ENDIF - #IF ((DSKMAP != DM_SD) & SDENABLE) - .DW SDDPH0 - .DW SDDPH1 - .DW SDDPH2 - .DW SDDPH3 - #ENDIF - #IF ((DSKMAP != DM_PRPSD) & PRPENABLE & PRPSDENABLE) - .DW PRPSDDPH0 - .DW PRPSDDPH1 - .DW PRPSDDPH2 - .DW PRPSDDPH3 - #ENDIF - #IF ((DSKMAP != DM_PPPSD) & PPPENABLE & PPPSDENABLE) - .DW PPPSDDPH0 - .DW PPPSDDPH1 - .DW PPPSDDPH2 - .DW PPPSDDPH3 - #ENDIF - #IF ((DSKMAP != DM_HDSK) & HDSKENABLE) - .DW HDSKDPH0 - .DW HDSKDPH1 - .DW HDSKDPH2 - .DW HDSKDPH3 - #ENDIF -#ENDIF ; CUSTOM_DPHMAP -; -DPH_CNT .EQU ($ - DPH_MAP) / 2 - .FILL (16 - DPH_CNT) * 2,0FFH -DSK_CNT .EQU DPH_CNT -; -;================================================================================================== -; CHARACTER DEVICE MAPPING -;================================================================================================== -; -; MAP LOGICAL TO PHYSICAL DEVICES -; -LD_TTY .EQU CIODEV_UART -LD_CRT .EQU CIODEV_CRT -LD_BAT .EQU CIODEV_BAT -LD_UC1 .EQU CIODEV_UART -LD_PTR .EQU CIODEV_UART -LD_UR1 .EQU CIODEV_UART -LD_UR2 .EQU CIODEV_UART -LD_PTP .EQU CIODEV_UART -LD_UP1 .EQU CIODEV_UART -LD_UP2 .EQU CIODEV_UART -LD_LPT .EQU CIODEV_UART -LD_UL1 .EQU CIODEV_UART -; -#IF (PLATFORM == PLT_N8) -LD_UC1 .SET CIODEV_UART + 1 -#ENDIF -; -#IF (VDUENABLE) -LD_CRT .SET CIODEV_CRT -#ENDIF -#IF (N8VENABLE) -LD_CRT .SET CIODEV_CRT -#ENDIF -#IF (PRPENABLE & PRPCONENABLE) -LD_CRT .SET CIODEV_PRPCON -#ENDIF -#IF (PPPENABLE & PPPCONENABLE) -LD_CRT .SET CIODEV_PPPCON -#ENDIF -; -CIO_MAP: -; - ; CONSOLE - .DB LD_TTY ; CON:=TTY: (IOBYTE XXXXXX00) - .DB LD_CRT ; CON:=CRT: (IOBYTE XXXXXX01) - .DB LD_BAT ; CON:=BAT: (IOBYTE XXXXXX10) - .DB LD_UC1 ; CON:=UC1: (IOBYTE XXXXXX11) - ; READER - .DB LD_TTY ; RDR:=TTY: (IOBYTE XXXX00XX) - .DB LD_PTR ; RDR:=PTR: (IOBYTE XXXX01XX) - .DB LD_UR1 ; RDR:=UR1: (IOBYTE XXXX10XX) - .DB LD_UR2 ; RDR:=UR2: (IOBYTE XXXX11XX) - ; PUNCH - .DB LD_TTY ; PUN:=TTY: (IOBYTE XX00XXXX) - .DB LD_PTP ; PUN:=PTP: (IOBYTE XX01XXXX) - .DB LD_UP1 ; PUN:=UP1: (IOBYTE XX10XXXX) - .DB LD_UP2 ; PUN:=UP2: (IOBYTE XX11XXXX) - ; LIST - .DB LD_TTY ; LST:=TTY: (IOBYTE 00XXXXXX) - .DB LD_CRT ; LST:=CRT: (IOBYTE 01XXXXXX) - .DB LD_LPT ; LST:=LPT: (IOBYTE 10XXXXXX) - .DB LD_UL1 ; LST:=UL1: (IOBYTE 11XXXXXX) -; -;================================================================================================== -; SECTOR AND CONFIG BUFFER; -;================================================================================================== -; -; A 512 AREA IS ALLOCATED AT FD00 AND IS USED FOR TWO PURPOSES: -; 1) AS THE DISK SECTOR BUFFER AFTER CBIOS COLD INIT IS DONE -; 2) FOR CBIOS INIT CODE THAT CAN BE DISCARDED AFTER INITIALIZTION: -; A) SYSTEM CONFIGURATION DATA BUFFER -; B) CBIOS INIT CODE THAT CAN BE DISCARDED AFTER INIT -; - .FILL 0FD00H - $,00H ; MAKE SURE SEC/CFGBUF STARTS AT FD00 -; -SECBUF: ; START OF 512 BYTE DISK SECTOR -CFGBUF: ; START OF 256 BYTE CONFIG BUFFER - .FILL 256,0 -; -INIT: - DI - IM 1 - - ; SETUP A TEMP STACK IN UPPER 32K - LD SP,ISTACK ; STACK FOR INITIALIZATION - - ; ENSURE RAM PAGE ZERO ACTIVE - CALL RAMPGZ - - ; THIS INIT CODE WILL BE OVERLAID, SO WE ARE GOING - ; TO MODIFY THE BOOT ENTRY POINT TO CAUSE A PANIC - ; TO EASILY IDENTIFY IF SOMETHING TRIES TO INVOKE - ; THE BOOT ENTRY POINT AFTER INIT IS DONE. - LD A,0CDH ; "CALL" INSTRUCTION - LD (BOOT),A ; STORE IT BOOT ENTRY POINT - LD HL,PANIC ; ADDRESS OF PANIC ROUTINE - LD (BOOT+1),HL ; STORE IT AT BOOT ENTRY + 1 - - ; PARAMETER INITIALIZATION - LD A,DEFIOBYTE ; LOAD DEFAULT IOBYTE - LD (IOBYTE),A ; STORE IT - -#IF ((PLATFORM != PLT_N8) & (PLATFORM != PLT_S100)) - IN A,(RTC) ; RTC PORT, BIT 6 HAS STATE OF CONFIG JUMPER - BIT 6,A ; BIT 6 HAS CONFIG JUMPER STATE - LD A,DEFIOBYTE ; ASSUME WE WANT DEFAULT IOBYTE VALUE - JR NZ,INIT1 ; IF BIT6=1, NOT SHORTED, CONTINUE WITH DEFAULT - LD A,ALTIOBYTE ; LOAD ALT IOBYTE VALUE -INIT1: - LD (IOBYTE),A ; SET THE ACTIVE IOBYTE -#ENDIF - - ; DEFAULT DRIVE - CALL DEFDRV ; DETERMINE DEFAULT DRIVE - LD A,(DEFDRIVE) ; GET DEFAULT DRIVE - LD (CDISK),A ; SETUP CDISK - - ; STARTUP MESSAGE - CALL NEWLINE - LD DE,STR_BANNER - CALL WRITESTR - CALL NEWLINE - - ; SAVE COMMAND PROCESSOR TO CACHE IN RAM1 - LD A,1 - CALL RAMPG - LD HL,CPM_LOC ; LOCATION OF ACTIVE COMMAND PROCESSOR - LD DE,0800H ; LOCATION IN RAM 1 OF COMMAND PROCESSOR CACHE - LD BC,CCPSIZ ; SIZE OF COMMAND PROCESSOR - LDIR - CALL RAMPGZ - - ; SYSTEM INITIALIZATION - CALL BLKRES ; RESET DISK (DE)BLOCKING ALGORITHM - CALL MD_INIT ; INITIALIZE MEMORY DISK DRIVER (RAM/ROM) - - CALL NEWLINE - - ; STARTUP CPM - JP GOCPM -; -DEFDRV: - ; START BY ASSUMING DRIVE 0 IS DEFAULT - XOR A ; ZERO - LD (DEFDRIVE),A ; STORE IT - - ; GET CONFIG INFO (STORE IN CFGBUF) - LD BC,$F000 - LD DE,CFGBUF - RST 08 - - ; IF NOT A DISK DEVICE BOOT, BAIL OUT, NOTHING MORE TO DO - LD A,(CFGBUF+DISKBOOT) ; DID WE BOOT FROM A DISK DEVICE? - OR A ; SET FLAGS - RET Z - - ; SCAN DRIVES TO MATCH BOOTDEVICE/LU AND STORE DEFDRIVE - LD C,-1 ; INIT CURRENT DRIVE FOR LOOP -DEFDRV1: - INC C ; NEXT DRIVE - LD A,C ; A = C - CP 16 ; MAX DRIVE IS 15, PAST IT? - RET Z ; NO MATCHES, BAIL OUT - CALL DSK_GETDPH ; GET POINTER TO DPH INTO HL - OR A ; SET FLAGS - JR NZ,DEFDRV1 ; INVALID DRIVE, BYPASS IT - DEC HL ; POINT TO DEVICE/UNIT - LD E,(HL) ; E = DEVICE/UNIT BYTE - LD A,(CFGBUF+BOOTDEVICE) ; A = BOOTDEVICE - CP E ; MATCH BOOTDEVICE? - JR NZ,DEFDRV1 ; NOPE, NEXT DRIVE - INC HL ; POINT HL BACK TO START OF DPH - CALL DSK_GETLU ; GET POINTER TO LU DATA IN HL - JR NZ,DEFDRV2 ; NO LU SUPPORT, DEVICE ALREADY MATCHED, WE ARE DONE - LD E,(HL) ; E = LU LSB - LD A,(CFGBUF+BOOTLU) ; A = BOOT LU LSB - CP E ; MATCH LSB? - JR NZ,DEFDRV1 ; NOPE, NEXT DRIVE - INC HL ; POINT TO LU MSB - LD E,(HL) ; E = LU MSB - LD A,(CFGBUF+BOOTLU+1) ; A = BOOT LU MSB - CP E ; MATCH MSB? - JR NZ,DEFDRV1 ; NOPE, NEXT DRIVE - -DEFDRV2: - ; WE HAVE A MATCH MATCHED, RECORD NEW DEFAULT DRIVE - LD A,C ; C HAS MATCHING DRIVE, MOVE TO A - LD (DEFDRIVE),A ; SAVE IT -; - RET -; - .FILL (256 - ($ - INIT)),0 ; FILL REMAINDER OF PAGE -; -ISTACK .EQU $ ; TEMP STACK SPACE -; - .END diff --git a/branches/s100/Source/ccpb03.asm b/branches/s100/Source/ccpb03.asm deleted file mode 100644 index dd3c8462..00000000 --- a/branches/s100/Source/ccpb03.asm +++ /dev/null @@ -1,1264 +0,0 @@ - .title "Digital Research CCP, Version 2.2" - .page 49 - -MON .EQU 1 ;ADD THE CCP MON COMMAND -USRDSP .EQU 1 ;SHOW THE USER NUMBER -CHKU0B .EQU 0 ;CHECK FOR TRANSIENTS ON USER 0 TOO -ENDFIL .EQU 1 ;FILE FULL CCP SIZE -; -;************************************************************** -;* -;* C C P - C O N S O L E C O M M A N D P R O C E S S O R -;* -;************************************************************** -;* -IOBYTE: .EQU 3 ; I/O DEFINITION BYTE. -TDRIVE: .EQU 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY: .EQU 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB: .EQU 5CH ; DEFAULT FILE CONTROL BLOCK. -TBUFF: .EQU 80H ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE: .EQU 100H ; TRANSIANT PROGRAM STORAGE AREA. -; -; SET CONTROL CHARACTER .EQUATES. -; -CNTRLC: .EQU 03H ; CONTROL-C -CNTRLE: .EQU 05H ; CONTROL-E -BS: .EQU 08H ; BACKSPACE -TAB: .EQU 09H ; TAB -LF: .EQU 0AH ; LINE FEED -FF: .EQU 0CH ; FORM FEED -CR: .EQU 0DH ; CARRIAGE RETURN -CNTRLP: .EQU 10H ; CONTROL-P -CNTRLR: .EQU 12H ; CONTROL-R -CNTRLS: .EQU 13H ; CONTROL-S -CNTRLU: .EQU 15H ; CONTROL-U -CNTRLX: .EQU 18H ; CONTROL-X -CNTRLZ: .EQU 1AH ; CONTROL-Z (END-OF-FILE MARK) -DEL: .EQU 7FH ; RUBOUT -; -; SET ORIGIN FOR CP/M -; - -NK .EQU 59 ;SYSTEM SIZE -BASE .EQU (NK*1024)-5000H -CCPO .EQU BASE+3400H ;CCP ORIGIN -BDOSO .EQU BASE+3C00H ;BDOS ORIGIN -BIOSO .EQU BASE+4A00H ;BIOS ORIGIN - - .ORG CCPO -; -CBASE: JP COMMAND ; EXECUTE COMMAND PROCESSOR (CCP). - JP CLEARBUF ; ENTRY TO EMPTY INPUT BUFFER BEFORE STARTING CCP. - -; -; STANDARD CP/M CCP INPUT BUFFER. FORMAT IS (MAX LENGTH), -; (ACTUAL LENGTH), (CHAR #1), (CHAR #2), (CHAR #3), ETC. -; -INBUFF: .DB 127 ; LENGTH OF INPUT BUFFER. -; N8VEM - if add any text after this point, change .DB 0 below to length -; and put a 0 after the text, and delete the same number of zeros after the dig -; so that inpoint ends up at the same spot -; INBUFF+1 is cleared on the next warm boot, so only runs once. - .DB 0 ;CURRENT LENGTH OF CONTENTS. - - -; .DB 17 ; Autoboot length of string -; .DB "SUPERSUB AUTOEXEC" -; .DB 0 ; zero at end - - - .DB "COPYRIGHT" - .DB " 1979 (C) BY " - .DB "DIGITAL RESEARCH " - .FILL ((INBUFF + 128) - $),055H - - -INPOINT:.DW INBUFF+2 ; INPUT LINE POINTER -NAMEPNT:.DW 0 ; INPUT LINE POINTER USED FOR ERROR MESSAGE. POINTS TO -; ;START OF NAME IN ERROR. -; -; ROUTINE TO PRINT (A) ON THE CONSOLE. ALL REGISTERS USED. -; -PRINT: LD E,A ; SETUP BDOS CALL. - LD C,2 - JP ENTRY -; -; ROUTINE TO PRINT (A) ON THE CONSOLE AND TO SAVE (BC). -; -PRINTB: PUSH BC - CALL PRINT - POP BC - RET -; -; ROUTINE TO SEND A CARRIAGE RETURN, LINE FEED COMBINATION -; TO THE CONSOLE. -; -CRLF: LD A,CR - CALL PRINTB - LD A,LF - JP PRINTB -; -; ROUTINE TO SEND ONE SPACE TO THE CONSOLE AND SAVE (BC). -; -SPACE: LD A,' ' - JP PRINTB -; -; ROUTINE TO PRINT CHARACTER STRING POINTED TO BE (BC) ON THE -; CONSOLE. IT MUST TERMINATE WITH A NULL BYTE. -; -PLINE: PUSH BC - CALL CRLF - POP HL -PLINE2: LD A,(HL) - OR A - RET Z - INC HL - PUSH HL - CALL PRINT - POP HL - JP PLINE2 -; -; ROUTINE TO RESET THE DISK SYSTEM. -; -RESDSK: LD C,13 - JP ENTRY -; -; ROUTINE TO SELECT DISK (A). -; -DSKSEL: LD E,A - LD C,14 - JP ENTRY -; -; ROUTINE TO CALL BDOS AND SAVE THE RETURN CODE. THE ZERO -; FLAG IS SET ON A RETURN OF 0FFH. -; -ENTRY1: CALL ENTRY - LD (RTNCODE),A ; SAVE RETURN CODE. - INC A ; SET ZERO IF 0FFH RETURNED. - RET -; -; ROUTINE TO OPEN A FILE. (DE) MUST POINT TO THE FCB. -; -OPEN: LD C,15 - JP ENTRY1 -; -; ROUTINE TO OPEN FILE AT (FCB). -; -OPENFCB:XOR A ; CLEAR THE RECORD NUMBER BYTE AT FCB+32 - LD (FCB+32),A - LD DE,FCB - JP OPEN -; -; ROUTINE TO CLOSE A FILE. (DE) POINTS TO FCB. -; -CLOSE: LD C,16 - JP ENTRY1 -; -; ROUTINE TO SEARCH FOR THE FIRST FILE WITH AMBIGUEOUS NAME -; (DE). -; -SRCHFST:LD C,17 - JP ENTRY1 -; -; SEARCH FOR THE NEXT AMBIGEOUS FILE NAME. -; -SRCHNXT:LD C,18 - JP ENTRY1 -; -; SEARCH FOR FILE AT (FCB). -; -SRCHFCB:LD DE,FCB - JP SRCHFST -; -; ROUTINE TO DELETE A FILE POINTED TO BY (DE). -; -DELETE: LD C,19 - JP ENTRY -; -; ROUTINE TO CALL THE BDOS AND SET THE ZERO FLAG IF A ZERO -; STATUS IS RETURNED. -; -ENTRY2: CALL ENTRY - OR A ; SET ZERO FLAG IF APPROPRIATE. - RET -; -; ROUTINE TO READ THE NEXT RECORD FROM A S.EQUENTIAL FILE. -; (DE) POINTS TO THE FCB. -; -RDREC: LD C,20 - JP ENTRY2 -; -; ROUTINE TO READ FILE AT (FCB). -; -READFCB:LD DE,FCB - JP RDREC -; -; ROUTINE TO WRITE THE NEXT RECORD OF A S.EQUENTIAL FILE. -; (DE) POINTS TO THE FCB. -; -WRTREC: LD C,21 - JP ENTRY2 -; -; ROUTINE TO CREATE THE FILE POINTED TO BY (DE). -; -CREATE: LD C,22 - JP ENTRY1 -; -; ROUTINE TO RENAME THE FILE POINTED TO BY (DE). NOTE THAT -; THE NEW NAME STARTS AT (DE+16). -; -RENAM: LD C,23 - JP ENTRY -; -; GET THE CURRENT USER CODE. -; -GETUSR: LD E,0FFH -; -; ROUTNE TO GET OR SET THE CURRENT USER CODE. -; IF (E) IS FF THEN THIS IS A GET, ELSE IT IS A SET. -; -GETSETUC: - LD C,32 - JP ENTRY -; -; ROUTINE TO SET THE CURRENT DRIVE BYTE AT (TDRIVE). -; -SETCDRV:CALL GETUSR ; GET USER NUMBER - ADD A,A ; AND SHIFT INTO THE UPPER 4 BITS. - ADD A,A - ADD A,A - ADD A,A - LD HL,CDRIVE ; NOW ADD IN THE CURRENT DRIVE NUMBER. - OR (HL) - LD (TDRIVE),A ; AND SAVE. - RET -; -; MOVE CURRENTLY ACTIVE DRIVE DOWN TO (TDRIVE). -; -MOVECD: LD A,(CDRIVE) - LD (TDRIVE),A - RET -; -; ROUTINE TO CONVERT (A) INTO UPPER CASE ASCII. ONLY LETTERS -; ARE AFFECTED. -; -UPPER: CP 'A' ; CHECK FOR LETTERS IN THE RANGE OF 'A' TO 'Z'. - RET C - CP '{' - RET NC - AND 5FH ; CONVERT IT IF FOUND. - RET -; -; ROUTINE TO GET A LINE OF INPUT. WE MUST CHECK TO SEE IF THE -; USER IS IN (BATCH) MODE. IF SO, THEN READ THE INPUT FROM FILE -; ($$$.SUB). AT THE END, RESET TO CONSOLE INPUT. -; -GETINP: LD A,(BATCH) ; IF =0, THEN USE CONSOLE INPUT. - OR A - JP Z,GETINP1 -; -; USE THE SUBMIT FILE ($$$.SUB) WHICH IS PREPARED BY A -; SUBMIT RUN. IT MUST BE ON DRIVE (A) AND IT WILL BE DELETED -; IF AND ERROR OCCURES (LIKE EOF). -; - LD A,(CDRIVE) ; SELECT DRIVE 0 IF NEED BE. - OR A - LD A,0 ; ALWAYS USE DRIVE A FOR SUBMIT. - CALL NZ,DSKSEL ; SELECT IT IF REQUIRED. - LD DE,BATCHFCB - CALL OPEN ; LOOK FOR IT. - JP Z,GETINP1 ; IF NOT THERE, USE NORMAL INPUT. - LD A,(BATCHFCB+15) ; GET LAST RECORD NUMBER+1. - DEC A - LD (BATCHFCB+32),A - LD DE,BATCHFCB - CALL RDREC ; READ LAST RECORD. - JP NZ,GETINP1 ; QUIT ON END OF FILE. -; -; MOVE THIS RECORD INTO INPUT BUFFER. -; - LD DE,INBUFF+1 - LD HL,TBUFF ; DATA WAS READ INTO BUFFER HERE. - LD B,128 ; ALL 128 CHARACTERS MAY BE USED. - CALL HL2DE ; (HL) TO (DE), (B) BYTES. - LD HL,BATCHFCB+14 - LD (HL),0 ; ZERO OUT THE 'S2' BYTE. - INC HL ; AND DECREMENT THE RECORD COUNT. - DEC (HL) - LD DE,BATCHFCB ; CLOSE THE BATCH FILE NOW. - CALL CLOSE - JP Z,GETINP1 ; QUIT ON AN ERROR. - LD A,(CDRIVE) ; RE-SELECT PREVIOUS DRIVE IF NEED BE. - OR A - CALL NZ,DSKSEL ; DON'T DO NEEDLESS SELECTS. -; -; PRINT LINE JUST READ ON CONSOLE. -; - LD HL,INBUFF+2 - CALL PLINE2 - CALL CHKCON ; CHECK CONSOLE, QUIT ON A KEY. - JP Z,GETINP2 ; JUMP IF NO KEY IS PRESSED. -; -; TERMINATE THE SUBMIT JOB ON ANY KEYBOARD INPUT. DELETE THIS -; FILE SUCH THAT IT IS NOT RE-STARTED AND JUMP TO NORMAL KEYBOARD -; INPUT SECTION. -; - CALL DELBATCH ; DELETE THE BATCH FILE. - JP CMMND1 ; AND RESTART COMMAND INPUT. -; -; GET HERE FOR NORMAL KEYBOARD INPUT. DELETE THE SUBMIT FILE -; INCASE THERE WAS ONE. -; -GETINP1:CALL DELBATCH ; DELETE FILE ($$$.SUB). - CALL SETCDRV ; RESET ACTIVE DISK. - LD C,10 ; GET LINE FROM CONSOLE DEVICE. - LD DE,INBUFF - CALL ENTRY - CALL MOVECD ; RESET CURRENT DRIVE (AGAIN). -; -; CONVERT INPUT LINE TO UPPER CASE. -; -GETINP2:LD HL,INBUFF+1 - LD B,(HL) ; (B)=CHARACTER COUNTER. -GETINP3:INC HL - LD A,B ; END OF THE LINE? - OR A - JP Z,GETINP4 - LD A,(HL) ; CONVERT TO UPPER CASE. - CALL UPPER - LD (HL),A - DEC B ; ADJUST CHARACTER COUNT. - JP GETINP3 -GETINP4:LD (HL),A ; ADD TRAILING NULL. - LD HL,INBUFF+2 - LD (INPOINT),HL ; RESET INPUT LINE POINTER. - RET -; -; ROUTINE TO CHECK THE CONSOLE FOR A KEY PRESSED. THE ZERO -; FLAG IS SET IS NONE, ELSE THE CHARACTER IS RETURNED IN (A). -; -CHKCON: LD C,11 ; CHECK CONSOLE. - CALL ENTRY - OR A - RET Z ; RETURN IF NOTHING. - LD C,1 ; ELSE GET CHARACTER. - CALL ENTRY - OR A ; CLEAR ZERO FLAG AND RETURN. - RET -; -; ROUTINE TO GET THE CURRENTLY ACTIVE DRIVE NUMBER. -; -GETDSK: LD C,25 - JP ENTRY -; -; SET THE STABDARD DMA ADDRESS. -; -STDDMA: LD DE,TBUFF -; -; ROUTINE TO SET THE DMA ADDRESS TO (DE). -; -DMASET: LD C,26 - JP ENTRY -; -; DELETE THE BATCH FILE CREATED BY SUBMIT. -; -DELBATCH: - LD HL,BATCH ; IS BATCH ACTIVE? - LD A,(HL) - OR A - RET Z - LD (HL),0 ; YES, DE-ACTIVATE IT. - XOR A - CALL DSKSEL ; SELECT DRIVE 0 FOR SURE. - LD DE,BATCHFCB ; AND DELETE THIS FILE. - CALL DELETE - LD A,(CDRIVE) ; RESET CURRENT DRIVE. - JP DSKSEL -; -; PRINT BACK FILE NAME WITH A '?' TO INDICATE A SYNTAX ERROR. -; -SYNERR: CALL CRLF ; END CURRENT LINE. - LD HL,(NAMEPNT) ; THIS POINTS TO NAME IN ERROR. -SYNERR1:LD A,(HL) ; PRINT IT UNTIL A SPACE OR NULL IS FOUND. - CP ' ' - JP Z,SYNERR2 - OR A - JP Z,SYNERR2 - PUSH HL - CALL PRINT - POP HL - INC HL - JP SYNERR1 -SYNERR2:LD A,'?' ; ADD TRAILING '?'. - CALL PRINT - CALL CRLF - CALL DELBATCH ; DELETE ANY BATCH FILE. - JP CMMND1 ; AND RESTART FROM CONSOLE INPUT. -; -; CHECK CHARACTER AT (DE) FOR LEGAL COMMAND INPUT. NOTE THAT THE -; ZERO FLAG IS SET IF THE CHARACTER IS A DELIMITER. -; -CHECK: LD A,(DE) - OR A - RET Z - CP ' ' ; CONTROL CHARACTERS ARE NOT LEGAL HERE. - JP C,SYNERR - RET Z ; CHECK FOR VALID DELIMITER. - CP '=' - RET Z - CP '_' - RET Z - CP '.' - RET Z - CP ':' - RET Z - CP $3B - RET Z - CP '<' - RET Z - CP '>' - RET Z - RET -; -; GET THE NEXT NON-BLANK CHARACTER FROM (DE). -; -NONBLANK: - LD A,(DE) - OR A ; STRING ENDS WITH A NULL. - RET Z - CP ' ' - RET NZ - INC DE - JP NONBLANK -; -; ADD (HL)=(HL)+(A) -; -ADDHL: ADD A,L - LD L,A - RET NC ; TAKE CARE OF ANY CARRY. - INC H - RET -; -; CONVERT THE FIRST NAME IN (FCB). -; -CONVFST:LD A,0 -; -; FORMAT A FILE NAME (CONVERT * TO '?', ETC.). ON RETURN, -; (A)=0 IS AN UNAMBIGEOUS NAME WAS SPECIFIED. ENTER WITH (A) .EQUAL TO -; THE POSITION WITHIN THE FCB FOR THE NAME (EITHER 0 OR 16). -; -CONVERT:LD HL,FCB - CALL ADDHL - PUSH HL - PUSH HL - XOR A - LD (CHGDRV),A ; INITIALIZE DRIVE CHANGE FLAG. - LD HL,(INPOINT) ; SET (HL) AS POINTER INTO INPUT LINE. - EX DE,HL - CALL NONBLANK ; GET NEXT NON-BLANK CHARACTER. - EX DE,HL - LD (NAMEPNT),HL ; SAVE POINTER HERE FOR ANY ERROR MESSAGE. - EX DE,HL - POP HL - LD A,(DE) ; GET FIRST CHARACTER. - OR A - JP Z,CONVRT1 - SBC A,'A'-1 ; MIGHT BE A DRIVE NAME, CONVERT TO BINARY. - LD B,A ; AND SAVE. - INC DE ; CHECK NEXT CHARACTER FOR A ':'. - LD A,(DE) - CP ':' - JP Z,CONVRT2 - DEC DE ; NOPE, MOVE POINTER BACK TO THE START OF THE LINE. -CONVRT1:LD A,(CDRIVE) - LD (HL),A - JP CONVRT3 -CONVRT2:LD A,B - LD (CHGDRV),A ; SET CHANGE IN DRIVES FLAG. - LD (HL),B - INC DE -; -; CONVERT THE BASIC FILE NAME. -; -CONVRT3:LD B,08H -CONVRT4:CALL CHECK - JP Z,CONVRT8 - INC HL - CP '*' ; NOTE THAT AN '*' WILL FILL THE REMAINING - JP NZ,CONVRT5 ; FIELD WITH '?'. - LD (HL),'?' - JP CONVRT6 -CONVRT5:LD (HL),A - INC DE -CONVRT6:DEC B - JP NZ,CONVRT4 -CONVRT7:CALL CHECK ; GET NEXT DELIMITER. - JP Z,GETEXT - INC DE - JP CONVRT7 -CONVRT8:INC HL ; BLANK FILL THE FILE NAME. - LD (HL),' ' - DEC B - JP NZ,CONVRT8 -; -; GET THE EXTENSION AND CONVERT IT. -; -GETEXT: LD B,03H - CP '.' - JP NZ,GETEXT5 - INC DE -GETEXT1:CALL CHECK - JP Z,GETEXT5 - INC HL - CP '*' - JP NZ,GETEXT2 - LD (HL),'?' - JP GETEXT3 -GETEXT2:LD (HL),A - INC DE -GETEXT3:DEC B - JP NZ,GETEXT1 -GETEXT4:CALL CHECK - JP Z,GETEXT6 - INC DE - JP GETEXT4 -GETEXT5:INC HL - LD (HL),' ' - DEC B - JP NZ,GETEXT5 -GETEXT6:LD B,3 -GETEXT7:INC HL - LD (HL),0 - DEC B - JP NZ,GETEXT7 - EX DE,HL - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - POP HL -; -; CHECK TO SEE IF THIS IS AN AMBIGEOUS FILE NAME SPECIFICATION. -; SET THE (A) REGISTER TO NON ZERO IF IT IS. -; - LD BC,11 ; SET NAME LENGTH. -GETEXT8:INC HL - LD A,(HL) - CP '?' ; ANY QUESTION MARKS? - JP NZ,GETEXT9 - INC B ; COUNT THEM. -GETEXT9:DEC C - JP NZ,GETEXT8 - LD A,B - OR A - RET -; -; CP/M COMMAND TABLE. NOTE COMMANDS CAN BE EITHER 3 OR 4 CHARACTERS LONG. -; - .IF MON -NUMCMDS:.EQU 7 ; NUMBER OF COMMANDS - .ELSE -NUMCMDS:.EQU 6 ; NUMBER OF COMMANDS - .ENDIF - -CMDTBL: .DB "DIR " - .DB "ERA " - .DB "TYPE" - .DB "SAVE" - .DB "REN " - .DB "USER" - .IF MON - .DB "MON " - .ENDIF - -CMDADR: .DW DIRECT - .DW ERASE - .DW TYPE - .DW SAVE - .DW RENAME - .DW USER - .IF MON - .DW MONITOR - .ENDIF - .DW UNKNOWN -; -; SEARCH THE COMMAND TABLE FOR A MATCH WITH WHAT HAS JUST -; BEEN ENTERED. IF A MATCH IS FOUND, THEN WE JUMP TO THE -; PROPER SECTION. ELSE JUMP TO (UNKNOWN). -; ON RETURN, THE (C) REGISTER IS SET TO THE COMMAND NUMBER -; THAT MATCHED (OR NUMCMDS+1 IF NO MATCH). -; -SEARCH: LD HL,CMDTBL - LD C,0 -SEARCH1:LD A,C - CP NUMCMDS ; THIS COMMANDS EXISTS. - RET NC - LD DE,FCB+1 ; CHECK THIS ONE. - LD B,4 ; MAX COMMAND LENGTH. -SEARCH2:LD A,(DE) - CP (HL) - JP NZ,SEARCH3 ; NOT A MATCH. - INC DE - INC HL - DEC B - JP NZ,SEARCH2 - LD A,(DE) ; ALLOW A 3 CHARACTER COMMAND TO MATCH. - CP ' ' - JP NZ,SEARCH4 - LD A,C ; SET RETURN REGISTER FOR THIS COMMAND. - RET -SEARCH3:INC HL - DEC B - JP NZ,SEARCH3 -SEARCH4:INC C - JP SEARCH1 -; -; SET THE INPUT BUFFER TO EMPTY AND THEN START THE COMMAND -; PROCESSOR (CCP). -; -CLEARBUF: - XOR A - LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH. -COMMAND:LD SP,CCPSTACK ; SETUP STACK AREA. - PUSH BC ; NOTE THAT (C) SHOULD BE .EQUAL TO: - LD A,C ; (UUUUDDDD) WHERE 'UUUU' IS THE USER NUMBER - RRA ; AND 'DDDD' IS THE DRIVE NUMBER. - RRA - RRA - RRA - AND 0FH ; ISOLATE THE USER NUMBER. - LD E,A - CALL GETSETUC ; AND SET IT. - CALL RESDSK ; RESET THE DISK SYSTEM. - LD (BATCH),A ; CLEAR BATCH MODE FLAG. - POP BC - LD A,C - AND 0FH ; ISOLATE THE DRIVE NUMBER. - LD (CDRIVE),A ; AND SAVE. - CALL DSKSEL ; ...AND SELECT. - LD A,(INBUFF+1) - OR A ; ANYTHING IN INPUT BUFFER ALREADY? - JP NZ,CMMND2 ; YES, WE JUST PROCESS IT. -; -; ENTRY POINT TO GET A COMMAND LINE FROM THE CONSOLE. -; -CMMND1: LD SP,CCPSTACK ; SET STACK STRAIGHT. - CALL CRLF ; START A NEW LINE ON THE SCREEN. - CALL GETDSK ; GET CURRENT DRIVE. - ADD A,'A' - CALL PRINT ; PRINT CURRENT DRIVE. - .IF USRDSP - CALL GETUSR ;GET CURRENT USER NUMBER - CP 10 ;TWO DIGITS? - JR C,CMMND3 ;NO - LD A,'1' ;PRINT LEADING '1' - CALL PRINT - CALL GETUSR ;GET CURRENT USER NUMBER - SUB 10 ;SUBTRACT 10 -CMMND3: ADD A,'0' - CALL PRINT - .ENDIF - LD A,'>' - CALL PRINT ; AND ADD PROMPT. - CALL GETINP ; GET LINE FROM USER. -; -; PROCESS COMMAND LINE HERE. -; -CMMND2: LD DE,TBUFF - CALL DMASET ; SET STANDARD DMA ADDRESS. - CALL GETDSK - LD (CDRIVE),A ; SET CURRENT DRIVE. - CALL CONVFST ; CONVERT NAME TYPED IN. - CALL NZ,SYNERR ; WILD CARDS ARE NOT ALLOWED. - LD A,(CHGDRV) ; IF A CHANGE IN DRIVES WAS INDICATED, - OR A ; THEN TREAT THIS AS AN UNKNOWN COMMAND - JP NZ,UNKNOWN ; WHICH GETS EXECUTED. - CALL SEARCH ; ELSE SEARCH COMMAND TABLE FOR A MATCH. -; -; NOTE THAT AN UNKNOWN COMMAND RETURNS -; WITH (A) POINTING TO THE LAST ADDRESS -; IN OUR TABLE WHICH IS (UNKNOWN). -; - LD HL,CMDADR ; NOW, LOOK THRU OUR ADDRESS TABLE FOR COMMAND (A). - LD E,A ; SET (DE) TO COMMAND NUMBER. - LD D,0 - ADD HL,DE - ADD HL,DE ; (HL)=(CMDADR)+2*(COMMAND NUMBER). - LD A,(HL) ; NOW PICK OUT THIS ADDRESS. - INC HL - LD H,(HL) - LD L,A - JP (HL) ; NOW EXECUTE IT. -; -; READ ERROR WHILE TYPEING A FILE. -; -RDERROR:LD BC,RDERR - JP PLINE -RDERR: .DB "Read Error",0 -; -; REQUIRED FILE WAS NOT LOCATED. -; -NONE: LD BC,NOFILE - JP PLINE -NOFILE: .DB "No File",0 -; -; DECODE A COMMAND OF THE FORM 'A>FILENAME NUMBER{ FILENAME}. -; NOTE THAT A DRIVE SPECIFIER IS NOT ALLOWED ON THE FIRST FILE -; NAME. ON RETURN, THE NUMBER IS IN REGISTER (A). ANY ERROR -; CAUSES 'FILENAME?' TO BE PRINTED AND THE COMMAND IS ABORTED. -; -DECODE: CALL CONVFST ; CONVERT FILENAME. - LD A,(CHGDRV) ; DO NOT ALLOW A DRIVE TO BE SPECIFIED. - OR A - JP NZ,SYNERR - LD HL,FCB+1 ; CONVERT NUMBER NOW. - LD BC,11 ; (B)=SUM REGISTER, (C)=MAX DIGIT COUNT. -DECODE1:LD A,(HL) - CP ' ' ; A SPACE TERMINATES THE NUMERAL. - JP Z,DECODE3 - INC HL - SUB '0' ; MAKE BINARY FROM ASCII. - CP 10 ; LEGAL DIGIT? - JP NC,SYNERR - LD D,A ; YES, SAVE IT IN (D). - LD A,B ; COMPUTE (B)=(B)*10 AND CHECK FOR OVERFLOW. - AND 0E0H - JP NZ,SYNERR - LD A,B - RLCA - RLCA - RLCA ; (A)=(B)*8 - ADD A,B ; .......*9 - JP C,SYNERR - ADD A,B ; .......*10 - JP C,SYNERR - ADD A,D ; ADD IN NEW DIGIT NOW. -DECODE2:JP C,SYNERR - LD B,A ; AND SAVE RESULT. - DEC C ; ONLY LOOK AT 11 DIGITS. - JP NZ,DECODE1 - RET -DECODE3:LD A,(HL) ; SPACES MUST FOLLOW (WHY?). - CP ' ' - JP NZ,SYNERR - INC HL -DECODE4:DEC C - JP NZ,DECODE3 - LD A,B ; SET (A)=THE NUMERIC VALUE ENTERED. - RET -; -; MOVE 3 BYTES FROM (HL) TO (DE). NOTE THAT THERE IS ONLY -; ONE REFERENCE TO THIS AT (A2D5H). -; -MOVE3: LD B,3 -; -; MOVE (B) BYTES FROM (HL) TO (DE). -; -HL2DE: LD A,(HL) - LD (DE),A - INC HL - INC DE - DEC B - JP NZ,HL2DE - RET -; -; COMPUTE (HL)=(TBUFF)+(A)+(C) AND GET THE BYTE THAT'S HERE. -; -EXTRACT:LD HL,TBUFF - ADD A,C - CALL ADDHL - LD A,(HL) - RET -; -; CHECK DRIVE SPECIFIED. IF IT MEANS A CHANGE, THEN THE NEW -; DRIVE WILL BE SELECTED. IN ANY CASE, THE DRIVE BYTE OF THE -; FCB WILL BE SET TO NULL (MEANS USE CURRENT DRIVE). -; -DSELECT:XOR A ; NULL OUT FIRST BYTE OF FCB. - LD (FCB),A - LD A,(CHGDRV) ; A DRIVE CHANGE INDICATED? - OR A - RET Z - DEC A ; YES, IS IT THE SAME AS THE CURRENT DRIVE? - LD HL,CDRIVE - CP (HL) - RET Z - JP DSKSEL ; NO. SELECT IT THEN. -; -; CHECK THE DRIVE SELECTION AND RESET IT TO THE PREVIOUS -; DRIVE IF IT WAS CHANGED FOR THE PRECEEDING COMMAND. -; -RESETDR:LD A,(CHGDRV) ; DRIVE CHANGE INDICATED? - OR A - RET Z - DEC A ; YES, WAS IT A DIFFERENT DRIVE? - LD HL,CDRIVE - CP (HL) - RET Z - LD A,(CDRIVE) ; YES, RE-SELECT OUR OLD DRIVE. - JP DSKSEL - -; -;************************************************************** -;* -;* M O N I T O R C O M M A N D -;* -;************************************************************** -; - .IF MON -MONITOR:RST 38 - .ENDIF - -; -;************************************************************** -;* -;* D I R E C T O R Y C O M M A N D -;* -;************************************************************** -; -DIRECT: CALL CONVFST ; CONVERT FILE NAME. - CALL DSELECT ; SELECT INDICATED DRIVE. - LD HL,FCB+1 ; WAS ANY FILE INDICATED? - LD A,(HL) - CP ' ' - JP NZ,DIRECT2 - LD B,11 ; NO. FILL FIELD WITH '?' - SAME AS *.*. -DIRECT1:LD (HL),'?' - INC HL - DEC B - JP NZ,DIRECT1 -DIRECT2:LD E,0 ; SET INITIAL CURSOR POSITION. - PUSH DE - CALL SRCHFCB ; GET FIRST FILE NAME. - CALL Z,NONE ; NONE FOUND AT ALL? -DIRECT3:JP Z,DIRECT9 ; TERMINATE IF NO MORE NAMES. - LD A,(RTNCODE) ; GET FILE'S POSITION IN SEGMENT (0-3). - RRCA - RRCA - RRCA - AND 60H ; (A)=POSITION*32 - LD C,A - LD A,10 - CALL EXTRACT ; EXTRACT THE TENTH ENTRY IN FCB. - RLA ; CHECK SYSTEM FILE STATUS BIT. - JP C,DIRECT8 ; WE DON'T LIST THEM. - POP DE - LD A,E ; BUMP NAME COUNT. - INC E - PUSH DE - AND 03H ; AT END OF LINE? - PUSH AF - JP NZ,DIRECT4 - CALL CRLF ; YES, END THIS LINE AND START ANOTHER. - PUSH BC - CALL GETDSK ; START LINE WITH ('A:'). - POP BC - ADD A,'A' - CALL PRINTB - LD A,':' - CALL PRINTB - JP DIRECT5 -DIRECT4:CALL SPACE ; ADD SEPERATOR BETWEEN FILE NAMES. - LD A,':' - CALL PRINTB -DIRECT5:CALL SPACE - LD B,1 ; 'EXTRACT' EACH FILE NAME CHARACTER AT A TIME. -DIRECT6:LD A,B - CALL EXTRACT - AND 7FH ; STRIP BIT 7 (STATUS BIT). - CP ' ' ; ARE WE AT THE END OF THE NAME? - JP NZ,DRECT65 - POP AF ; YES, DON'T PRINT SPACES AT THE END OF A LINE. - PUSH AF - CP 3 - JP NZ,DRECT63 - LD A,9 ; FIRST CHECK FOR NO EXTENSION. - CALL EXTRACT - AND 7FH - CP ' ' - JP Z,DIRECT7 ; DON'T PRINT SPACES. -DRECT63:LD A,' ' ; ELSE PRINT THEM. -DRECT65:CALL PRINTB - INC B ; BUMP TO NEXT CHARACTER PSOITION. - LD A,B - CP 12 ; END OF THE NAME? - JP NC,DIRECT7 - CP 9 ; NOPE, STARTING EXTENSION? - JP NZ,DIRECT6 - CALL SPACE ; YES, ADD SEPERATING SPACE. - JP DIRECT6 -DIRECT7:POP AF ; GET THE NEXT FILE NAME. -DIRECT8:CALL CHKCON ; FIRST CHECK CONSOLE, QUIT ON ANYTHING. - JP NZ,DIRECT9 - CALL SRCHNXT ; GET NEXT NAME. - JP DIRECT3 ; AND CONTINUE WITH OUR LIST. -DIRECT9:POP DE ; RESTORE THE STACK AND RETURN TO COMMAND LEVEL. - JP GETBACK -; -;************************************************************** -;* -;* E R A S E C O M M A N D -;* -;************************************************************** -; -ERASE: CALL CONVFST ; CONVERT FILE NAME. - CP 11 ; WAS '*.*' ENTERED? - JP NZ,ERASE1 - LD BC,YESNO ; YES, ASK FOR CONFIRMATION. - CALL PLINE - CALL GETINP - LD HL,INBUFF+1 - DEC (HL) ; MUST BE EXACTLY 'Y'. - JP NZ,CMMND1 - INC HL - LD A,(HL) - CP 'Y' - JP NZ,CMMND1 - INC HL - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. -ERASE1: CALL DSELECT ; SELECT DESIRED DISK. - LD DE,FCB - CALL DELETE ; DELETE THE FILE. - INC A - CALL Z,NONE ; NOT THERE? - JP GETBACK ; RETURN TO COMMAND LEVEL NOW. -YESNO: .DB "All (Y/N)?",0 -; -;************************************************************** -;* -;* T Y P E C O M M A N D -;* -;************************************************************** -; -TYPE: CALL CONVFST ; CONVERT FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - CALL DSELECT ; SELECT INDICATED DRIVE. - CALL OPENFCB ; OPEN THE FILE. - JP Z,TYPE5 ; NOT THERE? - CALL CRLF ; OK, START A NEW LINE ON THE SCREEN. - LD HL,NBYTES ; INITIALIZE BYTE COUNTER. - LD (HL),0FFH ; SET TO READ FIRST SECTOR. -TYPE1: LD HL,NBYTES -TYPE2: LD A,(HL) ; HAVE WE WRITTEN THE ENTIRE SECTOR? - CP 128 - JP C,TYPE3 - PUSH HL ; YES, READ IN THE NEXT ONE. - CALL READFCB - POP HL - JP NZ,TYPE4 ; END OR ERROR? - XOR A ; OK, CLEAR BYTE COUNTER. - LD (HL),A -TYPE3: INC (HL) ; COUNT THIS BYTE. - LD HL,TBUFF ; AND GET THE (A)TH ONE FROM THE BUFFER (TBUFF). - CALL ADDHL - LD A,(HL) - CP CNTRLZ ; END OF FILE MARK? - JP Z,GETBACK - CALL PRINT ; NO, PRINT IT. - CALL CHKCON ; CHECK CONSOLE, QUIT IF ANYTHING READY. - JP NZ,GETBACK - JP TYPE1 -; -; GET HERE ON AN END OF FILE OR READ ERROR. -; -TYPE4: DEC A ; READ ERROR? - JP Z,GETBACK - CALL RDERROR ; YES, PRINT MESSAGE. -TYPE5: CALL RESETDR ; AND RESET PROPER DRIVE - JP SYNERR ; NOW PRINT FILE NAME WITH PROBLEM. -; -;************************************************************** -;* -;* S A V E C O M M A N D -;* -;************************************************************** -; -SAVE: CALL DECODE ; GET NUMERIC NUMBER THAT FOLLOWS SAVE. - PUSH AF ; SAVE NUMBER OF PAGES TO WRITE. - CALL CONVFST ; CONVERT FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - CALL DSELECT ; SELECT SPECIFIED DRIVE. - LD DE,FCB ; NOW DELETE THIS FILE. - PUSH DE - CALL DELETE - POP DE - CALL CREATE ; AND CREATE IT AGAIN. - JP Z,SAVE3 ; CAN'T CREATE? - XOR A ; CLEAR RECORD NUMBER BYTE. - LD (FCB+32),A - POP AF ; CONVERT PAGES TO SECTORS. - LD L,A - LD H,0 - ADD HL,HL ; (HL)=NUMBER OF SECTORS TO WRITE. - LD DE,TBASE ; AND WE START FROM HERE. -SAVE1: LD A,H ; DONE YET? - OR L - JP Z,SAVE2 - DEC HL ; NOPE, COUNT THIS AND COMPUTE THE START - PUSH HL ; OF THE NEXT 128 BYTE SECTOR. - LD HL,128 - ADD HL,DE - PUSH HL ; SAVE IT AND SET THE TRANSFER ADDRESS. - CALL DMASET - LD DE,FCB ; WRITE OUT THIS SECTOR NOW. - CALL WRTREC - POP DE ; RESET (DE) TO THE START OF THE LAST SECTOR. - POP HL ; RESTORE SECTOR COUNT. - JP NZ,SAVE3 ; WRITE ERROR? - JP SAVE1 -; -; GET HERE AFTER WRITING ALL OF THE FILE. -; -SAVE2: LD DE,FCB ; NOW CLOSE THE FILE. - CALL CLOSE - INC A ; DID IT CLOSE OK? - JP NZ,SAVE4 -; -; PRINT OUT ERROR MESSAGE (NO SPACE). -; -SAVE3: LD BC,NOSPACE - CALL PLINE -SAVE4: CALL STDDMA ; RESET THE STANDARD DMA ADDRESS. - JP GETBACK -NOSPACE:.DB "No Space",0 -; -;************************************************************** -;* -;* R E N A M E C O M M A N D -;* -;************************************************************** -; -RENAME: CALL CONVFST ; CONVERT FIRST FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - LD A,(CHGDRV) ; REMEMBER ANY CHANGE IN DRIVES SPECIFIED. - PUSH AF - CALL DSELECT ; AND SELECT THIS DRIVE. - CALL SRCHFCB ; IS THIS FILE PRESENT? - JP NZ,RENAME6 ; YES, PRINT ERROR MESSAGE. - LD HL,FCB ; YES, MOVE THIS NAME INTO SECOND SLOT. - LD DE,FCB+16 - LD B,16 - CALL HL2DE - LD HL,(INPOINT) ; GET INPUT POINTER. - EX DE,HL - CALL NONBLANK ; GET NEXT NON BLANK CHARACTER. - CP '=' ; ONLY ALLOW AN '=' OR '_' SEPERATOR. - JP Z,RENAME1 - CP '_' - JP NZ,RENAME5 -RENAME1:EX DE,HL - INC HL ; OK, SKIP SEPERATOR. - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - CALL CONVFST ; CONVERT THIS SECOND FILE NAME NOW. - JP NZ,RENAME5 ; AGAIN, NO WILD CARDS. - POP AF ; IF A DRIVE WAS SPECIFIED, THEN IT - LD B,A ; MUST BE THE SAME AS BEFORE. - LD HL,CHGDRV - LD A,(HL) - OR A - JP Z,RENAME2 - CP B - LD (HL),B - JP NZ,RENAME5 ; THEY WERE DIFFERENT, ERROR. -RENAME2:LD (HL),B ; RESET AS PER THE FIRST FILE SPECIFICATION. - XOR A - LD (FCB),A ; CLEAR THE DRIVE BYTE OF THE FCB. -RENAME3:CALL SRCHFCB ; AND GO LOOK FOR SECOND FILE. - JP Z,RENAME4 ; DOESN'T EXIST? - LD DE,FCB - CALL RENAM ; OK, RENAME THE FILE. - JP GETBACK -; -; PROCESS RENAME ERRORS HERE. -; -RENAME4:CALL NONE ; FILE NOT THERE. - JP GETBACK -RENAME5:CALL RESETDR ; BAD COMMAND FORMAT. - JP SYNERR -RENAME6:LD BC,EXISTS ; DESTINATION FILE ALREADY EXISTS. - CALL PLINE - JP GETBACK -EXISTS: .DB "File Exists",0 -; -;************************************************************** -;* -;* U S E R C O M M A N D -;* -;************************************************************** -; -USER: CALL DECODE ; GET NUMERIC VALUE FOLLOWING COMMAND. - CP 16 ; LEGAL USER NUMBER? - JP NC,SYNERR - LD E,A ; YES BUT IS THERE ANYTHING ELSE? - LD A,(FCB+1) - CP ' ' - JP Z,SYNERR ; YES, THAT IS NOT ALLOWED. - CALL GETSETUC ; OK, SET USER CODE. - JP GETBACK1 -; -;************************************************************** -;* -;* T R A N S I A N T P R O G R A M C O M M A N D -;* -;************************************************************** -; -UNKNOWN:LD A,(FCB+1) ; ANYTHING TO EXECUTE? - CP ' ' - JP NZ,UNKWN1 - LD A,(CHGDRV) ; NOPE, ONLY A DRIVE CHANGE? - OR A - JP Z,GETBACK1 ; NEITHER??? - DEC A - LD (CDRIVE),A ; OK, STORE NEW DRIVE. - CALL MOVECD ; SET (TDRIVE) ALSO. - CALL DSKSEL ; AND SELECT THIS DRIVE. - JP GETBACK1 ; THEN RETURN. -; -; HERE A FILE NAME WAS TYPED. PREPARE TO EXECUTE IT. -; -UNKWN1: LD DE,FCB+9 ; AN EXTENSION SPECIFIED? - LD A,(DE) - CP ' ' - JP NZ,SYNERR ; YES, NOT ALLOWED. -UNKWN2: PUSH DE - CALL DSELECT ; SELECT SPECIFIED DRIVE. - POP DE - LD HL,COMFILE ; SET THE EXTENSION TO 'COM'. LD HL,COMFILE - CALL MOVE3 ; MOVE 3 BYTES FROM (HL) TO (DE) TO ADD .COM - CALL OPENFCB ; AND OPEN THIS FILE. - .IF CHKU0B - JP NZ,UNKWNA ; GOT IT - LD E,0 ; TRY USER 0, THIS DRIVE - CALL GETSETUC ; OK, SET USER CODE. - CALL OPENFCB - JP NZ,UNKWNA ; GOT IT - LD HL,FCB ; SEE IF ON DRIVE B, USER 0 - LD (HL),2 - CALL OPENFCB - .ENDIF - JP Z,UNKWN9 ; NOPE -; -; LOAD IN THE PROGRAM. -; -UNKWNA: LD HL,TBASE ; STORE THE PROGRAM STARTING HERE. -UNKWN3: PUSH HL - EX DE,HL - CALL DMASET ; SET TRANSFER ADDRESS. - LD DE,FCB ; AND READ THE NEXT RECORD. - CALL RDREC - JP NZ,UNKWN4 ; END OF FILE OR READ ERROR? - POP HL ; NOPE, BUMP POINTER FOR NEXT SECTOR. - LD DE,128 - ADD HL,DE - LD DE,CBASE ; ENOUGH ROOM FOR THE WHOLE FILE? - LD A,L - SUB E - LD A,H - SBC A,D - JP NC,UNKWN0 ; NO, IT CAN'T FIT. - JP UNKWN3 -; -; GET HERE AFTER FINISHED READING. -; -UNKWN4: POP HL - DEC A ; NORMAL END OF FILE? - JP NZ,UNKWN0 - CALL RESETDR ; YES, RESET PREVIOUS DRIVE. - CALL CONVFST ; CONVERT THE FIRST FILE NAME THAT FOLLOWS - LD HL,CHGDRV ; COMMAND NAME. - PUSH HL - LD A,(HL) ; SET DRIVE CODE IN DEFAULT FCB. - LD (FCB),A - LD A,16 ; PUT SECOND NAME 16 BYTES LATER. - CALL CONVERT ; CONVERT SECOND FILE NAME. - POP HL - LD A,(HL) ; AND SET THE DRIVE FOR THIS SECOND FILE. - LD (FCB+16),A - XOR A ; CLEAR RECORD BYTE IN FCB. - LD (FCB+32),A - LD DE,TFCB ; MOVE IT INTO PLACE AT(005CH). - LD HL,FCB - LD B,33 - CALL HL2DE - LD HL,INBUFF+2 ; NOW MOVE THE REMAINDER OF THE INPUT -UNKWN5: LD A,(HL) ; LINE DOWN TO (0080H). LOOK FOR A NON BLANK. - OR A ; OR A NULL. - JP Z,UNKWN6 - CP ' ' - JP Z,UNKWN6 - INC HL - JP UNKWN5 -; -; DO THE LINE MOVE NOW. IT ENDS IN A NULL BYTE. -; -UNKWN6: LD B,0 ; KEEP A CHARACTER COUNT. - LD DE,TBUFF+1 ; DATA GETS PUT HERE. -UNKWN7: LD A,(HL) ; MOVE IT NOW. - LD (DE),A - OR A - JP Z,UNKWN8 - INC B - INC HL - INC DE - JP UNKWN7 -UNKWN8: LD A,B ; NOW STORE THE CHARACTER COUNT. - LD (TBUFF),A - CALL CRLF ; CLEAN UP THE SCREEN. - CALL STDDMA ; SET STANDARD TRANSFER ADDRESS. - CALL SETCDRV ; RESET CURRENT DRIVE. - CALL TBASE ; AND EXECUTE THE PROGRAM. -; -; TRANSIANT PROGRAMS RETURN HERE (OR REBOOT). -; - LD SP,BATCH ; SET STACK FIRST OFF. - CALL MOVECD ; MOVE CURRENT DRIVE INTO PLACE (TDRIVE). - CALL DSKSEL ; AND RESELECT IT. - JP CMMND1 ; BACK TO COMAND MODE. -; -; GET HERE IF SOME ERROR OCCURED. -; -UNKWN9: CALL RESETDR ; INPROPER FORMAT. - JP SYNERR -UNKWN0: LD BC,BADLOAD ; READ ERROR OR WON'T FIT. - CALL PLINE - JP GETBACK -BADLOAD:.DB "Bad Load",0 -COMFILE:.DB "COM" ; COMMAND FILE EXTENSION. -; -; GET HERE TO RETURN TO COMMAND LEVEL. WE WILL RESET THE -; PREVIOUS ACTIVE DRIVE AND THEN EITHER RETURN TO COMMAND -; LEVEL DIRECTLY OR PRINT ERROR MESSAGE AND THEN RETURN. -; -GETBACK:CALL RESETDR ; RESET PREVIOUS DRIVE. -GETBACK1: - CALL CONVFST ; CONVERT FIRST NAME IN (FCB). - LD A,(FCB+1) ; IF THIS WAS JUST A DRIVE CHANGE REQUEST, - SUB ' ' ; MAKE SURE IT WAS VALID. - LD HL,CHGDRV - OR (HL) - JP NZ,SYNERR - JP CMMND1 ; OK, RETURN TO COMMAND LEVEL. -; -; CCP STACK AREA. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -CCPSTACK: .EQU $ ;END OF CCP STACK AREA. - -; -; BATCH (OR SUBMIT) PROCESSING INFORMATION STORAGE. -; -BATCH: .DB 0 ; BATCH MODE FLAG (0=NOT ACTIVE). -BATCHFCB:.DB 0,"$$$ SUB" - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; FILE CONTROL BLOCK SETUP BY THE CCP. -; -FCB: .DB 0," ",0,0,0,0,0 - .DB " ",0,0,0,0,0 -RTNCODE:.DB 0 ; STATUS RETURNED FROM BDOS CALL. -CDRIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -CHGDRV: .DB 0 ; CHANGE IN DRIVES FLAG (0=NO CHANGE). -NBYTES: .DW 0 ; BYTE COUNTER USED BY TYPE. - - .IF ENDFIL - .FILL ((CCPO + 0800H) - $),055H - .ENDIF - - .END diff --git a/branches/s100/Source/cnfgdata.inc b/branches/s100/Source/cnfgdata.inc deleted file mode 100644 index c6657b92..00000000 --- a/branches/s100/Source/cnfgdata.inc +++ /dev/null @@ -1,202 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; cnfgdata.inc 6/02/2012 dwg - for 2.0 B8 ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 6/04/2012 dwg - add BOOTLU per Wayne email ; -; 6/02/2012 dwg - change BOOTDISK to DEVUNIT ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; 5/10/2012 dwg - cleanup for 2.0 architecture ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; cnfgdata.inc 3/14/2012 dwg - for 2.0 X5 ; -; 3/14/2012 dwg - retire LDRCON & DBGCON ; -; cnfgdata.inc 3/04/2012 dwg - for 2.0.0.0 ; -; 3/04/2012 dwg - added ptrs VAR_LOC & TST_LOC ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - .DB RMJ,RMN,RUP,RTP ; config data version - -; Loader data -; -; This area is for notes left by the loader from when the ccp/bdos/bios were -; placed in memory and kicked off, this allows logging onto the boot drive on startup -; -DISKBOOT .DB FALSE ; FALSE if ROM BOOT, otherwise TRUE -BOOTDEVICE .DB 0 ; if not ROM boot, has DEV/UNIT of boot device -BOOTLU .DW 0 ; logical unit on dev/unit for boot - .DB 0,0,0, 0,0,0 ; system startup time to be filled in by loader (from rtc) - -;================================================================================================== -; CONFIGURATION -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; - -;CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS - .DB CPUFREQ - -;PLATFORM .EQU PLT_ZETA ; PLT_N8VEM, PLT_ZETA - .DB PLATFORM - -;DIOPLT .EQU DIOPLT_ZETA ; DIOPLT_NONE, DIOPLT_DISKIO, DIOPLT_ZETA, DIOPLT_DIDE, DIOPLT_N8, DIOPLT_DISKIO3 - .DB DIOPLT - -;VDUMODE .EQU VDUPLT_NONE ; VDUPLT_NONE, VDUPLT_VDUV1, VDUPLT_PROPIO, VDUPLT_N8, VDUPLT_V2 (ONLY V1 IMPLEMENTED!) - .DB VDUMODE - -;ROMSIZE .EQU 512 ; SIZE OF ROM IN KB, MUST MATCH YOUR HARDWARE!!! - .DW ROMSIZE - -;RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! - .DW RAMSIZE - -;CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) - .DB CLRRAMDISK - - -;DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) - .DB DSKYENABLE - -;UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) - .DB UARTENABLE - -;VDUENABLE .EQU FALSE ; TRUE FOR VDU SERVICES (YOU MUST HAVE THE HARDWARE!) - .DB VDUENABLE - - -;FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT - .DB FDENABLE - -;FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) - .DB FDTRACE - -;FDMEDIA .EQU FDM720 ; FDM720 OR FDM144 (ONLY RELEVANT IF FDENABLE = TRUE) - .DB FDMEDIA - -;FDMEDIAALT .EQU FDM144 ; ALTERNATIVE MEDIA TO TRY - .DB FDMEDIAALT - -;FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY - .DB FDMAUTO - - -;IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT - .DB IDEENABLE - -;IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) - .DB IDETRACE - -;IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) - .DB IDE8BIT - -;IDECAPACITY .EQU 64 ; SIZE OF DEVICE IN MEGABYTES - .DW IDECAPACITY - -;PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) - .DB PPIDEENABLE - -;PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) - .DB PPIDETRACE - -;PPIDE8BIT .EQU TRUE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) - .DB PPIDE8BIT - -;PPIDECAPACITY .EQU 64 - .DW PPIDECAPACITY ; SIZE OF DEVICE IN MEGABYTES - -; PPIDESLOW .EQU FALSE - .DB PPIDESLOW ; Add NOPs to PPIDE driver for recovery time - -;BOOTTYPE: .EQU BT_JP2 ; BT_UART, BT_DSKY, BT_JP2 - .DB BOOTTYPE - -;BOOT_TIMEOUT .EQU 10 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE - .DB BOOT_TIMEOUT - -;BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT - .DB BOOT_DEFAULT - -;BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 - .DW BAUDRATE - -#IF (PLATFORM == PLT_N8) -;Z180_CLKDIV .EQU 1 ; 0=XTAL/2, 1=XTAL/1 - .DB Z180_CLKDIV - -;Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3) - .DB Z180_MEMWAIT - -;Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3) - .DB Z180_IOWAIT - -;Z180_CNTLB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT - .DB Z180_CNTLB0 - -;Z180_CNTLB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT - .DB Z180_CNTLB1 - - .DB SDENABLE ; SD support boolean - .DB SDTRACE ; SD trace type - -;SDCAPACITY .EQU 64 ; DEVICE SIZE IN MEGABYTES - .DW SDCAPACITY - - .DB SDCSIO ; USE CSI/O PORT (boolean) - .DB SDCSIOFAST ; USE FAST CSI/O ALGORITHM (boolean) -#ELSE - .DB 0E5h ; placeholder for Z180_CLKDIV - .DB 0E5h ; placeholder for Z180_MEMWAIT - .DB 0E5h ; placeholder for Z180_IOWAIT - .DB 0E5h ; placeholder for Z180_CNTLB0 - .DB 0E5h ; placeholder for Z180_CNTLB1 - .DB 0e5h ; placeholder for SDENABLE - .DB 0e5h ; placeholder for SDTARCE - .DW 0e5e5h ; placeholder for SDCAPACITY - .DB 0e5h ; placeholder for SDCSIO - .DB 0e5h ; placeholder for SDCSIOFAST -#ENDIF - -; DEFIOBYTE .EQU $00 ; INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE); - .DB DEFIOBYTE - -; TERMTYPE .EQU TERM_TTY - .DB TERMTYPE - -; REVISION .EQU 500 ; approximate svn revision of source tree - .DW REVISION - -#IF (PRPSDENABLE) - .DB PRPSDENABLE - .DB PRPSDTRACE - .DW PRPSDCAPACITY - .DB PRPCONENABLE -#ELSE - .DB 0E5h ; placeholder for PRPSDENABLE - .DB 0E5h ; placeholder for PRPSDTARCE - .DW 0E5E5h ; placeholder for PRPSDCAPACITY - .DB 0E5h ; placeholder for PRPCONENABLE -#ENDIF - -; DATASIZE .EQU 0700h ; - .DW BIOSSIZE - -;PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT - .DB PPPENABLE - -;PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) - .DB PPPSDENABLE - -;PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) - .DB PPPSDTRACE - -;PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) - .DW PPPSDCAPACITY - -;PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) - .DB PPPCONENABLE - -; PRPENABLE .EQU FALSE - .DB PRPENABLE - -;;;;;;;;;;;;;;;;;;;;;; -; eof - cnfgdata.inc ; -;;;;;;;;;;;;;;;;;;;;;; diff --git a/branches/s100/Source/config_n8_2312.asm b/branches/s100/Source/config_n8_2312.asm deleted file mode 100644 index 13104efd..00000000 --- a/branches/s100/Source/config_n8_2312.asm +++ /dev/null @@ -1,100 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 20 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_N8V ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU TRUE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_N8 ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU TRUE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU TRUE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU TRUE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 -; -Z180_CLKDIV .EQU 1 ; 0=XTAL/2, 1=XTAL/1 -Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3) -Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3) -Z180_CNTLB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT -Z180_CNTLB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT diff --git a/branches/s100/Source/config_n8_2511.asm b/branches/s100/Source/config_n8_2511.asm deleted file mode 100644 index 44f2a34a..00000000 --- a/branches/s100/Source/config_n8_2511.asm +++ /dev/null @@ -1,100 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 20 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_N8V ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU TRUE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_N8 ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU TRUE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU TRUE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 -; -Z180_CLKDIV .EQU 1 ; 0=XTAL/2, 1=XTAL/1 -Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3) -Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3) -Z180_CNTLB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT -Z180_CNTLB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT diff --git a/branches/s100/Source/config_n8vem_cvdu.asm b/branches/s100/Source/config_n8vem_cvdu.asm deleted file mode 100644 index 99a99b86..00000000 --- a/branches/s100/Source/config_n8vem_cvdu.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC W/ VDU 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_CVDU ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_ANSI ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU TRUE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU TRUE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_dide.asm b/branches/s100/Source/config_n8vem_dide.asm deleted file mode 100644 index 0eb33d08..00000000 --- a/branches/s100/Source/config_n8vem_dide.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIDE ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU TRUE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIDE ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_diskio.asm b/branches/s100/Source/config_n8vem_diskio.asm deleted file mode 100644 index 2c3fc748..00000000 --- a/branches/s100/Source/config_n8vem_diskio.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU TRUE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_diskio3.asm b/branches/s100/Source/config_n8vem_diskio3.asm deleted file mode 100644 index ae3014bc..00000000 --- a/branches/s100/Source/config_n8vem_diskio3.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC W/ DISKIO V3 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO3 ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_DIO3 ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_ppide.asm b/branches/s100/Source/config_n8vem_ppide.asm deleted file mode 100644 index f2ad1ccb..00000000 --- a/branches/s100/Source/config_n8vem_ppide.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC W/ PPIDE 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_ppisd.asm b/branches/s100/Source/config_n8vem_ppisd.asm deleted file mode 100644 index 180fa3b5..00000000 --- a/branches/s100/Source/config_n8vem_ppisd.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU TRUE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU TRUE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_propio.asm b/branches/s100/Source/config_n8vem_propio.asm deleted file mode 100644 index ce30d22f..00000000 --- a/branches/s100/Source/config_n8vem_propio.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_PRPCON ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU CIODEV_UART ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $01 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU $00 ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_simh.asm b/branches/s100/Source/config_n8vem_simh.asm deleted file mode 100644 index 57ec9929..00000000 --- a/branches/s100/Source/config_n8vem_simh.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR SIMH EMULATOR 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_ALWAYS ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU FALSE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU TRUE ; TRUE FOR HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_std.asm b/branches/s100/Source/config_n8vem_std.asm deleted file mode 100644 index 609a9cf3..00000000 --- a/branches/s100/Source/config_n8vem_std.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_n8vem_vdu.asm b/branches/s100/Source/config_n8vem_vdu.asm deleted file mode 100644 index 77a1b9d1..00000000 --- a/branches/s100/Source/config_n8vem_vdu.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8VEM SBC W/ VDU 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 8 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_VDU ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_ANSI ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU TRUE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_DIO ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_DIO3 ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU TRUE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_s100_std.asm b/branches/s100/Source/config_s100_std.asm deleted file mode 100644 index 7428e1de..00000000 --- a/branches/s100/Source/config_s100_std.asm +++ /dev/null @@ -1,111 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR N8 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 20 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; - -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_N8V ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_7220, V\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; - -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! - -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU TRUE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU FALSE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_N8 ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -;; -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU TRUE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU TRUE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU TRUE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU TRUE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; - -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 - -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 -; -; Z180_CLKDIV .EQU 1 ; 0=XTAL/2, 1=XTAL/1 -;; Z180_MEMWAIT .EQU 0 ; MEMORY WAIT STATES TO INSERT (0-3) -;; Z180_IOWAIT .EQU 3 ; IO WAIT STATES TO INSERT (0-3) -;; Z180_CNTLB0 .EQU 20H ; SERIAL PORT 0 DIV, SEE Z180 CLOCKING DOCUMENT -;; Z180_CNTLB1 .EQU 20H ; SERIAL PORT 1 DIV, SEE Z180 CLOCKING DOCUMENT - -;;;;;;;;;;;;;;;;;;;;;;;; -; EOF - CONFG_S100.ASM ; -;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/branches/s100/Source/config_zeta_ppp.asm b/branches/s100/Source/config_zeta_ppp.asm deleted file mode 100644 index 0660067c..00000000 --- a/branches/s100/Source/config_zeta_ppp.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR ZETA W/ PPP 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 20 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_PPPCON ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU CIODEV_UART ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $01 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU $00 ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_ZETA ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU FALSE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU FALSE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU TRUE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/config_zeta_std.asm b/branches/s100/Source/config_zeta_std.asm deleted file mode 100644 index 6c051e5f..00000000 --- a/branches/s100/Source/config_zeta_std.asm +++ /dev/null @@ -1,94 +0,0 @@ -; -;================================================================================================== -; ROMWBW 2.X CONFIGURATION FOR ZETA 5/8/2012 -;================================================================================================== -; -; BUILD CONFIGURATION OPTIONS -; -CPUFREQ .EQU 20 ; IN MHZ, USED TO COMPUTE DELAY FACTORS -; -DEFCON .EQU CIODEV_UART ; DEFAULT CONSOLE DEVICE (LOADER AND MONITOR): CIODEV_UART, CIODEV_VDU, DIODEV_PRPCON -ALTCON .EQU DEFCON ; ALT CONSOLE DEVICE (USED WHEN CONFIG JUMPER SHORTED) -DEFVDA .EQU VDADEV_NONE ; DEFAULT VDA (VDADEV_NONE, VDADEV_VDU, VDADEV_CVDU, VDADEV_UPD7220, VDADEV_N8V) -DEFEMU .EQU EMUTYP_TTY ; DEFAULT EMULATION TYPE (EMUTYP_TTY, EMUTYP_ANSI, ...) -; -RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! -CLRRAMDISK .EQU CLR_AUTO ; CLR_ALWAYS, CLR_NEVER, CLR_AUTO (CLEAR IF INVALID DIR AREA) -; -DSKMAP .EQU DM_RAM ; DM_ROM, DM_RAM, DM_FD, DM_IDE, DM_PPIDE, DM_SD, DM_PRPSD, DM_PPPSD -; -DSKYENABLE .EQU FALSE ; TRUE FOR DSKY SUPPORT (DO NOT COMBINE WITH PPIDE) -; -UARTENABLE .EQU TRUE ; TRUE FOR UART SUPPORT (ALMOST ALWAYS WANT THIS TO BE TRUE) -UARTFIFO .EQU TRUE ; TRUE ENABLES UART FIFO (16550 ASSUMED, N8VEM AND ZETA ONLY) -UARTAFC .EQU FALSE ; TRUE ENABLES AUTO FLOW CONTROL (YOUR TERMINAL/UART MUST SUPPORT RTS/CTS FLOW CONTROL!!!) -; -VDUENABLE .EQU FALSE ; TRUE FOR VDU BOARD SUPPORT -CVDUENABLE .EQU FALSE ; TRUE FOR CVDU BOARD SUPPORT -UPD7220ENABLE .EQU FALSE ; TRUE FOR uPD7220 BOARD SUPPORT -N8VENABLE .EQU FALSE ; TRUE FOR N8 (TMS9918) VIDEO/KBD SUPPORT -; -DEFIOBYTE .EQU $00 ; DEFAULT INITIAL VALUE FOR CP/M IOBYTE, $00=TTY, $01=CRT (MUST HAVE CRT HARDWARE) -ALTIOBYTE .EQU DEFIOBYTE ; ALT INITIAL VALUE (USED WHEN CONFIG JUMPER SHORTED) -WRTCACHE .EQU TRUE ; ENABLE WRITE CACHING IN CBIOS (DE)BLOCKING ALGORITHM -DSKTRACE .EQU FALSE ; ENABLE TRACING OF CBIOS DISK FUNCTION CALLS -; -FDENABLE .EQU TRUE ; TRUE FOR FLOPPY SUPPORT -FDMODE .EQU FDMODE_ZETA ; FDMODE_DIO, FDMODE_ZETA, FDMODE_DIDE, FDMODE_N8, FDMODE_DIO3 -FDTRACE .EQU 1 ; 0=SILENT, 1=FATAL ERRORS, 2=ALL ERRORS, 3=EVERYTHING (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIA .EQU FDM144 ; FDM720, FDM144, FDM360, FDM120 (ONLY RELEVANT IF FDENABLE = TRUE) -FDMEDIAALT .EQU FDM720 ; ALTERNATE MEDIA TO TRY, SAME CHOICES AS ABOVE (ONLY RELEVANT IF FDMAUTO = TRUE) -FDMAUTO .EQU TRUE ; SELECT BETWEEN MEDIA OPTS ABOVE AUTOMATICALLY -; -IDEENABLE .EQU FALSE ; TRUE FOR IDE SUPPORT -IDEMODE .EQU IDEMODE_DIO ; IDEMODE_DIO, IDEMODE_DIDE -IDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -IDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -IDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPIDEENABLE .EQU TRUE ; TRUE FOR PPIDE SUPPORT (DO NOT COMBINE WITH DSKYENABLE) -PPIDEMODE .EQU PPIDEMODE_STD ; PPIDEMODE_STD, PPIDEMODE_DIO3 -PPIDETRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPIDEENABLE = TRUE) -PPIDE8BIT .EQU FALSE ; USE IDE 8BIT TRANSFERS (PROBABLY ONLY WORKS FOR CF CARDS!) -PPIDECAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PPIDESLOW .EQU FALSE ; ADD DELAYS TO HELP PROBLEMATIC HARDWARE (TRY THIS IF PPIDE IS UNRELIABLE) -; -SDENABLE .EQU FALSE ; TRUE FOR SD SUPPORT -SDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -SDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -SDCSIO .EQU FALSE ; TRUE IF USING THE CSIO PORT (N8 ONLY) -SDCSIOFAST .EQU FALSE ; TRUE IF USING THE LOOKUP TABLE RATHER THAN SHIFTS AND ROTATES (N8 ONLY) -PPISD .EQU TRUE ; TRUE IF USING PPISD MINI-BOARD (DO NOT COMBINE WITH PPIDE) -S2ISD .EQU FALSE ; TRUE IF USING SCSI2IDE BOARD (DO NOT COMBINE WITH PPISD) -; -PRPENABLE .EQU FALSE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PRPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PRPSDENABLE = TRUE) -PRPSDCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -PRPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -PPPENABLE .EQU FALSE ; TRUE FOR PARPORTPROP SUPPORT -PPPSDENABLE .EQU TRUE ; TRUE FOR PROPIO SD SUPPORT (FOR N8VEM PROPIO ONLY!) -PPPSDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPPENABLE = TRUE) -PPPSDCAPACITY .EQU 64 ; CAPACITY OF PPP SD DEVICE (IN MB) -PPPCONENABLE .EQU TRUE ; TRUE FOR PROPIO CONSOLE SUPPORT (PS/2 KBD & VGA VIDEO) -; -HDSKENABLE .EQU FALSE ; TRUE FOR SIMH HDSK SUPPORT -HDSKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF IDEENABLE = TRUE) -HDSKCAPACITY .EQU 64 ; CAPACITY OF DEVICE (IN MB) -; -PPKENABLE .EQU FALSE ; TRUE FOR PARALLEL PORT KEYBOARD -PPKTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF PPKENABLE = TRUE) -KBDENABLE .EQU FALSE ; TRUE FOR PS/2 KEYBOARD ON I8242 -KBDTRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF KBDENABLE = TRUE) -; -TTYENABLE .EQU FALSE ; INCLUDE TTY EMULATION SUPPORT -ANSIENABLE .EQU FALSE ; INCLUDE ANSI EMULATION SUPPORT -ANSITRACE .EQU 1 ; 0=SILENT, 1=ERRORS, 2=EVERYTHING (ONLY RELEVANT IF ANSIENABLE = TRUE) -; -BOOTTYPE .EQU BT_MENU ; BT_MENU (WAIT FOR KEYPRESS), BT_AUTO (BOOT_DEFAULT AFTER BOOT_TIMEOUT SECS) -BOOT_TIMEOUT .EQU 20 ; APPROX TIMEOUT IN SECONDS FOR AUTOBOOT, 0 FOR IMMEDIATE -BOOT_DEFAULT .EQU 'R' ; SELECTION TO INVOKE AT TIMEOUT -; -BAUDRATE .EQU 38400 ; IN BPS: 1200, 9600, 38400, ..., 115200 -TERMTYPE .EQU TERM_ANSI ; TERM_TTY=0, TERM_ANSI=1, TERM_WYSE=2 diff --git a/branches/s100/Source/cvdu.asm b/branches/s100/Source/cvdu.asm deleted file mode 100644 index 6a24057a..00000000 --- a/branches/s100/Source/cvdu.asm +++ /dev/null @@ -1,712 +0,0 @@ -;====================================================================== -; COLOR VDU DRIVER FOR N8VEM PROJECT -; -; WRITTEN BY: DAN WERNER -- 11/4/2011 -; ROMWBW ADAPTATION BY: WAYNE WARTHEN -- 11/9/2012 -;====================================================================== -; -; TODO: -; - IMPLEMENT CONSTANTS FOR SCREEN DIMENSIONS -; - IMPLEMENT SET CURSOR STYLE (VDASCS) FUNCTION -; - IMPLEMENT ALTERNATE DISPLAY MODES? -; - IMPLEMENT DYNAMIC READ/WRITE OF CHARACTER BITMAP DATA? -; -;====================================================================== -; CVDU DRIVER - CONSTANTS -;====================================================================== -; -CVDU_STAT .EQU $E4 ; READ M8563 STATUS -CVDU_REG .EQU $E4 ; SELECT M8563 REGISTER -CVDU_DATA .EQU $EC ; READ/WRITE M8563 DATA -; -CVDU_ROWS .EQU 25 -CVDU_COLS .EQU 80 -; -;====================================================================== -; CVDU DRIVER - INITIALIZATION -;====================================================================== -; -CVDU_INIT: - PRTS("CVDU: IO=0x$") - LD A,CVDU_STAT - CALL PRTHEXBYTE -; - CALL CVDU_CRTINIT ; SETUP THE CVDU CHIP REGISTERS - CALL CVDU_LOADFONT ; LOAD FONT DATA FROM ROM TO CVDU STRORAGE - -CVDU_RESET: - LD A,$0E ; ATTRIBUTE IS STANDARD WHITE ON BLACK - LD (CVDU_ATTR),A ; SAVE IT - - LD DE,0 ; ROW = 0, COL = 0 - CALL CVDU_XY ; SEND CURSOR TO TOP LEFT - LD A,' ' ; BLANK THE SCREEN - LD DE,$800 ; FILL ENTIRE BUFFER - CALL CVDU_FILL ; DO IT - LD DE,0 ; ROW = 0, COL = 0 - CALL CVDU_XY ; SEND CURSOR TO TOP LEFT - - XOR A ; SIGNAL SUCCESS - RET -; -;====================================================================== -; CVDU DRIVER - CHARACTER I/O (CIO) DISPATCHER AND FUNCTIONS -;====================================================================== -; -CVDU_DISPCIO: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,CVDU_CIOIN ; $00 - DEC A - JR Z,CVDU_CIOOUT ; $01 - DEC A - JR Z,CVDU_CIOIST ; $02 - DEC A - JR Z,CVDU_CIOOST ; $03 - CALL PANIC -; -CVDU_CIOIN: - JP KBD_READ ; CHAIN TO KEYBOARD DRIVER -; -CVDU_CIOIST: - JP KBD_STAT ; CHAIN TO KEYBOARD DRIVER -; -CVDU_CIOOUT: - JP CVDU_VDAWRC ; WRITE CHARACTER -; -CVDU_CIOOST: - XOR A ; A = 0 - INC A ; A = 1, SIGNAL OUTPUT BUFFER READY - RET -; -;====================================================================== -; CVDU DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS -;====================================================================== -; -CVDU_DISPVDA: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JR Z,CVDU_VDAINI ; $40 - DEC A - JR Z,CVDU_VDAQRY ; $41 - DEC A - JR Z,CVDU_VDARES ; $42 - DEC A - JR Z,CVDU_VDASCS ; $43 - DEC A - JR Z,CVDU_VDASCP ; $44 - DEC A - JR Z,CVDU_VDASAT ; $45 - DEC A - JR Z,CVDU_VDASCO ; $46 - DEC A - JR Z,CVDU_VDAWRC ; $47 - DEC A - JR Z,CVDU_VDAFIL ; $48 - DEC A - JR Z,CVDU_VDACPY ; $49 - DEC A - JR Z,CVDU_VDASCR ; $4A - DEC A - JP Z,KBD_STAT ; $4B - DEC A - JP Z,KBD_FLUSH ; $4C - DEC A - JP Z,KBD_READ ; $4D - CALL PANIC - -CVDU_VDAINI: - JP CVDU_INIT ; INITIALIZE - -CVDU_VDAQRY: - LD C,$00 ; MODE ZERO IS ALL WE KNOW - LD D,CVDU_ROWS ; ROWS - LD E,CVDU_COLS ; COLS - LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED YET - XOR A ; SIGNAL SUCCESS - RET - -CVDU_VDARES: - JR CVDU_RESET ; DO THE RESET - -CVDU_VDASCS: - CALL PANIC ; NOT IMPLEMENTED (YET) - -CVDU_VDASCP: - CALL CVDU_XY ; SET CURSOR POSITION - XOR A ; SIGNAL SUCCESS - RET - -CVDU_VDASAT: - ; INCOMING IS: -----RUB (R=REVERSE, U=UNDERLINE, B=BLINK) - ; TRANSFORM TO: -RUB---- - LD A,E ; GET THE INCOMING ATTRIBUTE - RLCA ; TRANSLATE TO OUR DESIRED BIT - RLCA ; " - RLCA ; " - RLCA ; " - AND %01110000 ; REMOVE ANYTHING EXTRANEOUS - LD E,A ; SAVE IT IN E - LD A,(CVDU_ATTR) ; GET CURRENT ATTRIBUTE SETTING - AND %10001111 ; CLEAR OUT OLD ATTRIBUTE BITS - OR E ; STUFF IN THE NEW ONES - LD (CVDU_ATTR),A ; AND SAVE THE RESULT - XOR A ; SIGNAL SUCCESS - RET - -CVDU_VDASCO: - ; INCOMING IS: IBGRIBGR (I=INTENSITY, B=BLUE, G=GREEN, R=RED) - ; TRANSFORM TO: ----RGBI (DISCARD BACKGROUND COLOR IN HIGH NIBBLE) - XOR A ; CLEAR A - LD B,4 ; LOOP 4 TIMES (4 BITS) -CVDU_VDASCO1: - RRC E ; ROTATE LOW ORDER BIT OUT OF E INTO CF - RLA ; ROTATE CF INTO LOW ORDER BIT OF A - DJNZ CVDU_VDASCO1 ; DO FOUR BITS OF THIS - LD E,A ; SAVE RESULT IN E - LD A,(CVDU_ATTR) ; GET CURRENT VALUE INTO A - AND %11110000 ; CLEAR OUT OLD COLOR BITS - OR E ; STUFF IN THE NEW ONES - LD (CVDU_ATTR),A ; AND SAVE THE RESULT - XOR A ; SIGNAL SUCCESS - RET - -CVDU_VDAWRC: - LD A,E ; CHARACTER TO WRITE GOES IN A - CALL CVDU_PUTCHAR ; PUT IT ON THE SCREEN - XOR A ; SIGNAL SUCCESS - RET - -CVDU_VDAFIL: - LD A,E ; FILL CHARACTER GOES IN A - EX DE,HL ; FILL LENGTH GOES IN DE - CALL CVDU_FILL ; DO THE FILL - XOR A ; SIGNAL SUCCESS - RET - -CVDU_VDACPY: - ; LENGTH IN HL, SOURCE ROW/COL IN DE, DEST IS CVDU_POS - ; BLKCPY USES: HL=SOURCE, DE=DEST, BC=COUNT - PUSH HL ; SAVE LENGTH - CALL CVDU_XY2IDX ; ROW/COL IN DE -> SOURCE ADR IN HL - POP BC ; RECOVER LENGTH IN BC - LD DE,(CVDU_POS) ; PUT DEST IN DE - JP CVDU_BLKCPY ; DO A BLOCK COPY - -CVDU_VDASCR: - LD A,E ; LOAD E INTO A - OR A ; SET FLAGS - RET Z ; IF ZERO, WE ARE DONE - PUSH DE ; SAVE E - JP M,CVDU_VDASCR1 ; E IS NEGATIVE, REVERSE SCROLL - CALL CVDU_SCROLL ; SCROLL FORWARD ONE LINE - POP DE ; RECOVER E - DEC E ; DECREMENT IT - JR CVDU_VDASCR ; LOOP -CVDU_VDASCR1: - CALL CVDU_RSCROLL ; SCROLL REVERSE ONE LINE - POP DE ; RECOVER E - INC E ; INCREMENT IT - JR CVDU_VDASCR ; LOOP -; -;====================================================================== -; CVDU DRIVER - PRIVATE DRIVER FUNCTIONS -;====================================================================== -; -;---------------------------------------------------------------------- -; UPDATE M8563 REGISTERS -; CVDU_WR WRITES VALUE IN A TO VDU REGISTER SPECIFIED IN C -; CVDU_WRX WRITES VALUE IN DE TO VDU REGISTER PAIR IN C, C+1 -;---------------------------------------------------------------------- -; -CVDU_WR: - PUSH AF ; SAVE VALUE TO WRITE - LD A,C ; SET A TO CVDU REGISTER TO SELECT - OUT (CVDU_REG),A ; WRITE IT TO SELECT THE REGISTER -CVDU_WR1: - IN A,(CVDU_STAT) ; GET CVDU STATUS - BIT 7,A ; CHECK BIT 7 - JR Z,CVDU_WR1 ; LOOP WHILE NOT READY (BIT 7 NOT SET) - POP AF ; RESTORE VALUE TO WRITE - OUT (CVDU_DATA),A ; WRITE IT - RET -; -CVDU_WRX: - LD A,H ; SETUP MSB TO WRITE - CALL CVDU_WR ; DO IT - INC C ; NEXT CVDU REGISTER - LD A,L ; SETUP LSB TO WRITE - JR CVDU_WR ; DO IT & RETURN -; -;---------------------------------------------------------------------- -; READ M8563 REGISTERS -; CVDU_RD READS VDU REGISTER SPECIFIED IN C AND RETURNS VALUE IN A -; CVDU_RDX READS VDU REGISTER PAIR SPECIFIED BY C, C+1 -; AND RETURNS VALUE IN HL -;---------------------------------------------------------------------- -; -CVDU_RD: - LD A,C ; SET A TO CVDU REGISTER TO SELECT - OUT (CVDU_REG),A ; WRITE IT TO SELECT THE REGISTER -CVDU_RD1: - IN A,(CVDU_STAT) ; GET CVDU STATUS - BIT 7,A ; CHECK BIT 7 - JR Z,CVDU_RD1 ; LOOP WHILE NOT READY (BIT 7 NOT SET) - IN A,(CVDU_DATA) ; READ IT - RET -; -CVDU_RDX: - CALL CVDU_RD ; GET VALUE FROM REGISTER IN C - LD H,A ; SAVE IN H - INC C ; BUMP TO NEXT REGISTER OF PAIR - CALL CVDU_RD ; READ THE VALUE - LD L,A ; SAVE IT IN L - RET -; -;---------------------------------------------------------------------- -; MOS 8563 DISPLAY CONTROLLER CHIP INITIALIZATION -;---------------------------------------------------------------------- -; -CVDU_CRTINIT: - LD C,0 ; START WITH REGISTER 0 - LD B,37 ; INIT 37 REGISTERS - LD HL,CVDU_INIT8563 ; HL = POINTER TO THE DEFAULT VALUES -CVDU_CRTINIT1: - LD A,(HL) ; GET VALUE - CALL CVDU_WR ; WRITE IT - INC HL ; POINT TO NEXT VALUE - INC C ; POINT TO NEXT REGISTER - DJNZ CVDU_CRTINIT1 ; LOOP - RET -; -;---------------------------------------------------------------------- -; LOAD FONT DATA -;---------------------------------------------------------------------- -; -CVDU_LOADFONT: - LD HL,$2000 ; START OF FONT BUFFER - LD C,18 ; UPDATE ADDRESS REGISTER PAIR - CALL CVDU_WRX ; DO IT - - LD HL,CVDU_FONTDATA ; POINTER TO FONT DATA - LD DE,$2000 ; LENGTH OF FONT DATA - LD C,31 ; DATA REGISTER -CVDU_LOADFONT1: - LD A,(HL) ; LOAD NEXT BYTE OF FONT DATA - CALL CVDU_WR ; WRITE IT - INC HL ; INCREMENT FONT DATA POINTER - DEC DE ; DECREMENT LOOP COUNTER - LD A,D ; CHECK DE... - OR E ; FOR COUNTER EXHAUSTED - JR NZ,CVDU_LOADFONT1 ; LOOP TILL DONE - RET -; -;---------------------------------------------------------------------- -; SET CURSOR POSITION TO ROW IN D AND COLUMN IN E -;---------------------------------------------------------------------- -; -CVDU_XY: - CALL CVDU_XY2IDX ; CONVERT ROW/COL TO BUF IDX - LD (CVDU_POS),HL ; SAVE THE RESULT (DISPLAY POSITION) - LD C,14 ; CURSOR POSITION REGISTER PAIR - JP CVDU_WRX ; DO IT AND RETURN -; -;---------------------------------------------------------------------- -; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL -; D=ROW, E=COL -;---------------------------------------------------------------------- -; -CVDU_XY2IDX: - LD A,E ; SAVE COLUMN NUMBER IN A - LD H,D ; SET H TO ROW NUMBER - LD E,CVDU_COLS ; SET E TO ROW LENGTH - CALL MULT8 ; MULTIPLY TO GET ROW OFFSET - LD E,A ; GET COLUMN BACK - ADD HL,DE ; ADD IT IN - RET ; RETURN -; -;---------------------------------------------------------------------- -; WRITE VALUE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR -;---------------------------------------------------------------------- -; -CVDU_PUTCHAR: - PUSH AF ; SAVE CHARACTER - - ; SET MEMORY LOCATION FOR CHARACTER - LD HL,(CVDU_POS) ; LOAD CURRENT POSITION INTO HL - LD C,18 ; UPDATE ADDRESS REGISTER PAIR - CALL CVDU_WRX ; DO IT - - ; PUT THE CHARACTER THERE - POP AF ; RECOVER CHARACTER VALLUE TO WRITE - LD C,31 ; DATA REGISTER - CALL CVDU_WR ; DO IT - - ; BUMP THE CURSOR FORWARD - INC HL ; BUMP HL TO NEXT POSITION - LD (CVDU_POS),HL ; SAVE IT - LD C,14 ; CURSOR POSITION REGISTER PAIR - CALL CVDU_WRX ; DO IT - - ; SET MEMORY LOCATION FOR ATTRIBUTE - LD DE,$800 - 1 ; SETUP DE TO ADD OFFSET INTO ATTRIB BUFFER - ADD HL,DE ; HL NOW POINTS TO ATTRIB POS FOR CHAR JUST WRITTEN - LD C,18 ; UPDATE ADDRESS REGISTER PAIR - CALL CVDU_WRX ; DO IT - - ; PUT THE ATTRIBUTE THERE - LD A,(CVDU_ATTR) ; LOAD THE ATTRIBUTE VALUE - LD C,31 ; DATA REGISTER - JP CVDU_WR ; DO IT AND RETURN -; -;---------------------------------------------------------------------- -; FILL AREA IN BUFFER WITH SPECIFIED CHARACTER AND CURRENT COLOR/ATTRIBUTE -; STARTING AT THE CURRENT FRAME BUFFER POSITION -; A: FILL CHARACTER -; DE: NUMBER OF CHARACTERS TO FILL -;---------------------------------------------------------------------- -; -CVDU_FILL: - PUSH DE ; SAVE FILL COUNT - LD HL,(CVDU_POS) ; SET CHARACTER BUFFER POSITION TO FILL - PUSH HL ; SAVE BUF POS - CALL CVDU_FILL1 ; DO THE CHARACTER FILL - POP HL ; RECOVER BUF POS - LD DE,$800 ; INCREMENT FOR ATTRIBUTE FILL - ADD HL,DE ; HL := BUF POS FOR ATTRIBUTE FILL - POP DE ; RECOVER FILL COUNT - LD A,(CVDU_ATTR) ; SET ATTRIBUTE VALUE FOR ATTRIBUTE FILL - JR CVDU_FILL1 ; DO ATTRIBUTE FILL AND RETURN - -CVDU_FILL1: - LD B,A ; SAVE REQUESTED FILL VALUE - - ; CHECK FOR VALID FILL LENGTH - LD A,D ; LOAD D - OR E ; OR WITH E - RET Z ; BAIL OUT IF LENGTH OF ZERO SPECIFIED - - ; POINT TO BUFFER LOCATION TO START FILL - LD C,18 ; UPDATE ADDRESS REGISTER PAIR - CALL CVDU_WRX ; DO IT - - ; SET MODE TO BLOCK WRITE - LD C,24 ; BLOCK MODE CONTROL REGISTER - CALL CVDU_RD ; GET CURRENT VALUE - AND $7F ; CLEAR BIT 7 FOR FILL MODE - CALL CVDU_WR ; DO IT - - ; SET CHARACTER TO WRITE (WRITES ONE CHARACTER) - LD A,B ; RECOVER FILL VALUE - LD C,31 ; DATA REGISTER - CALL CVDU_WR ; DO IT - DEC DE ; REFLECT ONE CHARACTER WRITTEN - - ; LOOP TO DO BULK WRITE (UP TO 255 BYTES PER LOOP) - EX DE,HL ; NOW USE HL FOR COUNT - LD C,30 ; BYTE COUNT REGISTER -CVDU_FILL2: - LD A,H ; GET HIGH BYTE - OR A ; SET FLAGS - LD A,L ; PRESUME WE WILL WRITE L COUNT (ALL REMAINING) BYTES - JR Z,CVDU_FILL3 ; IF H WAS ZERO, WRITE L BYTES - LD A,$FF ; H WAS > 0, NEED MORE LOOPS, WRITE 255 BYTES -CVDU_FILL3: - CALL CVDU_WR ; DO IT (SOURCE/DEST REGS AUTO INCREMENT) - LD D,0 ; CLEAR D - LD E,A ; SET E TO BYTES WRITTEN - OR A ; CLEAR CARRY - SBC HL,DE ; SUBTRACT FROM HL - RET Z ; IF ZERO, WE ARE DONE - JR CVDU_FILL2 ; OTHERWISE, WRITE SOME MORE -; -;---------------------------------------------------------------------- -; SCROLL ENTIRE SCREEN FORWARD BY ONE LINE (CURSOR POSITION UNCHANGED) -;---------------------------------------------------------------------- -; -CVDU_SCROLL: - ; SCROLL THE CHARACTER BUFFER - LD A,' ' ; CHAR VALUE TO FILL NEW EXPOSED LINE - LD HL,0 ; SOURCE ADDRESS OF CHARACER BUFFER - CALL CVDU_SCROLL1 ; SCROLL CHARACTER BUFFER - - ; SCROLL THE ATTRIBUTE BUFFER - LD A,(CVDU_ATTR) ; ATTRIBUTE VALUE TO FILL NEW EXPOSED LINE - LD HL,$800 ; SOURCE ADDRESS OF ATTRIBUTE BUFFER - JR CVDU_SCROLL1 ; SCROLL ATTRIBUTE BUFFER - -CVDU_SCROLL1: - PUSH AF ; SAVE FILL VALUE FOR NOW - - ; SET MODE TO BLOCK COPY - LD C,24 ; BLOCK MODE CONTROL REGISTER - CALL CVDU_RD ; GET CURRENT VALUE - OR $80 ; SET BIT 7 FOR COPY MODE - CALL CVDU_WR ; DO IT - - ; SET INITIAL BLOCK COPY DESTINATION (USING HL PASSED IN) - LD C,18 ; UPDATE ADDRESS (DESTINATION) REGISTER - CALL CVDU_WRX ; DO IT - - ; COMPUTE SOURCE (INCREMENT ONE ROW) - LD DE,CVDU_COLS ; SOURCE ADDRESS IS ONE ROW PAST DESTINATION - ADD HL,DE ; ADD IT TO BUF ADDRESS - - ; SET INITIAL BLOCK COPY SOURCE - LD C,32 ; BLOCK START ADDRESS REGISTER - CALL CVDU_WRX ; DO IT - - LD B,CVDU_ROWS - 1 ; ITERATIONS (ROWS - 1) -CVDU_SCROLL2: - ; SET BLOCK COPY COUNT (WILL EXECUTE COPY) - LD A,CVDU_COLS ; COPY 80 BYTES - LD C,30 ; WORD COUNT REGISTER - CALL CVDU_WR ; DO IT - - ; LOOP TILL DONE WITH ALL LINES - DJNZ CVDU_SCROLL2 ; REPEAT FOR ALL LINES - - ; SET MODE TO BLOCK WRITE TO CLEAR NEW LINE EXPOSED BY SCROLL - LD C,24 ; BLOCK MODE CONTROL REGISTER - CALL CVDU_RD ; GET CURRENT VALUE - AND $7F ; CLEAR BIT 7 FOR FILL MODE - CALL CVDU_WR ; DO IT - - ; SET VALUE TO WRITE - POP AF ; RESTORE THE FILL VALUE PASSED IN - LD C,31 ; DATA REGISTER - CALL CVDU_WR ; DO IT - - ; SET BLOCK WRITE COUNT (WILL EXECUTE THE WRITE) - LD A,CVDU_COLS - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN) - LD C,30 ; WORD COUNT REGISTER - CALL CVDU_WR ; DO IT - - RET -; -;---------------------------------------------------------------------- -; REVERSE SCROLL ENTIRE SCREEN BY ONE LINE (CURSOR POSITION UNCHANGED) -;---------------------------------------------------------------------- -; -CVDU_RSCROLL: - ; SCROLL THE CHARACTER BUFFER - LD A,' ' ; CHAR VALUE TO FILL NEW EXPOSED LINE - LD HL,$0 + ((CVDU_ROWS - 1) * CVDU_COLS) ; SOURCE ADDRESS OF CHARACER BUFFER - CALL CVDU_RSCROLL1 ; SCROLL CHARACTER BUFFER - - ; SCROLL THE ATTRIBUTE BUFFER - LD A,(CVDU_ATTR) ; ATTRIBUTE VALUE TO FILL NEW EXPOSED LINE - LD HL,$800 + ((CVDU_ROWS - 1) * CVDU_COLS) ; SOURCE ADDRESS OF ATTRIBUTE BUFFER - JR CVDU_RSCROLL1 ; SCROLL ATTRIBUTE BUFFER AND RETURN - -CVDU_RSCROLL1: - PUSH AF ; SAVE FILL VALUE FOR NOW - - ; SET MODE TO BLOCK COPY - LD C,24 ; BLOCK MODE CONTROL REGISTER - CALL CVDU_RD ; GET CURRENT VALUE - OR $80 ; SET BIT 7 FOR COPY MODE - CALL CVDU_WR ; DO IT - - ; LOOP TO SCROLL EACH LINE WORKING FROM BOTTOM TO TOP - LD B,CVDU_ROWS - 1 ; ITERATIONS (ROWS - 1) -CVDU_RSCROLL2: - - ; SET BLOCK COPY DESTINATION (USING HL PASSED IN) - LD C,18 ; UPDATE ADDRESS (DESTINATION) REGISTER - CALL CVDU_WRX ; DO IT - - ; COMPUTE SOURCE (DECREMENT ONE ROW) - LD DE,CVDU_COLS ; SOURCE ADDRESS IS ONE ROW PAST DESTINATION - OR A ; CLEAR CARRY - SBC HL,DE ; SUBTRACT IT FROM BUF ADDRESS - - ; SET BLOCK COPY SOURCE - LD C,32 ; BLOCK START ADDRESS REGISTER - CALL CVDU_WRX ; DO IT - - ; SET BLOCK COPY COUNT (WILL EXECUTE COPY) - LD A,CVDU_COLS ; COPY 80 BYTES - LD C,30 ; WORD COUNT REGISTER - CALL CVDU_WR ; DO IT - - DJNZ CVDU_RSCROLL2 ; REPEAT FOR ALL LINES - - ; SET FILL DESTINATION (USING HL PASSED IN) - LD C,18 ; UPDATE ADDRESS (DESTINATION) REGISTER - CALL CVDU_WRX ; DO IT - - ; SET MODE TO BLOCK WRITE TO CLEAR NEW LINE EXPOSED BY SCROLL - LD C,24 ; BLOCK MODE CONTROL REGISTER - CALL CVDU_RD ; GET CURRENT VALUE - AND $7F ; CLEAR BIT 7 FOR FILL MODE - CALL CVDU_WR ; DO IT - - ; SET VALUE TO WRITE - POP AF ; RESTORE THE FILL VALUE PASSED IN - LD C,31 ; DATA REGISTER - CALL CVDU_WR ; DO IT - - ; SET BLOCK WRITE COUNT (WILL EXECUTE THE WRITE) - LD A,CVDU_COLS - 1 ; SET WRITE COUNT TO LINE LENGTH - 1 (1 CHAR ALREADY WRITTEN) - LD C,30 ; WORD COUNT REGISTER - CALL CVDU_WR ; DO IT - - RET -; -;---------------------------------------------------------------------- -; BLOCK COPY BC BYTES FROM HL TO DE -;---------------------------------------------------------------------- -; -CVDU_BLKCPY: - ; SETUP PARMS FOR FIRST PASS (CHARS) - PUSH BC ; LENGTH - PUSH HL ; SOURCE - PUSH DE ; DEST - ; PUT A RETURN ADDRESS ON THE STACK FOR SECOND PASS - PUSH HL ; PUT CURRENT HL ON STACK - LD HL,CVDU_BLKCPY1 ; NOW SET HL TO RETURN ADDRESS - EX (SP),HL ; GET ORIG HL BACK, AND PUT RET ADR ON STACK - ; SETUP PARMS FOR SECOND PASS (ATTRIBUTES) - PUSH BC ; LENGTH - LD BC,$800 ; USE BC TO ADD OFFSET TO ATTR BUF - ADD HL,BC ; ADD THE OFFSET TO HL - PUSH HL ; SAVE PARM (SOURCE ADR) - EX DE,HL ; GET DE INTO HL - ADD HL,BC ; ADD THE OFFSET - PUSH HL ; SAVE PARM (DESTINATION ADR) -; -CVDU_BLKCPY1: - ; SET MODE TO BLOCK COPY - LD C,24 ; BLOCK MODE CONTROL REGISTER - CALL CVDU_RD ; GET CURRENT VALUE - OR $80 ; SET BIT 7 FOR COPY MODE - CALL CVDU_WR ; DO IT -; - ; SET DESTINATION - POP HL ; RECOVER DESTINATION ADDRESS - LD C,18 ; REGISTER = UPDATE ADDRESS - CALL CVDU_WRX ; DO IT -; - ; SET SOURCE - POP HL ; RECOVER SOURCE ADDRESS - LD C,32 ; REGISTER = BLOCK START - CALL CVDU_WRX ; DO IT -; - ; SET LENGTH - POP HL ; RECOVER LENGTH - LD A,L ; BYTES TO COPY GOES IN A - LD C,30 ; REGSITER = WORD COUNT - JP CVDU_WR ; DO IT (COPY OCCURS HERE) AND RETURN -; -;================================================================================================== -; CVDU DRIVER - DATA -;================================================================================================== -; -CVDU_ATTR .DB 0 ; CURRENT COLOR -CVDU_POS .DW 0 ; CURRENT DISPLAY POSITION -; -; ATTRIBUTE ENCODING: -; BIT 7: ALTERNATE CHARACTER SET -; BIT 6: REVERSE VIDEO -; BIT 5: UNDERLINE -; BIT 4: BLINK -; BIT 3: RED -; BIT 2: GREEN -; BIT 1: BLUE -; BIT 0: INTENSITY -; -;================================================================================================== -; CVDU DRIVER - 8563 REGISTER INITIALIZATION -;================================================================================================== -; -; Reg Hex Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 Description -; 0 $00 HT7 HT6 HT5 HT4 HT3 HT2 HT1 HT0 Horizontal Total -; 1 $01 HD7 HD6 HD5 HD4 HD3 HD2 HD1 HD0 Horizontal Displayed -; 2 $02 HP7 HP6 HP5 HP4 HP3 HP2 HP1 HP0 Horizontal Sync Position -; 3 $03 VW3 VW2 VW1 VW0 HW3 HW2 HW1 HW0 Vertical/Horizontal Sync Width -; 4 $04 VT7 VT6 VT5 VT4 VT3 VT2 VT1 VT0 Vertical Total -; 5 $05 -- -- -- VA4 VA3 VA2 VA1 VA0 Vertical Adjust -; 6 $06 VD7 VD6 VD5 VD4 VD3 VD2 VD1 VD0 Vertical Displayed -; 7 $07 VP7 VP6 VP5 VP4 VP3 VP2 VP1 VP0 Vertical Sync Position -; 8 $08 -- -- -- -- -- -- IM1 IM0 Interlace Mode -; 9 $09 -- -- -- -- CTV4 CTV3 CTV2 CTV1 Character Total Vertical -; 10 $0A -- CM1 CM0 CS4 CS3 CS2 CS1 CS0 Cursor Mode, Start Scan -; 11 $0B -- -- -- CE4 CE3 CE2 CE1 CE0 Cursor End Scan Line -; 12 $0C DS15 DS14 DS13 DS12 DS11 DS10 DS9 DS8 Display Start Address High Byte -; 13 $0D DS7 DS6 DS5 DS4 DS3 DS2 DS1 DS0 Display Start Address Low Byte -; 14 $0E CP15 CP14 CP13 CP12 CP11 CP10 CP9 CP8 Cursor Position High Byte -; 15 $0F CP7 CP6 CP5 CP4 CP3 CP2 CP1 CP0 Cursor Position Low Byte -; 16 $10 LPV7 LPV6 LPV5 LPV4 LPV3 LPV2 LPV1 LPV0 Light Pen Vertical Position -; 17 $11 LPH7 LPH6 LPH5 LPH4 LPH3 LPH2 LPH1 LPH0 Light Pen Horizontal Position -; 18 $12 UA15 UA14 UA13 UA12 UA11 UA10 UA9 UA8 Update Address High Byte -; 19 $13 UA7 UA6 UA5 UA4 UA3 UA2 UA1 UA0 Update Address Low Byte -; 20 $14 AA15 AA14 AA13 AA12 AA11 AA10 AA9 AA8 Attribute Start Address High Byte -; 21 $15 AA7 AA6 AA5 AA4 AA3 AA2 AA1 AA0 Attribute Start Address Low Byte -; 22 $16 CTH3 CTH2 CTH1 CTH0 CDH3 CDH2 CDH1 CDH0 Character Total Horizontal, Character Display Horizontal -; 23 $17 -- -- -- CDV4 CDV3 CDV2 CDV1 CDV0 Character Display Vertical -; 24 $18 COPY RVS CBRATE VSS4 VSS3 VSS2 VSS1 VSS0 Vertical Smooth Scrolling -; 25 $19 TEXT ATR SEMI DBL HSS3 HSS2 HSS1 HSS0 Horizontal Smooth Scrolling -; 26 $1A FG3 FG2 FG1 FG0 BG3 BG2 BG1 BG0 Foreground/Background color -; 27 $1B AI7 AI6 AI5 AI4 AI3 AI2 AI1 AI0 Address Increment per Row -; 28 $1C CB15 CB14 CB13 RAM -- -- -- -- Character Base Address -; 29 $1D -- -- -- UL4 UL3 UL2 UL1 UL0 Underline Scan Line -; 30 $1E WC7 WC6 WC5 WC4 WC3 WC2 WC1 WC0 Word Count -; 31 $1F DA7 DA6 DA5 DA4 DA3 DA2 DA1 DA0 Data Register -; 32 $20 BA15 BA14 BA13 BA12 BA11 BA10 BA9 BA8 Block Start Address High Byte -; 33 $21 BA7 BA6 BA5 BA4 BA3 BA2 BA1 BA0 Block Start Address Low Byte -; 34 $22 DEB7 DEB6 DEB5 DEB4 DEB3 DEB2 DEB1 DEB0 Display Enable Begin -; 35 $23 DEE7 DEE6 DEE5 DEE4 DEE3 DEE2 DEE1 DEE0 Display Enable End -; 36 $24 -- -- -- -- DRR3 DRR2 DRR1 DRR0 DRAM Refresh Rate -; -; EGA 720X368 9-BIT CHARACTERS -; - requires 16.257Mhz oscillator frequency -; -CVDU_INIT8563: - .DB 97 ; 0: hor. total - 1 - .DB 80 ; 1: hor. displayed - .DB 90 ; 2: hor. sync position 85 - .DB $14 ; 3: vert/hor sync width or 0x4F -- MDA - .DB 26 ; 4: vert total - .DB 2 ; 5: vert total adjust - .DB 25 ; 6: vert. displayed - .DB 26 ; 7: vert. sync postition - .DB 0 ; 8: interlace mode - .DB 13 ; 9: char height - 1 - .DB (2<<5)+12 ; 10: cursor mode, start line - .DB 13 ; 11: cursor end line - .DB 0 ; 12: display start addr hi - .DB 0 ; 13: display start addr lo - .DB 7 ; 14: cursor position hi - .DB 128 ; 15: cursor position lo - .DB 1 ; 16: light pen vertical - .DB 1 ; 17: light pen horizontal - .DB 0 ; 18: update address hi - .DB 0 ; 19: update address lo - .DB 8 ; 20: attribute start addr hi - .DB 0 ; 21: attribute start addr lo - .DB $89 ; 22: char hor size cntrl 0x78 - .DB 13 ; 23: vert char pixel space - 1, increase to 13 with new font - .DB 0 ; 24: copy/fill, reverse, blink rate; vertical scroll - .DB $48 ; 25: gr/txt, color/mono, pxl-rpt, dbl-wide; horiz. scroll - .DB $E0 ; 26: fg/bg colors (monochr) - .DB 0 ; 27: row addr display incr - .DB $20+(1<<4) ; 28: char set addr; RAM size (64/16) - .DB 13 ; 29: underline position - .DB 0 ; 30: word count - 1 - .DB 0 ; 31: data - .DB 0 ; 32: block copy src hi - .DB 0 ; 33: block copy src lo - .DB 6 ; 34: display enable begin - .DB 88 ; 35: display enable end - .DB 0 ; 36: refresh rate - -; .DB 126,80,102,73,32,224,25,29,252,231,160,231,0,0,7,128 -; .DB 18,23,15,208,8,32,120,232,32,71,240,0,47,231,79,7,15,208,125,100,245 -; -;================================================================================================== -; CVDU DRIVER - FONT DATA -;================================================================================================== -; -#INCLUDE "cvdu_font.asm" \ No newline at end of file diff --git a/branches/s100/Source/cvdu_font.asm b/branches/s100/Source/cvdu_font.asm deleted file mode 100644 index 567baef0..00000000 --- a/branches/s100/Source/cvdu_font.asm +++ /dev/null @@ -1,1025 +0,0 @@ -CVDU_FONTDATA: - .DB $18,$18,$18,$FF,$FF,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$C0,$30,$30,$C0,$C0,$30,$30 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$18,$18,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $33,$33,$CC,$CC,$33,$33,$CC,$CC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $33,$99,$CC,$66,$33,$99,$CC,$66 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F0,$F0,$F0,$F0,$F0,$F0,$F0,$F0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CC,$CC,$33,$33,$CC,$CC,$33,$33 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $03,$03,$03,$03,$03,$03,$03,$03 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$CC,$CC,$33,$33 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CC,$99,$33,$66,$CC,$99,$33,$66 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $03,$03,$03,$03,$03,$03,$03,$03 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$1F,$1F,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$1F,$1F,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$F8,$F8,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$1F,$1F,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$FF,$FF,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$FF,$FF,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$F8,$F8,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $07,$07,$07,$07,$07,$07,$07,$07 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $01,$03,$06,$6C,$78,$70,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$18,$00,$00,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$FF,$66,$FF,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$3E,$60,$3C,$06,$7C,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $62,$66,$0C,$18,$30,$66,$46,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$3C,$38,$67,$66,$3F,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $06,$0C,$18,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0C,$18,$30,$30,$30,$18,$0C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $30,$18,$0C,$0C,$0C,$18,$30,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$66,$3C,$FF,$3C,$66,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$18,$7E,$18,$18,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$18,$18,$30 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$7E,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$03,$06,$0C,$18,$30,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$6E,$76,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$38,$18,$18,$18,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$06,$0C,$30,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$06,$1C,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $06,$0E,$1E,$66,$7F,$06,$06,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$60,$7C,$06,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$7C,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$66,$0C,$18,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$3C,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$3E,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$18,$00,$00,$18,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$18,$00,$00,$18,$18,$30 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0E,$18,$30,$60,$30,$18,$0E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$7E,$00,$7E,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $70,$18,$0C,$06,$0C,$18,$70,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$06,$0C,$18,$00,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$6E,$6E,$60,$62,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$3C,$66,$7E,$66,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7C,$66,$66,$7C,$66,$66,$7C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$60,$60,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $78,$6C,$66,$66,$66,$6C,$78,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$60,$60,$78,$60,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$60,$60,$78,$60,$60,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$6E,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$7E,$66,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$18,$18,$18,$18,$18,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $1E,$0C,$0C,$0C,$0C,$6C,$38,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$6C,$78,$70,$78,$6C,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $60,$60,$60,$60,$60,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $63,$77,$7F,$6B,$63,$63,$63,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$76,$7E,$7E,$6E,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$66,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7C,$66,$66,$7C,$60,$60,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$66,$66,$3C,$0E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7C,$66,$66,$7C,$78,$6C,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$3C,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$18,$18,$18,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$66,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$66,$66,$3C,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $63,$63,$63,$6B,$7F,$77,$63,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$3C,$18,$3C,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$3C,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$06,$0C,$18,$30,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$30,$30,$30,$30,$30,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $40,$60,$30,$18,$0C,$06,$02,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$0C,$0C,$0C,$0C,$0C,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$24,$42,$42,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$30,$18,$0C,$04,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3C,$06,$3E,$66,$3E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$60,$60,$7C,$66,$66,$7C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3C,$60,$60,$60,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$06,$06,$3E,$66,$66,$3E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3C,$66,$7E,$60,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$0E,$18,$3E,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3E,$66,$66,$3E,$06,$7C - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$60,$60,$7C,$66,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$00,$38,$18,$18,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$06,$00,$06,$06,$06,$06,$3C - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$60,$60,$6C,$78,$6C,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$38,$18,$18,$18,$18,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$66,$7F,$7F,$6B,$63,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$7C,$66,$66,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3C,$66,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$7C,$66,$66,$7C,$60,$60 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3E,$66,$66,$3E,$06,$06 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$7C,$66,$60,$60,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3E,$60,$3C,$06,$7C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$7E,$18,$18,$18,$0E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$66,$66,$66,$66,$3E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$66,$66,$66,$3C,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$63,$6B,$7F,$3E,$36,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$66,$3C,$18,$3C,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$66,$66,$66,$3E,$0C,$78 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$7E,$0C,$18,$30,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$0C,$10,$10,$20,$10,$10,$0C - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$18,$18,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$04,$04,$02,$04,$04,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$32,$4C,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$81,$81,$81,$81,$81,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F0,$F0,$F0,$F0,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$91,$91,$9F,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C3,$F9,$C1,$99,$C1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$9F,$9F,$83,$99,$99,$83,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C3,$9F,$9F,$9F,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$F9,$F9,$C1,$99,$99,$C1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C3,$99,$81,$9F,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$F1,$E7,$C1,$E7,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C1,$99,$99,$C1,$F9,$83 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$9F,$9F,$83,$99,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$E7,$FF,$C7,$E7,$E7,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$F9,$FF,$F9,$F9,$F9,$F9,$C3 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$9F,$9F,$93,$87,$93,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$C7,$E7,$E7,$E7,$E7,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$99,$80,$80,$94,$9C,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$83,$99,$99,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C3,$99,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$83,$99,$99,$83,$9F,$9F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C1,$99,$99,$C1,$F9,$F9 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$83,$99,$9F,$9F,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C1,$9F,$C3,$F9,$83,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$E7,$81,$E7,$E7,$E7,$F1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$99,$99,$99,$99,$C1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$99,$99,$99,$C3,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$9C,$94,$80,$C1,$C9,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$99,$C3,$E7,$C3,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$99,$99,$99,$C1,$F3,$87 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$81,$F3,$E7,$CF,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$CF,$CF,$CF,$CF,$CF,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F3,$ED,$CF,$83,$CF,$9D,$03,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$F3,$F3,$F3,$F3,$F3,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$E7,$C3,$81,$E7,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$EF,$CF,$80,$80,$CF,$EF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E7,$FF,$FF,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$00,$99,$00,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$C1,$9F,$C3,$F9,$83,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9D,$99,$F3,$E7,$CF,$99,$B9,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$C3,$C7,$98,$99,$C0,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F9,$F3,$E7,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F3,$E7,$CF,$CF,$CF,$E7,$F3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CF,$E7,$F3,$F3,$F3,$E7,$CF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$99,$C3,$00,$C3,$99,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$E7,$E7,$81,$E7,$E7,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$CF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$81,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FC,$F9,$F3,$E7,$CF,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$91,$89,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$C7,$E7,$E7,$E7,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$F9,$F3,$CF,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$F9,$E3,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F9,$F1,$E1,$99,$80,$F9,$F9,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$9F,$83,$F9,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$83,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$99,$F3,$E7,$E7,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$C3,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$C1,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$E7,$FF,$FF,$E7,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$E7,$FF,$FF,$E7,$E7,$CF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F1,$E7,$CF,$9F,$CF,$E7,$F1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$81,$FF,$81,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $8F,$E7,$F3,$F9,$F3,$E7,$8F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$F9,$F3,$E7,$FF,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$00,$00,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$C3,$99,$81,$99,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $83,$99,$99,$83,$99,$99,$83,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$9F,$9F,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $87,$93,$99,$99,$99,$93,$87,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$9F,$9F,$87,$9F,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$9F,$9F,$87,$9F,$9F,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$91,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$81,$99,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$E7,$E7,$E7,$E7,$E7,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E1,$F3,$F3,$F3,$F3,$93,$C7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$93,$87,$8F,$87,$93,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9F,$9F,$9F,$9F,$9F,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9C,$88,$80,$94,$9C,$9C,$9C,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$89,$81,$81,$91,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$99,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $83,$99,$99,$83,$9F,$9F,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$99,$99,$C3,$F1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $83,$99,$99,$83,$87,$93,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$C3,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$E7,$E7,$E7,$E7,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$99,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$99,$99,$C3,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9C,$9C,$9C,$94,$80,$88,$9C,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$C3,$E7,$C3,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$C3,$E7,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$F9,$F3,$E7,$CF,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$00,$00,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$3F,$CF,$CF,$3F,$3F,$CF,$CF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E7,$E7,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CC,$CC,$33,$33,$CC,$CC,$33,$33 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CC,$66,$33,$99,$CC,$66,$33,$99 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$FF,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $33,$33,$CC,$CC,$33,$33,$CC,$CC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$33,$33,$CC,$CC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $33,$66,$CC,$99,$33,$66,$CC,$99 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E0,$E0,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$F0,$F0,$F0,$F0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E0,$E0,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$07,$07,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$E0,$E0,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$00,$00,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$00,$00,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$07,$07,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F8,$F8,$F8,$F8,$F8,$F8,$F8,$F8 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FE,$FC,$F9,$93,$87,$8F,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F0,$F0,$F0,$F0,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$07,$07,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0F,$0F,$0F,$0F,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0F,$0F,$0F,$0F,$F0,$F0,$F0,$F0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$6E,$6E,$60,$62,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$3C,$66,$7E,$66,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7C,$66,$66,$7C,$66,$66,$7C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$60,$60,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $78,$6C,$66,$66,$66,$6C,$78,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$60,$60,$78,$60,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$60,$60,$78,$60,$60,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$6E,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$7E,$66,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$18,$18,$18,$18,$18,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $1E,$0C,$0C,$0C,$0C,$6C,$38,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$6C,$78,$70,$78,$6C,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $60,$60,$60,$60,$60,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $63,$77,$7F,$6B,$63,$63,$63,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$76,$7E,$7E,$6E,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$66,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7C,$66,$66,$7C,$60,$60,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$66,$66,$3C,$0E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7C,$66,$66,$7C,$78,$6C,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$3C,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$18,$18,$18,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$66,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$66,$66,$3C,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $63,$63,$63,$6B,$7F,$77,$63,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$3C,$18,$3C,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$3C,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$06,$0C,$18,$30,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$30,$30,$30,$30,$30,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0C,$12,$30,$7C,$30,$62,$FC,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$0C,$0C,$0C,$0C,$0C,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$3C,$7E,$18,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$10,$30,$7F,$7F,$30,$10,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$18,$00,$00,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$66,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $66,$66,$FF,$66,$FF,$66,$66,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$3E,$60,$3C,$06,$7C,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $62,$66,$0C,$18,$30,$66,$46,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$3C,$38,$67,$66,$3F,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $06,$0C,$18,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0C,$18,$30,$30,$30,$18,$0C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $30,$18,$0C,$0C,$0C,$18,$30,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$66,$3C,$FF,$3C,$66,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$18,$18,$7E,$18,$18,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$18,$18,$30 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$7E,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$03,$06,$0C,$18,$30,$60,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$6E,$76,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$38,$18,$18,$18,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$06,$0C,$30,$60,$7E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$06,$1C,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $06,$0E,$1E,$66,$7F,$06,$06,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$60,$7C,$06,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$60,$7C,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $7E,$66,$0C,$18,$18,$18,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$3C,$66,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$66,$3E,$06,$66,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$18,$00,$00,$18,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$18,$00,$00,$18,$18,$30 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0E,$18,$30,$60,$30,$18,$0E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$7E,$00,$7E,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $70,$18,$0C,$06,$0C,$18,$70,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$66,$06,$0C,$18,$00,$18,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$FF,$FF,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $08,$1C,$3E,$7F,$7F,$1C,$3E,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$18,$18,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$FF,$FF,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$FF,$FF,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$FF,$FF,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$FF,$FF,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $30,$30,$30,$30,$30,$30,$30,$30 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$E0,$F0,$38,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$1C,$0F,$07,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$38,$F0,$E0,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$C0,$C0,$C0,$C0,$C0,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$E0,$70,$38,$1C,$0E,$07,$03 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $03,$07,$0E,$1C,$38,$70,$E0,$C0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$C0,$C0,$C0,$C0,$C0,$C0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$03,$03,$03,$03,$03,$03 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$3C,$7E,$7E,$7E,$7E,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$FF,$FF,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $36,$7F,$7F,$7F,$3E,$1C,$08,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $60,$60,$60,$60,$60,$60,$60,$60 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$07,$0F,$1C,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$E7,$7E,$3C,$3C,$7E,$E7,$C3 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$3C,$7E,$66,$66,$7E,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$66,$66,$18,$18,$3C,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $06,$06,$06,$06,$06,$06,$06,$06 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $08,$1C,$3E,$7F,$3E,$1C,$08,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$FF,$FF,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$C0,$30,$30,$C0,$C0,$30,$30 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$18,$18,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$03,$3E,$76,$36,$36,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$7F,$3F,$1F,$0F,$07,$03,$01 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F0,$F0,$F0,$F0,$F0,$F0,$F0,$F0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CC,$CC,$33,$33,$CC,$CC,$33,$33 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $03,$03,$03,$03,$03,$03,$03,$03 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$CC,$CC,$33,$33 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FE,$FC,$F8,$F0,$E0,$C0,$80 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $03,$03,$03,$03,$03,$03,$03,$03 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$1F,$1F,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$1F,$1F,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$F8,$F8,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$1F,$1F,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$FF,$FF,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$FF,$FF,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$F8,$F8,$18,$18,$18 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $07,$07,$07,$07,$07,$07,$07,$07 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $03,$03,$03,$03,$03,$03,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$F0,$F0,$F0,$F0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0F,$0F,$0F,$0F,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $18,$18,$18,$F8,$F8,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F0,$F0,$F0,$F0,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F0,$F0,$F0,$F0,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$91,$91,$9F,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$C3,$99,$81,$99,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $83,$99,$99,$83,$99,$99,$83,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$9F,$9F,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $87,$93,$99,$99,$99,$93,$87,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$9F,$9F,$87,$9F,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$9F,$9F,$87,$9F,$9F,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$91,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$81,$99,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$E7,$E7,$E7,$E7,$E7,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E1,$F3,$F3,$F3,$F3,$93,$C7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$93,$87,$8F,$87,$93,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9F,$9F,$9F,$9F,$9F,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9C,$88,$80,$94,$9C,$9C,$9C,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$89,$81,$81,$91,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$99,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $83,$99,$99,$83,$9F,$9F,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$99,$99,$C3,$F1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $83,$99,$99,$83,$87,$93,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$C3,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$E7,$E7,$E7,$E7,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$99,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$99,$99,$C3,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9C,$9C,$9C,$94,$80,$88,$9C,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$C3,$E7,$C3,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$C3,$E7,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$F9,$F3,$E7,$CF,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$CF,$CF,$CF,$CF,$CF,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F3,$ED,$CF,$83,$CF,$9D,$03,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$F3,$F3,$F3,$F3,$F3,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$E7,$C3,$81,$E7,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$EF,$CF,$80,$80,$CF,$EF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E7,$FF,$FF,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$99,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $99,$99,$00,$99,$00,$99,$99,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$C1,$9F,$C3,$F9,$83,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9D,$99,$F3,$E7,$CF,$99,$B9,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$C3,$C7,$98,$99,$C0,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F9,$F3,$E7,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F3,$E7,$CF,$CF,$CF,$E7,$F3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CF,$E7,$F3,$F3,$F3,$E7,$CF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$99,$C3,$00,$C3,$99,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$E7,$E7,$81,$E7,$E7,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$CF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$81,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FC,$F9,$F3,$E7,$CF,$9F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$91,$89,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$C7,$E7,$E7,$E7,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$F9,$F3,$CF,$9F,$81,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$F9,$E3,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F9,$F1,$E1,$99,$80,$F9,$F9,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$9F,$83,$F9,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$9F,$83,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $81,$99,$F3,$E7,$E7,$E7,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$C3,$99,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$99,$C1,$F9,$99,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$E7,$FF,$FF,$E7,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$E7,$FF,$FF,$E7,$E7,$CF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F1,$E7,$CF,$9F,$CF,$E7,$F1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$81,$FF,$81,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $8F,$E7,$F3,$F9,$F3,$E7,$8F,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C3,$99,$F9,$F3,$E7,$FF,$E7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$00,$00,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F7,$E3,$C1,$80,$80,$E3,$C1,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E7,$E7,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$00,$00,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$00,$00,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$00,$00,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$00,$00,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $CF,$CF,$CF,$CF,$CF,$CF,$CF,$CF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F3,$F3,$F3,$F3,$F3,$F3,$F3,$F3 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$1F,$0F,$C7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E3,$F0,$F8,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$C7,$0F,$1F,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$3F,$3F,$3F,$3F,$3F,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$1F,$8F,$C7,$E3,$F1,$F8,$FC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FC,$F8,$F1,$E3,$C7,$8F,$1F,$3F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$3F,$3F,$3F,$3F,$3F,$3F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$FC,$FC,$FC,$FC,$FC,$FC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$C3,$81,$81,$81,$81,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$00,$00,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $C9,$80,$80,$80,$C1,$E3,$F7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $9F,$9F,$9F,$9F,$9F,$9F,$9F,$9F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$F8,$F0,$E3,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3C,$18,$81,$C3,$C3,$81,$18,$3C - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$C3,$81,$99,$99,$81,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$99,$99,$E7,$E7,$C3,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F9,$F9,$F9,$F9,$F9,$F9,$F9,$F9 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F7,$E3,$C1,$80,$C1,$E3,$F7,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$00,$00,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$3F,$CF,$CF,$3F,$3F,$CF,$CF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E7,$E7,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FC,$C1,$89,$C9,$C9,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$80,$C0,$E0,$F0,$F8,$FC,$FE - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$00,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$FF,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $33,$33,$CC,$CC,$33,$33,$CC,$CC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$33,$33,$CC,$CC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$01,$03,$07,$0F,$1F,$3F,$7F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E0,$E0,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$F0,$F0,$F0,$F0 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$E0,$E0,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$07,$07,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$FF,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$E0,$E0,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$00,$00,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$00,$00,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$07,$07,$E7,$E7,$E7 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $3F,$3F,$3F,$3F,$3F,$3F,$3F,$3F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F8,$F8,$F8,$F8,$F8,$F8,$F8,$F8 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$FF,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $00,$00,$00,$FF,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$FF,$00,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FC,$FC,$FC,$FC,$FC,$FC,$00,$00 - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $FF,$FF,$FF,$FF,$0F,$0F,$0F,$0F - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $F0,$F0,$F0,$F0,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $E7,$E7,$E7,$07,$07,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 - .DB $0F,$0F,$0F,$0F,$FF,$FF,$FF,$FF - .DB $00,$00,$00,$00,$00,$00,$00,$00 diff --git a/branches/s100/Source/dbgmon.asm b/branches/s100/Source/dbgmon.asm deleted file mode 100644 index c78b0cf7..00000000 --- a/branches/s100/Source/dbgmon.asm +++ /dev/null @@ -1,1589 +0,0 @@ -;___ROM_MONITOR_PROGRAM_______________________________________________________ -; -; ORIGINAL CODE BY: ANDREW LYNCH (LYNCHAJ@YAHOO COM) 13 FEB 2007 -; -; MODIFIED BY : DAN WERNER 03 09.2009 -; -;__REFERENCES_________________________________________________________________ -; THOMAS SCHERRER BASIC HAR.DWARE TEST ASSEMBLER SOURCES FROM THE Z80 INFO PAGE -; INCLUDING ORIGINAL SCHEMATIC CONCEPT -; HTTP://Z80 INFO/Z80SOURC.TXT -; CODE SAMPLES FROM BRUCE JONES PUBLIC DOMAIN ROM MONITOR FOR THE SBC-200C -; HTTP://WWW RETROTECHNOLOGY.COM/HERBS_STUFF/SD_BRUCE_CODE.ZIP -; INSPIRATION FROM JOEL OWENS "Z-80 SPACE-TIME PRODUCTIONS SINGLE BOARD COMPUTER" -; HTTP://WWW JOELOWENS.ORG/Z80/Z80INDEX.HTML -; GREAT HELP AND TECHNICAL ADVICE FROM ALLISON AT ALPACA_DESIGNERS -; HTTP://GROUPS YAHOO.COM/GROUP/ALPACA_DESIGNERS -; INTEL SDK-85 ROM DEBUG MONITOR -;_____________________________________________________________________________ -; -#INCLUDE "std.asm" -; -;__CONSTANTS__________________________________________________________________ -; -ENDT: .EQU 0FFh ; MARK END OF TEXT -CR: .EQU 0DH ; ASCII CARRIAGE RETURN CHARACTER -LF: .EQU 0AH ; ASCII LINE FEED CHARACTER -ESC: .EQU 1BH ; ASCII ESCAPE CHARACTER -BS: .EQU 08H ; ASCII BACKSPACE CHARACTER -; -;__MAIN_PROGRAM_______________________________________________________________ -; -; ORG 00100h ; FOR DEBUG IN CP/M (AS .COM) - .ORG MON_LOC -; -;__ENTRY JUMP TABLE___________________________________________________________ -; - JP DSKY_ENTRY - JP UART_ENTRY -; -#DEFINE CIOMODE_CBIOS -#INCLUDE "util.asm" -; -#INCLUDE "memmgr.asm" -; -;__DSKY_ENTRY_________________________________________________________________ -; -DSKY_ENTRY: - LD SP,MON_STACK ; SET THE STACK POINTER - CALL INITIALIZE ; INITIALIZE SYSTEM - -;__FRONT_PANEL_STARTUP________________________________________________________ -; -; START UP THE SYSTEM WITH THE FRONT PANEL INTERFACE -; -;_____________________________________________________________________________ -; - CALL MTERM_INIT ; INIT 8255 FOR MTERM - LD HL,CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - - - -FRONTPANELLOOP: - CALL KB_GET ; GET KEY FROM KB - - CP 10H ; IS PORT READ? - JP Z,DOPORTREAD ; YES, JUMP - CP 11H ; IS PORT WRITE? - JP Z,DOPORTWRITE ; YES, JUMP - CP 14H ; IS DEPOSIT? - JP Z,DODEPOSIT ; YES, JUMP - CP 15H ; IS EXAMINE? - JP Z,DOEXAMINE ; YES, JUMP - CP 16H ; IS GO? - JP Z,DOGO ; YES, JUMP - CP 17H ; IS BO? - JP Z,DOBOOT ; YES, JUMP - - JR FRONTPANELLOOP ; LOOP -EXIT: - RET - - -;__DOBOOT_____________________________________________________________________ -; -; PERFORM BOOT FRONT PANEL ACTION -;_____________________________________________________________________________ -; -DOBOOT: - ; ENSURE DEFAULT MEMORY PAGE CONFIGURATION -;#IF (PLATFORM == PLT_N8) -; LD A,DEFACR -; OUT0 (ACR),A -; XOR A -; OUT0 (RMAP),A -;#ELSE -; XOR A -; OUT (MPCL_ROM),A -; OUT (MPCL_RAM),A -;#ENDIF - CALL ROMPGZ - ; JUMP TO RESTART ADDRESS - JP 0000H -; -;__DOPORTREAD_________________________________________________________________ -; -; PERFORM PORT READ FRONT PANEL ACTION -;_____________________________________________________________________________ -; -DOPORTREAD: - CALL GETPORT ; GET PORT INTO A -PORTREADLOOP: - LD C,A ; STORE PORT IN "C" - SRL A ; ROTATE HIGH NIB TO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; SHOW HIGH NIB IN DISP 5 - LD A,C ; RESTORE PORT VALUE INTO "A" - AND 0FH ; CLEAR HIGH NIB, LEAVING LOW - LD (DISPLAYBUF+4),A ; SHOW LOW NIB IN DISP 4 - IN A,(C) ; GET PORT VALUE FROM PORT IN "C" - LD C,A ; STORE VALUE IN "C" - SRL A ; ROTATE HIGH NIB TO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; SHOW HIGH NIB IN DISP 1 - LD A,C ; RESTORE VALUE TO "A" - AND 0FH ; CLEAR HIGH NIB, LEAVING LOW - LD (DISPLAYBUF),A ; DISPLAY LOW NIB IN DISP 0 - LD A,10H ; CLEAR OTHER DISPLAYS - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - LD A,13H ; "P" - LD (DISPLAYBUF+7),A ; STORE IN DISP 7 - LD A,14H ; "O" - LD (DISPLAYBUF+6),A ; STORE IN DISP 6 - LD HL,DISPLAYBUF ; SET POINTER TO DISPLAY BUFFER - CALL HEXDISPLAY ; DISPLAY BUFFER CONTENTS -PORTREADGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP 12H ; [CL] PRESSED, EXIT - JP Z,PORTREADEXIT ; - CP 10H ; [PR] PRESSED, PROMPT FOR NEW PORT - JR Z,DOPORTREAD ; - JR PORTREADGETKEY ; NO VALID KEY, LOOP -PORTREADEXIT: - LD HL,CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - -;__DOPORTWRITE________________________________________________________________ -; -; PERFORM PORT WRITE FRONT PANEL ACTION -;_____________________________________________________________________________ -; -DOPORTWRITE: - CALL GETPORT ; GET PORT INTO A -PORTWRITELOOP: - LD C,A ; STORE PORT IN "C" - SRL A ; ROTATE HIGH NIB INTO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; DISPLAY HIGH NIB IN DISPLAY 5 - LD A,C ; RESTORE PORT VALUE INTO "A" - AND 0FH ; CLEAR OUT HIGH NIB - LD (DISPLAYBUF+4),A ; DISPLAY LOW NIB IN DISPLAY 4 - LD A,10H ; CLEAR OUT DISPLAYS 2 AND 3 - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - LD A,13H ; DISPLAY "P" IN DISP 7 - LD (DISPLAYBUF+7),A ; - LD A,14H ; DISPLAY "O" IN DISP 6 - LD (DISPLAYBUF+6),A ; - LD HL,DISPLAYBUF ; POINT TO DISPLAY BUFFER - CALL GETVALUE ; INPUT A BYTE VALUE, RETURN IN "A" - OUT (C),A ; OUTPUT VALUE TO PORT STORED IN "C" - LD HL,CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - -;__DOGO_______________________________________________________________________ -; -; PERFORM GO FRONT PANEL ACTION -;_____________________________________________________________________________ -; -DOGO: - CALL GETADDR ; GET ADDRESS INTO HL - JP (HL) ; GO THERE! - - - -;__DODEPOSIT__________________________________________________________________ -; -; PERFORM DEPOSIT FRONT PANEL ACTION -;_____________________________________________________________________________ -; -DODEPOSIT: - CALL GETADDR ; GET ADDRESS INTO HL - PUSH HL -DEPOSITLOOP: - LD A,H ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,H ; - AND 0FH ; - LD (DISPLAYBUF+6),A ; - LD A,L ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,L ; - AND 0FH ; - LD (DISPLAYBUF+4),A ; - LD A,10H ; - LD (DISPLAYBUF+3),A ; - LD HL,DISPLAYBUF ; - CALL GETVALUE ; - POP HL ; - LD (HL),A ; -DEPOSITGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP 12H ; [CL] PRESSED, EXIT - JP Z,DEPOSITEXIT ; - CP 13H ; [EN] PRESSED, INC ADDRESS AND LOOP - JR Z,DEPOSITFW ; - CP 14H ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - JR Z,DODEPOSIT ; - JR DEPOSITGETKEY ; NO VALID KEY, LOOP -DEPOSITFW: - INC HL ; - PUSH HL ; STORE HL - JR DEPOSITLOOP ; -DEPOSITEXIT: - LD HL,CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - - - -;__DOEXAMINE__________________________________________________________________ -; -; PERFORM EXAMINE FRONT PANEL ACTION -;_____________________________________________________________________________ -; -DOEXAMINE: - CALL GETADDR ; GET ADDRESS INTO HL - PUSH HL ; STORE HL -EXAMINELOOP: - LD A,H ; MOVE HIGH BYTE IN "A" - SRL A ; SHOW HIGH NIBBLE IN DISP 7 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,H ; RESTORE HIGH BYTE - AND 0FH ; CLEAR HIGH NIBBLE - LD (DISPLAYBUF+6),A ; DISPLAY LOW NIBBLE IN DISP 6 - LD A,L ; PUT LOW BYTE IN "A" - SRL A ; SHOW HIGH NIBBLE IN DISP 5 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,L ; RESTORE LOW BYTE IN "A" - AND 0FH ; CLEAR OUT HIGH NIBBLE - LD (DISPLAYBUF+4),A ; DISPLAY LOW NIBBLE IN DISP 4 - LD A,10H ; CLEAR OUT DISP 3 - LD (DISPLAYBUF+3),A ; - LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - SRL A ; DISPLAY HIGH NIB IN DISPLAY 1 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; - LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - AND 0FH ; CLEAR OUT HIGH NIBBLE - LD (DISPLAYBUF),A ; DISPLAY LOW NIBBLE IN DISPLAY 0 - LD HL,DISPLAYBUF ; POINT TO DISPLAY BUFFER - CALL HEXDISPLAY ; DISPLAY BUFFER ON DISPLAYS - POP HL ; RESTORE HL -EXAMINEGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP 12H ; [CL] PRESSED, EXIT - JP Z,EXAMINEEXIT ; - CP 13H ; [EN] PRESSED, INC ADDRESS AND LOOP - JR Z,EXAMINEFW ; - CP 15H ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - JR Z,DOEXAMINE ; - JR EXAMINEGETKEY ; NO VALID KEY, LOOP -EXAMINEFW: - INC HL ; HL++ - PUSH HL ; STORE HL - JR EXAMINELOOP ; -EXAMINEEXIT: - LD HL,CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - -;__GETADDR____________________________________________________________________ -; -; GET ADDRESS FROM FRONT PANEL -;_____________________________________________________________________________ -; -GETADDR: - PUSH BC ; STORE BC - JR GETADDRCLEAR ; -GETADDR1: - LD HL,ADDR ; DISPLAY PROMPT - CALL SEGDISPLAY ; -GETADDRLOOP: - CALL KB_GET ; - CP 10H ; - JP M,GETADDRNUM ; NUMBER PRESSED, STORE IT - CP 13H ; EN PRESSED, DONE - JR Z,GETADDRDONE ; - CP 12H ; CLEAR PRESSED, CLEAR - JR Z,GETADDRCLEAR ; - JR GETADDRLOOP ; INVALID KEY, LOOP -GETADDRDONE: - LD HL,00H ; HL=0 - LD A,(DISPLAYBUF+1) ; GET DIGIT IN DISPLAY 1 - SLA A ; ROTATE IT TO HIGH NIBBLE - SLA A ; - SLA A ; - SLA A ; - LD C,A ; STORE IT IN "C" - LD A,(DISPLAYBUF) ; GET DIGIT IN DISPLAY 0 - AND 0FH ; CLEAR HIGH NIBBLE - OR C ; ADD IN NIBBLE STORED IN C - LD L,A ; STORE IT IN LOW BYTE OF ADDRESS POINTER - LD A,(DISPLAYBUF+3) ; GET DIGIT IN DISPLAY 3 - SLA A ; ROTATE IT TO HIGH NIBBLE - SLA A ; - SLA A ; - SLA A ; - LD C,A ; STORE IT IN "C" - LD A,(DISPLAYBUF+2) ; GET DIGIT IN DISPLAY 2 - AND 0FH ; CLEAR HIGH NIBBLE - OR C ; ADD IN NIBBLE STORED IN "C" - LD H,A ; STORE BYTE IN HIGH BYTE OF ADDRESS POINTER - LD A,10H ; CLEAR OUT DISPLAYS 0,1,2 & 3 - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - POP BC ; RESTORE BC - RET -GETADDRNUM: - LD C,A ; - LD A,(DISPLAYBUF+2) ; SHIFT BYTES IN DISPLAY BUF TO THE LEFT - LD (DISPLAYBUF+3),A ; - LD A,(DISPLAYBUF+1) ; - LD (DISPLAYBUF+2),A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; DISPLAY KEYSTROKE IN RIGHT MOST DISPLAY (0) - LD (DISPLAYBUF+0),A ; - JR GETADDRDISP ; -GETADDRCLEAR: - LD A,12H ; CLEAR OUT DISPLAYS 0,1,2 & 3 - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; -GETADDRDISP: - LD A,(DISPLAYBUF) ; ENCODE DIGITS IN DISPLAY BUFFER TO DISPLAY - CALL DECODEDISPLAY ; - LD (ADDR),A ; - LD A,(DISPLAYBUF+1) ; - CALL DECODEDISPLAY ; - LD (ADDR+1),A ; - LD A,(DISPLAYBUF+2) ; - CALL DECODEDISPLAY ; - LD (ADDR+2),A ; - LD A,(DISPLAYBUF+3) ; - CALL DECODEDISPLAY ; - LD (ADDR+3),A ; - JP GETADDR1 ; - - - -;__DSPSECTOR__________________________________________________________________ -; -; DISPLAY SECTOR IN HL ON FRONT PANEL -;_____________________________________________________________________________ -; -DSPSECTOR: - PUSH BC ; STORE BC - PUSH HL ; STORE HL - LD A,H ; DISPLAY HIGH BYTE, HIGH NIBBLE - SRL A ; - SRL A ; - SRL A ; - SRL A ; - AND 0FH ; - CALL DECODEDISPLAY ; - LD (SEC+3),A ; - LD A,H ; DISPLAY HIGH BYTE, LOW NIBBLE - AND 0FH ; - CALL DECODEDISPLAY ; - LD (SEC+2),A ; - LD A,L ; DISPLAY LOW BYTE, HIGH NIBBLE - AND 0F0H ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - AND 0FH ; - CALL DECODEDISPLAY ; - LD (SEC+1),A ; DISPLAY LOW BYTE, LOW NIBBLE - LD A,L ; - AND 0FH ; - CALL DECODEDISPLAY ; - LD (SEC),A ; - LD HL,SEC ; DISPLAY PROMPT - CALL SEGDISPLAY ; - POP HL ; RESTORE HL - POP BC ; RESTORE BC - RET - - - -;__GETPORT____________________________________________________________________ -; -; GET PORT FROM FRONT PANEL -;_____________________________________________________________________________ -; -GETPORT: - PUSH BC ; STORE BC - JR GETPORTCLEAR ; -GETPORT1: - LD HL,PORT ; DISPLAY PROMPT - CALL SEGDISPLAY ; -GETPORTLOOP: - CALL KB_GET ; - CP 10H ; - JP M,GETPORTNUM ; NUMBER PRESSED, STORE IT - CP 13H ; EN PRESSED, DONE - JR Z,GETPORTDONE ; - CP 12H ; CLEAR PRESSED, CLEAR - JR Z,GETPORTCLEAR ; - JR GETPORTLOOP ; INVALID KEY, LOOP -GETPORTDONE: - LD A,(DISPLAYBUF+1) ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - LD C,A ; - LD A,(DISPLAYBUF) ; - AND 0FH ; - OR C ; - LD C,A ; - LD A,10H ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - POP BC ; RESTORE BC - RET -GETPORTNUM: - LD C,A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - LD (DISPLAYBUF+0),A ; - JR GETPORTDISP ; -GETPORTCLEAR: - LD A,12H ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; -GETPORTDISP: - LD A,(DISPLAYBUF) ; - CALL DECODEDISPLAY ; - LD (PORT),A ; - LD A,(DISPLAYBUF+1) ; - CALL DECODEDISPLAY ; - LD (PORT+1),A ; - JP GETPORT1 ; - - -;__GETVALUE___________________________________________________________________ -; -; GET VALUE FROM FRONT PANEL -;_____________________________________________________________________________ -; -GETVALUE: - PUSH BC ; STORE BC - JR GETVALUECLEAR ; -GETVALUE1: - CALL HEXDISPLAY ; - -GETVALUELOOP: - CALL KB_GET ; - CP 10H ; - JP M,GETVALUENUM ; NUMBER PRESSED, STORE IT - CP 13H ; EN PRESSED, DONE - JR Z,GETVALUEDONE ; - CP 12H ; CLEAR PRESSED, CLEAR - JR Z,GETVALUECLEAR ; - JR GETVALUELOOP ; INVALID KEY, LOOP -GETVALUEDONE: - LD A,(DISPLAYBUF+1) ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - LD C,A ; - LD A,(DISPLAYBUF) ; - AND 0FH ; - OR C ; - LD C,A ; - LD A,10H ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - POP BC ; RESTORE BC - RET -GETVALUENUM: - LD C,A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - LD (DISPLAYBUF+0),A ; - JR GETVALUE1 ; -GETVALUECLEAR: - LD A,12H ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - JP GETVALUE1 ; - - -;__UART_ENTRY_________________________________________________________________ -; -; SERIAL MONITOR STARTUP -;_____________________________________________________________________________ -; -UART_ENTRY: - LD SP,MON_STACK ; SET THE STACK POINTER - CALL INITIALIZE ; INITIALIZE SYSTEM - - XOR A ;ZERO OUT ACCUMULATOR (ADDED) - PUSH HL ;PROTECT HL FROM OVERWRITE - LD HL,TXT_READY ;POINT AT TEXT - CALL MSG ;SHOW WE'RE HERE - POP HL ;PROTECT HL FROM OVERWRITE - -; -;__SERIAL_MONITOR_COMMANDS____________________________________________________ -; -; B XX BOOT CPM FROM DRIVE XX -; D XXXXH YYYYH DUMP MEMORY FROM XXXX TO YYYY -; F XXXXH YYYYH ZZH FILL MEMORY FROM XXXX TO YYYY WITH ZZ -; H LOAD INTEL HEX FORMAT DATA -; I INPUT FROM PORT AND SHOW HEX DATA -; K ECHO KEYBOARD INPUT -; M XXXXH YYYYH ZZZZH MOVE MEMORY BLOCK XXXX TO YYYY TO ZZZZ -; O OUTPUT TO PORT HEX DATA -; P XXXXH YYH PROGRAM RAM FROM XXXXH WITH VALUE IN YYH, WILL PROMPT FOR NEXT LINES FOLLOWING UNTIL CR -; R RUN A PROGRAM FROM CURRENT LOCATION -; -;__COMMAND_PARSE______________________________________________________________ -; -; PROMPT USER FOR COMMANDS, THEN PARSE THEM -;_____________________________________________________________________________ -; - -SERIALCMDLOOP: - CALL CRLFA ; CR,LF,> - LD HL,KEYBUF ; SET POINTER TO KEYBUF AREA - CALL GETLN ; GET A LINE OF INPUT FROM THE USER - LD HL,KEYBUF ; RESET POINTER TO START OF KEYBUF - LD A,(HL) ; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE COMMAND) - INC HL ; INC POINTER - - CP 'B' ; IS IT "B" (Y/N) - JP Z,DOBOOT ; IF YES DO BOOT - CP 'R' ; IS IT "R" (Y/N) - JP Z,RUN ; IF YES GO RUN ROUTINE - CP 'P' ; IS IT "P" (Y/N) - JP Z,PROGRM ; IF YES GO PROGRAM ROUTINE - CP 'O' ; IS IT AN "O" (Y/N) - JP Z,POUT ; PORT OUTPUT - CP 'H' ; IS IT A "H" (Y/N) - JP Z,HXLOAD ; INTEL HEX FORMAT LOAD DATA - CP 'I' ; IS IT AN "I" (Y/N) - JP Z,PIN ; PORT INPUT - CP 'D' ; IS IT A "D" (Y/N) - JP Z,DUMP ; DUMP MEMORY - CP 'K' - JP Z,KLOP ; LOOP ON KEYBOARD - CP 'M' ; IS IT A "M" (Y/N) - JP Z,MOVE ; MOVE MEMORY COMMAND - CP 'F' ; IS IT A "F" (Y/N) - JP Z,FILL ; FILL MEMORY COMMAND - LD HL,TXT_COMMAND ; POINT AT ERROR TEXT - CALL MSG ; PRINT COMMAND LABEL - - JR SERIALCMDLOOP - - - - - -;__KLOP_______________________________________________________________________ -; -; READ FROM THE SERIAL PORT AND ECHO, MONITOR COMMAND "K" -;_____________________________________________________________________________ -; -KLOP: - CALL KIN ; GET A KEY - CALL COUT ; OUTPUT KEY TO SCREEN - CP ESC ; IS ? - JR NZ,KLOP ; NO, LOOP - JP SERIALCMDLOOP ; - -;__GETLN______________________________________________________________________ -; -; READ A LINE(80) OF TEXT FROM THE SERIAL PORT, HANDLE , TERM ON -; EXIT IF TOO MANY CHARS STORE RESULT IN HL. CHAR COUNT IN C. -;_____________________________________________________________________________ -; -GETLN: - LD C,00H ; ZERO CHAR COUNTER - PUSH DE ; STORE DE -GETLNLOP: - CALL KIN ; GET A KEY - CALL COUT ; OUTPUT KEY TO SCREEN - CP CR ; IS ? - JR Z,GETLNDONE ; YES, EXIT - CP BS ; IS ? - JR NZ,GETLNSTORE ; NO, STORE CHAR - LD A,C ; A=C - CP 0 ; - JR Z,GETLNLOP ; NOTHING TO BACKSPACE, IGNORE & GET NEXT KEY - DEC HL ; PERFORM BACKSPACE - DEC C ; LOWER CHAR COUNTER - LD A,0 ; - LD (HL),A ; STORE NULL IN BUFFER - LD A,20H ; BLANK OUT CHAR ON TERM - CALL COUT ; - LD A,BS ; - CALL COUT ; - JR GETLNLOP ; GET NEXT KEY -GETLNSTORE: - LD (HL),A ; STORE CHAR IN BUFFER - INC HL ; INC POINTER - INC C ; INC CHAR COUNTER - LD A,C ; A=C - CP 4DH ; OUT OF BUFFER SPACE? - JR NZ,GETLNLOP ; NOPE, GET NEXT CHAR -GETLNDONE: - LD (HL),00H ; STORE NULL IN BUFFER - POP DE ; RESTORE DE - RET ; -; -;__KIN________________________________________________________________________ -; -; READ FROM THE SERIAL PORT AND ECHO & CONVERT INPUT TO UCASE -;_____________________________________________________________________________ -; -KIN: - CALL CIN - AND 7FH ; STRIP HI BIT - CP 'A' ; KEEP NUMBERS, CONTROLS - RET C ; AND UPPER CASE - CP 7BH ; SEE IF NOT LOWER CASE - RET NC - AND 5FH ; MAKE UPPER CASE - RET -; -;__CRLF_______________________________________________________________________ -; -; SEND CR & LF TO THE SERIAL PORT -;_____________________________________________________________________________ -; -CRLF: - PUSH HL ; PROTECT HL FROM OVERWRITE - LD HL,TCRLF ; LOAD MESSAGE POINTER - CALL MSG ; SEBD MESSAGE TO SERIAL PORT - POP HL ; PROTECT HL FROM OVERWRITE - RET ; - - -;__LDHL_______________________________________________________________________ -; -; GET ONE WORD OF HEX DATA FROM BUFFER POINTED TO BY HL SERIAL PORT, RETURN IN HL -;_____________________________________________________________________________ -; -LDHL: - PUSH DE ; STORE DE - CALL HEXIN ; GET K B. AND MAKE HEX - LD D,A ; THATS THE HI BYTE - CALL HEXIN ; DO HEX AGAIN - LD L,A ; THATS THE LOW BYTE - LD H,D ; MOVE TO HL - POP DE ; RESTORE BC - RET ; GO BACK WITH ADDRESS - - -;__HEXIN______________________________________________________________________ -; -; GET ONE BYTE OF HEX DATA FROM BUFFER IN HL, RETURN IN A -;_____________________________________________________________________________ -; -HEXIN: - PUSH BC ;SAVE BC REGS - CALL NIBL ;DO A NIBBLE - RLC A ;MOVE FIRST BYTE UPPER NIBBLE - RLC A ; - RLC A ; - RLC A ; - LD B,A ; SAVE ROTATED BYTE - CALL NIBL ; DO NEXT NIBBLE - ADD A,B ; COMBINE NIBBLES IN ACC - POP BC ; RESTORE BC - RET ; DONE -NIBL: - LD A,(HL) ; GET K B. DATA - INC HL ; INC KB POINTER - CP 40H ; TEST FOR ALPHA - JR NC,ALPH ; - AND 0FH ; GET THE BITS - RET ; -ALPH: - AND 0FH ; GET THE BITS - ADD A,09H ; MAKE IT HEX A-F - RET ; - - -;__HEXINS_____________________________________________________________________ -; -; GET ONE BYTE OF HEX DATA FROM SERIAL PORT, RETURN IN A -;_____________________________________________________________________________ -; -HEXINS: - PUSH BC ;SAVE BC REGS - CALL NIBLS ;DO A NIBBLE - RLC A ;MOVE FIRST BYTE UPPER NIBBLE - RLC A ; - RLC A ; - RLC A ; - LD B,A ; SAVE ROTATED BYTE - CALL NIBLS ; DO NEXT NIBBLE - ADD A,B ; COMBINE NIBBLES IN ACC - POP BC ; RESTORE BC - RET ; DONE -NIBLS: - CALL KIN ; GET K B. DATA - CP 40H ; TEST FOR ALPHA - JR NC,ALPH ; - AND 0FH ; GET THE BITS - RET ; - - -;__HXOUT______________________________________________________________________ -; -; PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT -;_____________________________________________________________________________ -; -HXOUT: - PUSH BC ; SAVE BC - LD B,A ; - RLC A ; DO HIGH NIBBLE FIRST - RLC A ; - RLC A ; - RLC A ; - AND 0FH ; ONLY THIS NOW - ADD A,30H ; TRY A NUMBER - CP 3AH ; TEST IT - JR C,OUT1 ; IF CY SET PRINT 'NUMBER' - ADD A,07H ; MAKE IT AN ALPHA -OUT1: - CALL COUT ; SCREEN IT - LD A,B ; NEXT NIBBLE - AND 0FH ; JUST THIS - ADD A,30H ; TRY A NUMBER - CP 3AH ; TEST IT - JR C,OUT2 ; PRINT 'NUMBER' - ADD A,07H ; MAKE IT ALPHA -OUT2: - CALL COUT ; SCREEN IT - POP BC ; RESTORE BC - RET ; - - -;__SPACE______________________________________________________________________ -; -; PRINT A SPACE CHARACTER ON THE SERIAL PORT -;_____________________________________________________________________________ -; -SPACE: - PUSH AF ; STORE AF - LD A,20H ; LOAD A "SPACE" - CALL COUT ; SCREEN IT - POP AF ; RESTORE AF - RET ; DONE - -;__PHL________________________________________________________________________ -; -; PRINT THE HL REG ON THE SERIAL PORT -;_____________________________________________________________________________ -; -PHL: - LD A,H ; GET HI BYTE - CALL HXOUT ; DO HEX OUT ROUTINE - LD A,L ; GET LOW BYTE - CALL HXOUT ; HEX IT - CALL SPACE ; - RET ; DONE - -;__POUT_______________________________________________________________________ -; -; OUTPUT TO AN I/O PORT, MONITOR COMMAND "O" -;_____________________________________________________________________________ -; -POUT: -POUT1: -; INC HL ; - CALL HEXIN ; GET PORT - LD C,A ; SAVE PORT POINTER - INC HL ; - CALL HEXIN ; GET DATA -OUTIT: - OUT (C),A ; - JP SERIALCMDLOOP ; - - -;__PIN________________________________________________________________________ -; -; INPUT FROM AN I/O PORT, MONITOR COMMAND "I" -;_____________________________________________________________________________ -; -PIN: -; INC HL ; - CALL HEXIN ; GET PORT - LD C,A ; SAVE PORT POINTER - CALL CRLF ; - IN A,(C) ; GET DATA - CALL HXOUT ; SHOW IT - JP SERIALCMDLOOP ; - - - - - -;__CRLFA______________________________________________________________________ -; -; PRINT COMMAND PROMPT TO THE SERIAL PORT -;_____________________________________________________________________________ -; -CRLFA: - PUSH HL ; PROTECT HL FROM OVERWRITE - LD HL,PROMPT ; - CALL MSG ; - POP HL ; PROTECT HL FROM OVERWRITE - RET ; DONE - - -;__MSG________________________________________________________________________ -; -; PRINT A STRING TO THE SERIAL PORT -;_____________________________________________________________________________ -; -MSG: - -TX_SERLP: - LD A,(HL) ; GET CHARACTER TO A - CP ENDT ; TEST FOR END BYTE - JP Z,TX_END ; JUMP IF END BYTE IS FOUND - CALL COUT ; - INC HL ; INC POINTER, TO NEXT CHAR - JP TX_SERLP ; TRANSMIT LOOP -TX_END: - RET ;ELSE DONE - -;__RUN________________________________________________________________________ -; -; TRANSFER OUT OF MONITOR, USER OPTION "R" -;_____________________________________________________________________________ -; -RUN: - INC HL ; SHOW READY - CALL LDHL ; GET START ADDRESS - JP (HL) ; - - -;__PROGRM_____________________________________________________________________ -; -; PROGRAM RAM LOCATIONS, USER OPTION "P" -;_____________________________________________________________________________ -; -PROGRM: - INC HL ; SHOW READY - PUSH HL ; STORE HL - CALL LDHL ; GET START ADDRESS - LD D,H ; - LD E,L ; DE POINTS TO ADDRESS TO PROGRAM - POP HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; -PROGRMLP: - CALL HEXIN ; GET NEXT HEX NUMBER - LD (DE),A ; STORE IT - INC DE ; NEXT ADDRESS; - CALL CRLFA ; CR,LF,> - LD A,'P' ; - CALL COUT ; - CALL SPACE ; - LD H,D ; - LD L,E ; - CALL PHL ; - LD HL,KEYBUF ; SET POINTER TO KEYBUF AREA - CALL GETLN ; GET A LINE OF INPUT FROM THE USER - LD HL,KEYBUF ; RESET POINTER TO START OF KEYBUF - LD A,(HL) ; LOAD FIRST CHAR INTO A - CP 00H ; END OF LINE? - JP Z,PROGRMEXIT ; YES, EXIT - JP PROGRMLP ; NO, LOOP -PROGRMEXIT: - JP SERIALCMDLOOP - - - - - - - -;__DUMP_______________________________________________________________________ -; -; PRINT A MEMORY DUMP, USER OPTION "D" -;_____________________________________________________________________________ -; -DUMP: - INC HL ; SHOW READY - PUSH HL ; STORE HL - CALL LDHL ; GET START ADDRESS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; SAVE START - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; - CALL LDHL ; GET END ADDRESS - INC HL ; ADD ONE MORE FOR LATER COMPARE - EX DE,HL ; PUT END ADDRESS IN DE - POP HL ; GET BACK START -GDATA: - CALL CRLF ; -BLKRD: - CALL PHL ; PRINT START LOCATION - LD C,16 ; SET FOR 16 LOCS - PUSH HL ; SAVE STARTING HL -NXTONE: - EXX ; - LD C,E ; - IN A,(C) ; - EXX ; - AND 7FH ; - CP ESC ; - JP Z,SERIALCMDLOOP ; - CP 19 ; - JR Z,NXTONE ; - LD A,(HL) ; GET BYTE - CALL HXOUT ; PRINT IT - CALL SPACE ; -UPDH: - INC HL ; POINT NEXT - DEC C ; DEC LOC COUNT - JR NZ,NXTONE ; IF LINE NOT DONE - ; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP -PCRLF: - CALL SPACE ; SPACE IT - LD C,16 ; SET FOR 16 CHARS - POP HL ; GET BACK START -PCRLF0: - LD A,(HL) ; GET BYTE - AND 060H ; SEE IF A 'DOT' - LD A,(HL) ; O K. TO GET - JR NZ,PDOT ; -DOT: - LD A,2EH ; LOAD A DOT -PDOT: - CALL COUT ; PRINT IT - INC HL ; - LD A,D ; - CP H ; - JR NZ,UPDH1 ; - LD A,E ; - CP L ; - JP Z,SERIALCMDLOOP ; -; -;IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE -UPDH1: - DEC C ; DEC CHAR COUNT - JR NZ,PCRLF0 ; DO NEXT -CONTD: - CALL CRLF ; - JP BLKRD ; - - -;__HXLOAD_____________________________________________________________________ -; -; LOAD INTEL HEX FORMAT FILE FROM THE SERIAL PORT, USER OPTION "H" -; -; [INTEL HEX FORMAT IS: -; 1) COLON (FRAME 0) -; 2) RECORD LENGTH FIELD (FRAMES 1 AND 2) -; 3) LOAD ADDRESS FIELD (FRAMES 3,4,5,6) -; 4) RECORD TYPE FIELD (FRAMES 7 AND 8) -; 5) DATA FIELD (FRAMES 9 TO 9+2*(RECORD LENGTH)-1 -; 6) CHECKSUM FIELD - SUM OF ALL BYTE VALUES FROM RECORD LENGTH TO AND -; INCLUDING CHECKSUM FIELD = 0 ] -; -; EXAMPLE OF INTEL HEX FORMAT FILE -; EACH LINE CONTAINS A CARRIAGE RETURN AS THE LAST CHARACTER -; :18F900002048454C4C4F20574F524C4420FF0D0AFF0D0A3EFF0D0A54BF -; :18F918006573742050726F746F7479706520524F4D204D6F6E69746FF1 -; :18F9300072205265616479200D0AFF0D0A434F4D4D414E4420524543F2 -; :18F948004549564544203AFF0D0A434845434B53554D204552524F52CD -; :16F96000FF0A0D20202D454E442D4F462D46494C452D20200A0DA4 -; :00000001FF -;_____________________________________________________________________________ -HXLOAD: - CALL CRLF ; SHOW READY -HXLOAD0: - CALL KIN ; GET THE FIRST CHARACTER, EXPECTING A ':' -HXLOAD1: - CP 03Ah ; IS IT COLON ':'? START OF LINE OF INTEL HEX FILE - JR NZ,HXLOADERR ; IF NOT, MUST BE ERROR, ABORT ROUTINE - LD E,0 ; FIRST TWO CHARACTERS IS THE RECORD LENGTH FIELD - CALL HEXINS ; GET US TWO CHARACTERS INTO BC, CONVERT IT TO A BYTE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD D,A ; LOAD RECORD LENGTH COUNT INTO D - CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD H,A ; PUT VALUE IN H REGISTER - CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD L,A ; PUT VALUE IN L REGISTER - CALL HEXINS ; GET NEXT TWO CHARACTERS, RECORD FIELD TYPE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - CP 001h ; RECORD FIELD TYPE 00 IS DATA, 01 IS END OF FILE - JR NZ,HXLOAD2 ; MUST BE THE END OF THAT FILE - CALL HEXINS ; GET NEXT TWO CHARACTERS, ASSEMBLE INTO BYTE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD A,E ; RECALL THE CHECKSUM BYTE - AND A ; IS IT ZERO? - JP Z,HXLOADEXIT ; MUST BE O K., GO BACK FOR SOME MORE, ELSE - JR HXLOADERR ; CHECKSUMS DON'T ADD UP, ERROR OUT -HXLOAD2: - LD A,D ; RETRIEVE LINE CHARACTER COUNTER - AND A ; ARE WE DONE WITH THIS LINE? - JR Z,HXLOAD3 ; GET TWO MORE ASCII CHARACTERS, BUILD A BYTE AND CHECKSUM - CALL HEXINS ; GET NEXT TWO CHARS, CONVERT TO BYTE IN A, CHECKSUM IT - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD (HL),A ; CHECKSUM OK, MOVE CONVERTED BYTE IN A TO MEMORY LOCATION - INC HL ; INCREMENT POINTER TO NEXT MEMORY LOCATION - DEC D ; DECREMENT LINE CHARACTER COUNTER - JR HXLOAD2 ; AND KEEP LOADING INTO MEMORY UNTIL LINE IS COMPLETE -HXLOAD3: - CALL HEXINS ; GET TWO CHARS, BUILD BYTE AND CHECKSUM - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD A,E ; CHECK THE CHECKSUM VALUE - AND A ; IS IT ZERO? - JR Z,HXLOADAGAIN ; IF THE CHECKSUM IS STILL OK, CONTINUE ON, ELSE -HXLOADERR: - LD HL,TXT_CKSUMERR ; GET "CHECKSUM ERROR" MESSAGE - CALL MSG ; PRINT MESSAGE FROM (HL) AND TERMINATE THE LOAD - JP HXLOADEXIT ; RETURN TO PROMPT -HXCHKSUM: - LD C,A ; BUILD THE CHECKSUM - LD A,E ; - SUB C ; THE CHECKSUM SHOULD ALWAYS .EQUAL ZERO WHEN CHECKED - LD E,A ; SAVE THE CHECKSUM BACK WHERE IT CAME FROM - LD A,C ; RETRIEVE THE BYTE AND GO BACK - RET ; BACK TO CALLER -HXLOADAGAIN: - CALL KIN ; CATCH THE TRAILING CARRIAGE RETURN - JP HXLOAD0 ; LOAD ANOTHER LINE OF DATA -HXLOADEXIT: - CALL KIN ; CATCH ANY STRAY TRAILING CHARACTERS - JP SERIALCMDLOOP ; RETURN TO PROMPT - - -;__MOVE_______________________________________________________________________ -; -; MOVE MEMORY, USER OPTION "M" -;_____________________________________________________________________________ -; -MOVE: - LD C,03 - ; START GETNM REPLACEMENT - ; GET SOURCE STARTING MEMORY LOCATION - INC HL ; SHOW EXAMINE READY - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - CALL LDHL ; LOAD IN HL REGS - PUSH HL ; PUSH MEMORY ADDRESS ON STACK - ; END GETNM REPLACEMENT - POP DE ; DEST - POP BC ; SOURCE END - POP HL ; SOURCE - PUSH HL ; - LD A,L ; - CPL ; - LD L,A ; - LD A,H ; - CPL ; - LD H,A ; - INC HL ; - ADD HL,BC ; - LD C,L ; - LD B,H ; - POP HL ; - CALL MOVE_LOOP ; - JP SERIALCMDLOOP ; EXIT MOVE COMMAND ROUTINE -MOVE_LOOP: - LD A,(HL) ; FETCH - LD (DE),A ; DEPOSIT - INC HL ; BUMP SOURCE - INC DE ; BUMP DEST - DEC BC ; DEC COUNT - LD A,C ; - OR B ; - JP NZ,MOVE_LOOP ; TIL COUNT=0 - RET ; - -;__FILL_______________________________________________________________________ -; -; FILL MEMORY, USER OPTION "M" -;_____________________________________________________________________________ -; -FILL: - LD C,03 ; - ; START GETNM REPLACEMENT - ; GET FILL STARTING MEMORY LOCATION - INC HL ; SHOW EXAMINE READY - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - ; GET FILL ENDING MEMORY LOCATION - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - ; GET TARGET STARTING MEMORY LOCATION - CALL HEXIN ; GET K B. AND MAKE HEX - LD C,A ; PUT FILL VALUE IN F SO IT IS SAVED FOR LATER - PUSH BC ; PUSH FILL VALUE BYTE ON STACK - ; END GETNM REPLACEMENT - POP BC ; BYTE - POP DE ; END - POP HL ; START - LD (HL),C ; -FILL_LOOP: - LD (HL),C ; - INC HL ; - LD A,E ; - SUB L ; - LD B,A ; - LD A,D ; - SUB H ; - OR B ; - JP NZ,FILL_LOOP ; - JP SERIALCMDLOOP ; - -;__GOCPM______________________________________________________________________ -; -; BOOT CP/M FROM ROM DRIVE, USER OPTION "C" -;_____________________________________________________________________________ -; -GOCPM: -;___________________________ -; REMOVE COMMENTS WHEN BURNED IN ROM -;___________________________ - -; LD A,000000000b ; RESET MPCL LATCH TO DEFAULT ROM -; OUT (MPCL),A ; -; LD HL,ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) -; LD DE,RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) -; LD BC,MOVSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM -; LDIR ; PERFORM BLOCK COPY OF CP/M TO UPPER RAM PAGE -; LD A,010000000b ; RESET MPCL LATCH TO DEFAULT CP/M WITH 64K SETTING -; OUT (MPCL),A ; - - JP CPM_ENT -; -;__FILL_MEM___________________________________________________________________ -; -; FUNCTION : FILL MEMORY WITH A VALUE -; INPUT : HL = START ADDRESS BLOCK -; : BC = LENGTH OF BLOCK -; : A = VALUE TO FILL WITH -; USES : DE, BC -; OUTPUT : -; CALLS : -; TESTED : 13 FEB 2007 -;_____________________________________________________________________________ -; -FILL_MEM: - LD E,L ; - LD D,H ; - INC DE ; - LD (HL),A ; INITIALISE FIRST BYTE OF BLOCK WITH DATA BYTE IN A - DEC BC ; - LDIR ; FILL MEMORY - RET ; RETURN TO CALLER - -; -;__INITIALIZE_________________________________________________________________ -; -; INITIALIZE SYSTEM -;_____________________________________________________________________________ -; -INITIALIZE: -; CALL CIOCON_DISP + (CF_INIT * 3) - RET -; - -;__MTERM_INIT_________________________________________________________________ -; -; SETUP 8255, MODE 0, PORT A=OUT, PORT B=IN, PORT C=OUT/OUT -; -;_____________________________________________________________________________ -MTERM_INIT: - LD A, 82H - OUT (PPIX),A - LD A, 30H ;set PC4,5 to disable PPISD (if used) - OUT (PPIC),A ;won't affect DSKY - RET - -;__KB_GET_____________________________________________________________________ -; -; GET A SINGLE KEY AND DECODE -; -;_____________________________________________________________________________ -KB_GET: - PUSH HL ; STORE HL -KB_GET_LOOP: ; WAIT FOR KEY - CALL KB_SCAN ; SCAN KB ONCE - CP 00H ; NULL? - JR Z,KB_GET_LOOP ; LOOP WHILE NOT ZERO - LD D,A ; STORE A - LD A,4FH | 30H ; SCAN ALL COL LINES - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE -KB_CLEAR_LOOP: ; WAIT FOR KEY TO CLEAR - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KB_CLEAR_LOOP ; YES, EXIT - LD A,D ; RESTORE A - LD D,00H ; - LD HL,KB_DECODE ; POINT TO BEGINNING OF TABLE -KB_GET_LLOOP: - CP (HL) ; MATCH? - JR Z,KB_GET_DONE ; FOUND, DONE - INC HL - INC D ; D + 1 - JP NZ,KB_GET_LLOOP ; NOT FOUND, LOOP UNTIL EOT -KB_GET_DONE: - LD A,D ; RESULT INTO A - POP HL ; RESTORE HL - RET -; -;__KB_SCAN____________________________________________________________________ -; -; SCAN KEYBOARD MATRIX FOR AN INPUT -; -;_____________________________________________________________________________ -; -KB_SCAN: - LD C,0000H - LD A,41H | 30H ; SCAN COL ONE - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,0040H - LD A,42H | 30H ; SCAN COL TWO - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,0080H - LD A,44H | 30H ; SCAN COL THREE - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,00C0H ; - LD A,48H | 30H ; SCAN COL FOUR - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD A, 40H | 30H ; TURN OFF ALL COLUMNS - OUT (PPIC),A ; SEND TO COLUMN LINES - LD A, 00H ; RETURN NULL - RET ; EXIT - -KB_SCAN_FOUND: - AND 3FH ; CLEAR TOP TWO BITS - OR C ; ADD IN ROW BITS - LD C,A ; STORE VALUE - LD A, 00H | 30H ; TURN OFF ALL COLUMNS - OUT (PPIC),A ; SEND TO COLUMN LINES - LD A,C ; RESTORE VALUE - RET - -PAUSE: -KB_SCAN_DELAY: - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - RET - - - -;__HEXDISPLAY_________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;_____________________________________________________________________________ -HEXDISPLAY: - PUSH HL ; STORE HL - PUSH AF ; STORE AF - PUSH BC ; STORE BC - LD BC,0007H - ADD HL,BC - LD B,08H ; SET DIGIT COUNT - LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF - OUT (PPIC),A ; OUTPUT - CALL PAUSE ; WAIT - LD A,0F0H ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - OUT (PPIA),A ; OUTPUT TO PORT - LD A,80H | 30H ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PPIC),A ; OUTPUT TO PORT - CALL PAUSE ; WAIT - LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF - OUT (PPIC),A ; OUTPUT -HEXDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - CALL DECODEDISPLAY ; DECODE DISPLAY - OUT (PPIA),A ; OUT TO PPIA - LD A,00H | 30H ; SET WRITE STROBE - OUT (PPIC),A ; OUT TO PPIC - CALL PAUSE ; DELAY - LD A,40H | 30H ; SET CONTROL PORT OFF - OUT (PPIC),A ; OUT TO PPIC - CALL PAUSE ; WAIT - DEC HL ; INC POINTER - DJNZ HEXDISPLAY_LP ; LOOP FOR NEXT DIGIT - POP BC ; RESTORE BC - POP AF ; RESTORE AF - POP HL ; RESTORE HL - RET - -;__DECODEDISPLAY______________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;_____________________________________________________________________________ -DECODEDISPLAY: - PUSH BC ; STORE BC - PUSH HL ; STORE HL - LD HL,SEGDECODE ; POINT HL TO DECODE TABLE - LD B,00H ; RESET HIGH BYTE - LD C,A ; CHAR INTO LOW BYTE - ADD HL,BC ; SET TABLE POINTER - LD A,(HL) ; GET VALUE - POP HL ; RESTORE HL - POP BC ; RESTORE BC - RET - - -;__SEGDISPLAY_________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;_____________________________________________________________________________ -SEGDISPLAY: - PUSH AF ; STORE AF - PUSH BC ; STORE BC - LD BC,0007H - ADD HL,BC - LD B,08H ; SET DIGIT COUNT - LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF - OUT (PPIC),A ; OUTPUT - CALL PAUSE ; WAIT - LD A,0F0H ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - OUT (PPIA),A ; OUTPUT TO PORT - LD A,80H | 30H ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PPIC),A ; OUTPUT TO PORT - CALL PAUSE ; WAIT - LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF - OUT (PPIC),A ; OUTPUT -SEGDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - OUT (PPIA),A ; OUT TO PPIA - LD A,00H | 30H ; SET WRITE STROBE - OUT (PPIC),A ; OUT TO PPIC - CALL PAUSE ; DELAY - LD A,40H | 30H ; SET CONTROL PORT OFF - OUT (PPIC),A ; OUT TO PPIC - CALL PAUSE ; WAIT - DEC HL ; INC POINTER - DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - POP BC ; RESTORE BC - POP AF ; RESTORE AF - RET - -; -;__WORK_AREA__________________________________________________________________ -; -; RESERVED RAM FOR MONITOR WORKING AREA -;_____________________________________________________________________________ -; -KEYBUF: .FILL 80,' ' -DISPLAYBUF: .FILL 8,0 -; -;__TEXT_STRINGS_______________________________________________________________ -; -; SYSTEM TEXT STRINGS -;_____________________________________________________________________________ -; -TCRLF: - .DB CR,LF,ENDT - -PROMPT: - .DB CR,LF,'>',ENDT - -TXT_READY: - .DB CR,LF - .TEXT " NN NN 8888 VV VV EEEEEEEEEE MM MM" - .DB CR,LF - .TEXT " NNNN NN 88 88 VV VV EE MMMM MMMM" - .DB CR,LF - .TEXT " NN NN NN 88 88 VV VV EE MM MM MM MM" - .DB CR,LF - .TEXT " NN NNNN 88 88 VV VV EE MM MM MM" - .DB CR,LF - .TEXT " NN NN 8888 VV VV EEEEEEE MM MM" - .DB CR,LF - .TEXT " NN NN 88 88 VV VV EE MM MM" - .DB CR,LF - .TEXT " NN NN 88 88 VV VV EE MM MM" - .DB CR,LF - .TEXT " NN NN 88 88 VVV EE MM MM" - .DB CR,LF - .TEXT " NN NN 8888 V EEEEEEEEEE MM MM S B C" - .DB CR,LF - .DB CR,LF - .TEXT " ****************************************************************************" - .DB CR,LF - .TEXT "MONITOR READY " - .DB CR,LF,ENDT - -TXT_COMMAND: - .DB CR,LF - .TEXT "UNKNOWN COMMAND." - .DB ENDT - -TXT_CKSUMERR: - .DB CR,LF - .TEXT "CHECKSUM ERROR." - .DB ENDT -CPUUP: - .DB 084H,0EEH,0BBH,080H,0BBH,0EEH,0CBH,084H -ADDR: - .DB 00H,00H,00H,00H,08CH,0BDH,0BDH,0FEH - - -PORT: - .DB 00H,00H,80H,80H,094H,08CH,09DH,0EEH -SEC: - .DB 80H,80H,80H,80H,80H,0CBH,0CFH,0D7H - - -;_KB DECODE TABLE_____________________________________________________________ -; -; -KB_DECODE: -; 0 1 2 3 4 5 6 7 8 9 A B C D E F - .DB 41H,02H,42H,82H,04H,44H,84H,08H,48H,88H,10H,50H,90H,20H,60H,0A0H -; FW BK CL EN DP EX GO BO - .DB 01H,81H,0C1H,0C2H,0C4H,0C8H,0D0H,0E0H -; -; F-KEYS, -; FW = FORWARD -; BK = BACKWARD -; CL = CLEAR -; EN = ENTER -; DP = DEPOSIT (INTO MEM) -; EX = EXAMINE (MEM) -; GO = GO -; BO = BOOT -;_____________________________________________________________________________ -;_HEX 7_SEG_DECODE_TABLE______________________________________________________ -; -; 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, ,- -; AND WITH 7FH TO TURN ON DP -;_____________________________________________________________________________ -SEGDECODE: - .DB 0FBH,0B0H,0EDH,0F5H,0B6H,0D7H,0DFH,0F0H,0FFH,0F7H,0FEH,09FH - .DB 0CBH,0BDH,0CFH,0CEH,080H,084H,00H,0EEH,09DH - -;********************* END OF PROGRAM *********************************** -; -SLACK .EQU (MON_END - $) - .FILL SLACK,00H -; -MON_STACK .EQU $ -; - .ECHO "DBGMON space remaining: " - .ECHO SLACK - .ECHO " bytes.\n" - - .END diff --git a/branches/s100/Source/diskdefs b/branches/s100/Source/diskdefs deleted file mode 100644 index 2e1f5725..00000000 --- a/branches/s100/Source/diskdefs +++ /dev/null @@ -1,341 +0,0 @@ -diskdef ibm-3740 - seclen 128 - tracks 77 - sectrk 26 - blocksize 1024 - maxdir 64 - skew 6 - boottrk 2 - os p2dos -end - -diskdef 4mb-hd - seclen 128 - tracks 1024 - sectrk 32 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 0 - os p2dos -end - -diskdef pcw - seclen 512 - tracks 40 - sectrk 9 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 1 - os 3 -end - -diskdef pc1.2m - seclen 512 - tracks 80 - # this format uses 15 sectors per track, but 30 per cylinder - sectrk 30 - blocksize 4096 - maxdir 256 - skew 1 - boottrk 0 - os 3 -end - -# CP/M 86 on 1.44MB floppies -diskdef cpm86-144feat - seclen 512 - tracks 160 - sectrk 18 - blocksize 4096 - maxdir 256 - skew 1 - boottrk 2 - os 3 -end - -diskdef cf2dd - seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 1 - os 3 -end - -#amstrad: values are read from super block (special name hardcoded) - -# Royal alphatronic -# setfdprm /dev/fd1 dd ssize=256 cyl=40 sect=16 head=2 -diskdef alpha - seclen 256 - tracks 40 - sectrk 32 - blocksize 2048 - maxdir 128 - skew 1 - boottrk 2 - os 2.2 -end - -# Apple II CP/M skew o Apple II DOS 3.3 skew -diskdef apple-do - seclen 256 - tracks 35 - sectrk 16 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 3 - os 2.2 -end - -# Apple II CP/M skew o Apple II PRODOS skew -diskdef apple-po - seclen 256 - tracks 35 - sectrk 16 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 3 - os 2.2 -end - -# MYZ80 hard drive (only works with libdsk, because it has a 256-byte header) -diskdef myz80 - seclen 1024 - tracks 64 - sectrk 128 - blocksize 4096 - maxdir 1024 - skew 1 - boottrk 0 - os 3 -end - -# Despite being Amstrad formats, CPC System and CPC Data don't have an Amstrad -# superblock. You'll need to use libdsk to access them because the Linux -# and Windows kernel drivers won't touch them. -diskdef cpcsys - seclen 512 - tracks 40 - sectrk 9 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 2 - os 3 -end -diskdef cpcdata - seclen 512 - tracks 40 - sectrk 9 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 0 - os 3 -end - -# after being read in with no sector skew. -diskdef nigdos - seclen 512 - # NigDos double sided disk format, 42 tracks * 2 sides - tracks 84 - sectrk 10 - blocksize 2048 - maxdir 128 - skew 1 - boottrk 0 - # this format wastes half of the directory entry - logicalextents 1 - os 3 -end - -diskdef epsqx10 - seclen 512 - tracks 40 - sectrk 20 - blocksize 2048 - maxdir 128 - skew 0 - boottrk 2 - os 2.2 -end - -diskdef ibm-8ss - seclen 512 - tracks 40 - sectrk 8 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 1 - os 2.2 -end - -diskdef ibm-8ds - seclen 512 - tracks 40 - sectrk 8 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 1 - os 2.2 -end - -diskdef electroglas - seclen 512 - tracks 80 - sectrk 10 - blocksize 2048 - maxdir 256 - skew 0 - boottrk 1 - os 3 -end - -# IBM CP/M-86 -# setfdprm /dev/fd1 sect=8 dtr=1 hd ssize=512 tpi=48 head=1 -diskdef ibmpc-514ss - seclen 512 - tracks 40 - sectrk 8 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 1 - os 2.2 -end - -# IBM CP/M-86 -# setfdprm /dev/fd1 sect=8 dtr=1 hd ssize=512 tpi=48 -diskdef ibmpc-514ds - seclen 512 - tracks 80 - sectrk 8 - blocksize 2048 - maxdir 64 - skew 0 - boottrk 2 - os 2.2 -end - -diskdef p112 - seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 2 - os 3 -end - -diskdef p112-old - seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 128 - skew 1 - boottrk 1 - os 3 -end - -diskdef kpii - seclen 512 - tracks 40 - sectrk 10 - blocksize 1024 - maxdir 32 - skew 0 - boottrk 1 - os 2.2 -end - -# setfdprm /dev/fd0 dd sect=10 -diskdef interak - seclen 512 - tracks 80 - sectrk 20 - blocksize 4096 - maxdir 256 - skew 1 - boottrk 2 - os 2.2 -end - -# For 512KB ROM, less 32K for system image -diskdef rom512KB - seclen 128 - tracks 14 - sectrk 256 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 0 - os 2.2 -end - -# For 1024KB ROM, less 32K for system image -diskdef rom1024KB - seclen 128 - tracks 30 - sectrk 256 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 0 - os 2.2 -end - -# For N8VEM mass storage (4 raw partitions) -diskdef hd0 - seclen 512 - tracks 65 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 1 - os 2.2 -end - -diskdef hd1 - seclen 512 - tracks 130 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 66 - os 2.2 -end - -diskdef hd2 - seclen 512 - tracks 195 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 131 - os 2.2 -end - -diskdef hd3 - seclen 512 - tracks 260 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 196 - os 2.2 -end diff --git a/branches/s100/Source/fd.asm b/branches/s100/Source/fd.asm deleted file mode 100644 index cbac6890..00000000 --- a/branches/s100/Source/fd.asm +++ /dev/null @@ -1,1640 +0,0 @@ -; -;================================================================================================== -; FLOPPY DISK DRIVER -;================================================================================================== -; -; TODO: -; -; -; PORTS -; -#IF ((FDMODE == FDMODE_DIO) | (FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3)) -FDC_MSR: .EQU 036H ; 8272 MAIN STATUS REGISTER -FDC_DATA: .EQU 037H ; 8272 DATA PORT -FDC_DIR: .EQU 038H ; DATA INPUT REGISTER -FDC_DOR: .EQU 03AH ; DIGITAL OUTPUT REGISTER (LATCH) -FDC_DMA: .EQU 03CH ; PSEUDO DMA DATA PORT -#ENDIF -#IF (FDMODE == FDMODE_DIDE) -FDC_BID: .EQU 00100000B ; IO RANGE 20H-3FH -FDC_MSR: .EQU FDC_BID | 01010B ; 8272 MAIN STATUS REGISTER -FDC_DATA: .EQU FDC_BID | 01011B ; 8272 DATA PORT -FDC_DOR: .EQU FDC_BID | 01100B ; DOR -FDC_DCR: .EQU FDC_BID | 01101B ; DCR -FDC_DACK: .EQU FDC_BID | 11100B ; DACK -FDC_TC .EQU FDC_BID | 11101B ; TERMINAL COUNT (W/ DACK) -FDC_DMA: .EQU 03CH ; NOT USED BY DIDE -#ENDIF -#IF (FDMODE == FDMODE_N8) -FDC_MSR: .EQU 08CH ; 8272 MAIN STATUS REGISTER -FDC_DATA: .EQU 08DH ; 8272 DATA PORT -FDC_DOR: .EQU 092H ; DOR -FDC_DCR: .EQU 091H ; DCR -FDC_DACK: .EQU 090H ; DACK -FDC_TC .EQU 093H ; TERMINAL COUNT (W/ DACK) -FDC_DMA: .EQU 03CH ; NOT USED BY N8 -#ENDIF -; -; FDC RESULT CODES -; -FRC_OK .EQU 0 ; 00 -FRC_NOTIMPL .EQU -01H ; FF -FRC_CMDERR .EQU -02H ; FE -FRC_ERROR .EQU -03H ; FD -FRC_ABORT .EQU -04H ; FC -FRC_BUFMAX .EQU -05H ; FB -FRC_ABTERM .EQU -08H ; F8 -FRC_INVCMD .EQU -09H ; F7 -FRC_DSKCHG .EQU -0AH ; F6 -FRC_ENDCYL .EQU -0BH ; F5 -FRC_DATAERR .EQU -0CH ; F4 -FRC_OVERRUN .EQU -0DH ; F3 -FRC_NODATA .EQU -0EH ; F2 -FRC_NOTWRIT .EQU -0FH ; F1 -FRC_MISADR .EQU -10H ; F0 -FRC_TOFDCRDY .EQU -11H ; EF -FRC_TOSNDCMD .EQU -12H ; EE -FRC_TOGETRES .EQU -13H ; ED -FRC_TOEXEC .EQU -14H ; EC -FRC_TOSEEKWT .EQU -15H ; EB -; -#IF (FDTRACE > 0) -; -; FDC STATUS CODE STRINGS -; -FSS_OK .TEXT "OK$" -FSS_NOTIMPL .TEXT "NOT IMPLEMENTED$" -FSS_CMDERR .TEXT "COMMAND ERROR$" -FSS_ERROR .TEXT "ERROR$" -FSS_ABORT .TEXT "ABORT$" -FSS_BUFMAX .TEXT "BUFFER EXCEEDED$" -FSS_ABTERM .TEXT "ABNORMAL TERMINATION$" -FSS_INVCMD .TEXT "INVALID COMMAND$" -FSS_DSKCHG .TEXT "DISK CHANGE$" -FSS_ENDCYL .TEXT "END OF CYLINDER$" -FSS_DATAERR .TEXT "DATA ERROR$" -FSS_OVERRUN .TEXT "OVERRUN$" -FSS_NODATA .TEXT "NO DATA$" -FSS_NOTWRIT .TEXT "NOT WRITABLE$" -FSS_MISADR .TEXT "MISSING ADDRESS MARK$" -FSS_TOFDCRDY .TEXT "FDC READY TIMEOUT$" -FSS_TOSNDCMD .TEXT "SENDCMD TIMEOUT$" -FSS_TOGETRES .TEXT "GET RESULTS TIMEOUT$" -FSS_TOEXEC .TEXT "EXEC TIMEOUT$" -FSS_TOSEEKWT .TEXT "SEEK WAIT TIMEOUT$" -; -; FDC STATUS STRING TABLE -; -FSST: .DB FRC_OK \ .DW FSS_OK -FSST_ENTSIZ .EQU $ - FSST - .DB FRC_NOTIMPL \ .DW FSS_NOTIMPL - .DB FRC_CMDERR \ .DW FSS_CMDERR - .DB FRC_ERROR \ .DW FSS_ERROR - .DB FRC_ABORT \ .DW FSS_ABORT - .DB FRC_BUFMAX \ .DW FSS_BUFMAX - .DB FRC_ABTERM \ .DW FSS_ABTERM - .DB FRC_INVCMD \ .DW FSS_INVCMD - .DB FRC_DSKCHG \ .DW FSS_DSKCHG - .DB FRC_ENDCYL \ .DW FSS_ENDCYL - .DB FRC_DATAERR \ .DW FSS_DATAERR - .DB FRC_OVERRUN \ .DW FSS_OVERRUN - .DB FRC_NODATA \ .DW FSS_NODATA - .DB FRC_NOTWRIT \ .DW FSS_NOTWRIT - .DB FRC_MISADR \ .DW FSS_MISADR - .DB FRC_TOFDCRDY \ .DW FSS_TOFDCRDY - .DB FRC_TOSNDCMD \ .DW FSS_TOSNDCMD - .DB FRC_TOGETRES \ .DW FSS_TOGETRES - .DB FRC_TOEXEC \ .DW FSS_TOEXEC - .DB FRC_TOSEEKWT \ .DW FSS_TOSEEKWT -FSST_COUNT .EQU (($ - FSST) / FSST_ENTSIZ) ; # ENTRIES IN TABLE -#ENDIF -; -; FDC COMMANDS -; -CMD_READ .EQU 00000110B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,DTL --> ST0,ST1,ST2,C,H,R,N -CMD_READDEL .EQU 00001100B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,DTL --> ST0,ST1,ST2,C,H,R,N -CMD_WRITE .EQU 00000101B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,DTL --> ST0,ST1,ST2,C,H,R,N -CMD_WRITEDEL .EQU 00001001B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,DTL --> ST0,ST1,ST2,C,H,R,N -CMD_READTRK .EQU 00000010B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,DTL --> ST0,ST1,ST2,C,H,R,N -CMD_READID .EQU 00001010B ; CMD,HDS/DS --> ST0,ST1,ST2,C,H,R,N -CMD_FMTTRK .EQU 00001101B ; CMD,HDS/DS,N,SC,GPL,D --> ST0,ST1,ST2,C,H,R,N -CMD_SCANEQ .EQU 00010001B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,STP --> ST0,ST1,ST2,C,H,R,N -CMD_SCANLOEQ .EQU 00011001B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,STP --> ST0,ST1,ST2,C,H,R,N -CMD_SCANHIEQ .EQU 00011101B ; CMD,HDS/DS,C,H,R,N,EOT,GPL,STP --> ST0,ST1,ST2,C,H,R,N -CMD_RECAL .EQU 00000111B ; CMD,DS --> -CMD_SENSEINT .EQU 00001000B ; CMD --> ST0,PCN -CMD_SPECIFY .EQU 00000011B ; CMD,SRT/HUT,HLT/ND --> -CMD_DRVSTAT .EQU 00000100B ; CMD,HDS/DS --> ST3 -CMD_SEEK .EQU 00001111B ; CMD,HDS/DS --> -CMD_VERSION .EQU 00010000B ; CMD --> ST0 -; -; STATIC CONFIGURATION, NEVER CHANGES (PRIVATE) -; -FCD_MT .EQU 000H ; MULTI-TRACK, WE DON'T USE, SET TO 0 -FCD_MFM .EQU 001H ; MFM, 0=FM, 1=MFM, WE USE MFM ALWAYS -FCD_SK .EQU 000H ; SKIP MODE, WE DON'T USE, SET TO 0 -FCD_N .EQU 002H ; SECTOR SIZE, N=2 FOR 512 BYTES -FCD_DTL .EQU 0FFH ; DATA LENGTH (WHEN N=0, SET TO FF OTHERWISE) -FCD_STP .EQU 001H ; SECTOR SCAN TYPE, 1=CONTIG, 2=ALTERNATING -; -FCD_PC720 .DB 050H ; NUMBER OF CYLINDERS - .DB 002H ; NUMBER OF HEADS - .DB 009H ; NUMBER OF SECTORS - .DB 001H ; START OF TRACK (ID OF FIRST SECTOR, USUALLY 1) - .DB 009H ; SECTOR COUNT - .DW 200H ; SECTOR SIZE IN BYTES - .DB 02AH ; GAP LENGTH (R/W) - .DB 050H ; GAP LENGTH (FORMAT) - .DB 0DFH ; SRT/HUT: STEP RATE, IBM PS/2 CALLS FOR 3ms, 0DH = 3ms SRT, HEAD UNLOAD TIME - .DB 005H ; HLT/ND: HEAD LOAD TIME, IBM PS/2 CALLS FOR 15ms 08H = 16ms HUT - .DB DOR_BR250 ; DOR - .DB DCR_BR250 ; DCR - .IF (($ - FCD_PC720) != FCD_LEN) - .ECHO "*** FCD_PC720 SIZE ERROR!!! ***\n" - .ENDIF -; -FCD_PC144 .DB 050H ; NUMBER OF CYLINDERS - .DB 002H ; NUMBER OF HEADS - .DB 012H ; NUMBER OF SECTORS - .DB 001H ; START OF TRACK (ID OF FIRST SECTOR, USUALLY 1) - .DB 012H ; SECTOR COUNT - .DW 200H ; SECTOR SIZE IN BYTES - .DB 01BH ; GAP LENGTH (R/W) - .DB 06CH ; GAP LENGTH (FORMAT) - .DB 0DFH ; SRT/HUT: STEP RATE, IBM PS/2 CALLS FOR 3ms, 0DH = 3ms SRT, HEAD UNLOAD TIME - .DB 009H ; HLT/ND: HEAD LOAD TIME, IBM PS/2 CALLS FOR 15ms 08H = 16ms HUT - .DB DOR_BR500 ; DOR - .DB DCR_BR500 ; DCR - .IF (($ - FCD_PC144) != FCD_LEN) - .ECHO "*** FCD_PC144 SIZE ERROR!!! ***\n" - .ENDIF -; -FCD_PC360 .DB 028H ; NUMBER OF CYLINDERS - .DB 002H ; NUMBER OF HEADS - .DB 009H ; NUMBER OF SECTORS - .DB 001H ; START OF TRACK (ID OF FIRST SECTOR, USUALLY 1) - .DB 009H ; SECTOR COUNT - .DW 200H ; SECTOR SIZE IN BYTES - .DB 02AH ; GAP LENGTH (R/W) - .DB 050H ; GAP LENGTH (FORMAT) - .DB 0DFH ; SRT/HUT: STEP RATE, IBM PS/2 CALLS FOR 3ms, 0DH = 3ms SRT, HEAD UNLOAD TIME - .DB 005H ; HLT/ND: HEAD LOAD TIME, IBM PS/2 CALLS FOR 15ms 08H = 16ms HUT - .DB DOR_BR250 ; DOR - .DB DCR_BR250 ; DCR - .IF (($ - FCD_PC360) != FCD_LEN) - .ECHO "*** FCD_PC360 SIZE ERROR!!! ***\n" - .ENDIF -; -FCD_PC120 .DB 050H ; NUMBER OF CYLINDERS - .DB 002H ; NUMBER OF HEADS - .DB 00FH ; NUMBER OF SECTORS - .DB 001H ; START OF TRACK (ID OF FIRST SECTOR, USUALLY 1) - .DB 00FH ; SECTOR COUNT - .DW 200H ; SECTOR SIZE IN BYTES - .DB 01BH ; GAP LENGTH (R/W) - .DB 054H ; GAP LENGTH (FORMAT) - .DB 0DFH ; SRT/HUT: STEP RATE, IBM PS/2 CALLS FOR 3ms, 0DH = 3ms SRT, HEAD UNLOAD TIME - .DB 009H ; HLT/ND: HEAD LOAD TIME, IBM PS/2 CALLS FOR 15ms 08H = 16ms HUT - .DB DOR_BR500 ; DOR - .DB DCR_BR500 ; DCR - .IF (($ - FCD_PC120) != FCD_LEN) - .ECHO "*** FCD_PC120 SIZE ERROR!!! ***\n" - .ENDIF -; -FCD_PC111 .DB 04AH ; NUMBER OF CYLINDERS - .DB 002H ; NUMBER OF HEADS - .DB 00FH ; NUMBER OF SECTORS - .DB 001H ; START OF TRACK (ID OF FIRST SECTOR, USUALLY 1) - .DB 00FH ; SECTOR COUNT - .DW 200H ; SECTOR SIZE IN BYTES - .DB 01BH ; GAP LENGTH (R/W) - .DB 054H ; GAP LENGTH (FORMAT) - .DB 0DFH ; SRT/HUT: STEP RATE, IBM PS/2 CALLS FOR 3ms, 0DH = 3ms SRT, HEAD UNLOAD TIME - .DB 009H ; HLT/ND: HEAD LOAD TIME, IBM PS/2 CALLS FOR 15ms 08H = 16ms HUT - .DB DOR_BR500 ; DOR - .DB DCR_BR500 ; DCR - .IF (($ - FCD_PC111) != FCD_LEN) - .ECHO "*** FCD_PC111 SIZE ERROR!!! ***\n" - .ENDIF -; -; FCD LOOKUP TABLE (CALLED TO SET HL TO ADDRESS OF MEDIA DATA ABOVE) -; ENTRIES BELOW MUST MATCH COUNT AND VALUES OF FDMXXX IN STD.ASM -; -FCD_TBL: - LD HL,FCD_PC720 \ RET ; FDM720 = 0 - LD HL,FCD_PC144 \ RET ; FDM144 = 1 - LD HL,FCD_PC360 \ RET ; FDM360 = 2 - LD HL,FCD_PC120 \ RET ; FDM120 = 3 - LD HL,FCD_PC111 \ RET ; FDM111 = 4 -; -; DOR BITS (3AH) -; -; DISKIO 250KBPS 500KBPS -; ------- ------- ------- -;D7 /DC/RDY 1 (N/A) 1 (N/A) -;D6 /REDWC (DENSITY) 0 (DD) 1 (HD) -;D5 P0* (PRECOMP BIT 0) 1 \ 0 \ -;D4 P1* (PRECOMP BIT 1) 0 (125NS) 1 (125NS) -;D3 P2* (PRECOMP BIT 2) 0 / 0 / -;D2 MINI (BITRATE) 1 (250KBPS) 0 (500KBPS) -;D1 /MOTOR (ACTIVE LO) 1 (OFF) 1 (OFF) -;D0 TC (TERMINAL COUNT) 0 (OFF) 0 (OFF) -; -; *NOTE: FOR 9229 DATA SEPARATOR USED IN DISKIO, VALUE OF PRECOMP BITS CHANGES WITH MINI -; IF MINI=1 (250KBPS), USE 001 FOR 125NS PRECOMP, IF MINI=0, USE 010 FOR 125NS PRECOMP -; -#IF (FDMODE == FDMODE_DIO) -DOR_BR250 .EQU 10100100B ; 250KBPS W/ MOTOR ON -DOR_BR500 .EQU 11010000B ; 500KBPS W/ MOTOR ON -DOR_INIT .EQU 11010010B ; INITIAL DEFAULT LATCH VALUE -#ENDIF -; -; ZETA/DISKIO3 250KBPS 500KBPS -; ------------ ------- ------- -;D7 /FDC_RST 1 (RUN) 1 (RUN) -;D6 DENSEL 1 (DD) 0 (HD) -;D5 P0 (PRECOMP BIT 0) 1 \ 1 \ -;D4 P1 (PRECOMP BIT 1) 0 (125NS) 0 (125NS) -;D3 P2 (PRECOMP BIT 2) 0 / 0 / -;D2 MINI (BITRATE) 1 (250KBPS) 0 (500KBPS) -;D1 MOTOR 0 (OFF) 0 (OFF) -;D0 TC 0 (OFF) 0 (OFF) -; -; MOTOR AND DENSITY SELECT ARE INVERTED ON ZETA/DISKIO3 -; -#IF ((FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3)) -DOR_BR250 .EQU 11100110B ; 250KBPS W/ MOTOR ON -DOR_BR500 .EQU 10100010B ; 500KBPS W/ MOTOR ON -DOR_INIT .EQU 10100000B ; INITIAL DEFAULT LATCH VALUE -#ENDIF -; -; *** DIDE/N8 *** -; -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8)) -DOR_INIT .EQU 00001100B ; SOFT RESET INACTIVE, DMA ENABLED -DOR_BR250 .EQU DOR_INIT -DOR_BR500 .EQU DOR_INIT -#ENDIF -; -; DCR (ONLY APPLIES TO DIDE AND N8) -; -DCR_BR250 .EQU 01H ; 250KBPS -DCR_BR500 .EQU 00H ; 500KBPS -; -#IF (FDTRACE > 0) -; -; FDC COMMAND STRINGS -; -FCS_NOP: .TEXT "NOP$" -FCS_READ: .TEXT "READ$" -FCS_READDEL: .TEXT "READDEL$" -FCS_WRITE: .TEXT "WRITE$" -FCS_WRITEDEL: .TEXT "WRITEDEL$" -FCS_READTRK: .TEXT "READTRK$" -FCS_READID: .TEXT "READID$" -FCS_FMTTRK: .TEXT "FMTTRK$" -FCS_SCANEQ: .TEXT "SCANEQ$" -FCS_SCANLOEQ: .TEXT "SCANLOEQ$" -FCS_SCANHIEQ: .TEXT "SCANHIEQ$" -FCS_RECAL: .TEXT "RECAL$" -FCS_SENSEINT: .TEXT "SENSEINT$" -FCS_SPECIFY: .TEXT "SPECIFY$" -FCS_DRVSTAT: .TEXT "DRVSTAT$" -FCS_SEEK: .TEXT "SEEK$" -FCS_VERSION: .TEXT "VER$" -; -; FDC COMMAND TABLE -; -FCT .DB CMD_READ \ .DW FCS_READ -FCT_ENTSIZ .EQU $ - FCT - .DB CMD_READDEL \ .DW FCS_READDEL - .DB CMD_WRITE \ .DW FCS_WRITE - .DB CMD_WRITEDEL \ .DW FCS_WRITEDEL - .DB CMD_READTRK \ .DW FCS_READTRK - .DB CMD_READID \ .DW FCS_READID - .DB CMD_FMTTRK \ .DW FCS_FMTTRK - .DB CMD_SCANEQ \ .DW FCS_SCANEQ - .DB CMD_SCANLOEQ \ .DW FCS_SCANLOEQ - .DB CMD_SCANHIEQ \ .DW FCS_SCANHIEQ - .DB CMD_RECAL \ .DW FCS_RECAL - .DB CMD_SENSEINT \ .DW FCS_SENSEINT - .DB CMD_SPECIFY \ .DW FCS_SPECIFY - .DB CMD_DRVSTAT \ .DW FCS_DRVSTAT - .DB CMD_SEEK \ .DW FCS_SEEK - .DB CMD_VERSION \ .DW FCS_VERSION -FCT_COUNT .EQU (($ - FCT) / FCT_ENTSIZ) ; # ENTRIES IN TABLE -#ENDIF -; -; -; -FD_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JR Z,FD_RD - DEC A - JR Z,FD_WR - DEC A - JR Z,FD_ST - DEC A - JR Z,FD_MED - CALL PANIC -; -FD_RD: - JP FD_READ -FD_WR: - JP FD_WRITE -FD_ST: - JP FD_STATUS -FD_MED: - JP FD_MEDIA -; -; FD_MEDIA -; -FD_MEDIA: - CALL FD_SELECTUNIT - -#IF (FDMAUTO) - ; SETUP TO READ TRK 0, HD 0, SEC 0 - LD A,C ; C STILL HAS REQUESTED DRIVE - AND 0FH - LD (FCD_DS),A - LD A,0 - LD (FCD_C),A - LD (FCD_H),A - INC A - LD (FCD_R),A - LD A,DOP_READID - LD (FCD_DOP),A - -#IF (FDTRACE < 3) - ; SUPPRESS TRACING FOR MEDIA TESTS - LD A,0 - LD (FCD_TRACE),A -#ENDIF - - LD B,5 - -FD_MEDIARETRY: - ; TRY PRIMARY MEDIA CHOICE FIRST - LD A,FDMEDIA - CALL FD_TESTMEDIA - JR Z,FD_MEDIA3 ; IF SUCCESS, WE ARE DONE - - ; TRY ALTERNATE MEDIA CHOICE - LD A,FDMEDIAALT - CALL FD_TESTMEDIA - JR Z,FD_MEDIA3 ; IF SUCCESS, WE ARE DONE - - DJNZ FD_MEDIARETRY - - ; NO JOY, RETURN WITH A=0 (NO MEDIA) - XOR A - RET - -FD_TESTMEDIA: - LD HL,(FDDS_MEDIAADR) - LD (HL),A - PUSH BC - CALL FD_START - POP BC - RET - -FD_MEDIA3: - -#IF (FDTRACE < 3) - ; RESTORE TRACING FOR MEDIA TESTS - LD A,FDTRACE - LD (FCD_TRACE),A -#ENDIF -#ENDIF - -#IF (FDTRACE >= 3) - LD DE,FDSTR_SELECT - CALL WRITESTR - LD BC,(FDDS_MEDIAADR) - CALL PRTHEXWORD -#ENDIF - - ; LOAD THE MEDIA BYTE - LD HL,(FDDS_MEDIAADR) - LD A,(HL) - ADD A,MID_FD720 ; ASSUMES MID_ VALUES ARE IN SAME ORDER AS FDM VALUES - -#IF (FDTRACE >= 3) - CALL PC_SPACE - CALL PRTHEXBYTE -#ENDIF - RET -; -; FD_INIT -; -FD_INIT: - PRTS("FD: IO=0x$") - LD A,FDC_MSR - CALL PRTHEXBYTE - PRTS(" UNITS=2$") -; - LD A,FDMEDIA - LD (FCD_U0MEDIA),A - LD (FCD_U1MEDIA),A - LD A,0FEH - LD (FCD_U0TRK),A - LD (FCD_U1TRK),A - - LD A,FDTRACE - LD (FCD_TRACE),A - - LD BC,0 - LD (FCD_IDLECNT),BC - - LD A,DOR_INIT - LD (FST_DOR),A - - CALL FC_RESETFDC - CALL FD_CLRDSKCHG - - LD A,TRUE - LD (FCD_FDCRDY),A - - RET -; -; FD_IDLE QUIESCES THE FLOPPY SUBSYSTEM (MOTOR OFF) -; AFTER BEING CALLED ENOUGH TIMES... -; SHOULD IT INVALIDATE THE BUFFER??? -; -FD_IDLE: - LD BC,(FCD_IDLECNT) - LD A,B - OR C - RET Z ; COUNTER ALREADY FIRED - - DEC BC ; DECREMENT COUNTER - LD (FCD_IDLECNT),BC ; SAVE IT - LD A,B - OR C - RET NZ ; STILL COUNTING DOWN, RETURN - - CALL FC_MOTOROFF ; COUNTER JUST EXPIRED, SHUTDOWN MOTOR! - RET -; -; FD_STATUS -; -FD_STATUS: - CALL FD_SELECTUNIT - LD HL,(FDDS_TRKADR) - LD A,(HL) ; A = CURRENT TRACK - - CP 0FFH ; IS CURRENT TRACK = $FF? - JR Z,FD_STATUS1 ; IF SO, NOT READY - - XOR A ; A = 0 = OK - RET ; RETURN - -FD_STATUS1: - OR A ; A ALREADY = $FF, JUST SET FLAGS - RET -; -; FD_CLRDSKCHG -; -FD_CLRDSKCHG: - ; PROCESS ANY PENDING DISK CHANGE NOTIFICATIONS - LD B,5 -FD_CLRDSKCHG1: - PUSH BC - CALL FC_SENSEINT - POP BC - LD A,(FST_RC) - CP FRC_DSKCHG - RET NZ ; NO MORE DISK CHANGE NOTIFICATIONS - DJNZ FD_CLRDSKCHG1 -; -; FD_WTSEEK -; -; WAIT FOR PENDING SEEK OPERATION TO COMPLETE BY POLLING SENSEINT -; AND WAITING FOR ABTERM OR OK. -; -FD_WTSEEK: - LD BC,1000H - -FD_WTSEEKLOOP: - PUSH BC - CALL FC_SENSEINT - POP BC - - LD A,(FST_RC) ; CHECK RC - CP FRC_ABTERM ; ABTERM = DONE/FAILED - JR Z,FD_RETRC - CP FRC_OK ; OK = DONE/SUCCESS - JR Z,FD_RETRC - - DEC BC ; CHECK LOOP COUNTER IN BC - LD A,B ; " - OR C ; " - JR NZ,FD_WTSEEKLOOP ; LOOP UNTIL COUNTER EXHAUSTED - -FD_RETRC: - LD A,(FST_RC) - OR A - RET ; TIMEOUT/FAILED -; -; FD_FDCRESET -; -FD_FDCRESET: - CALL FC_RESETFDC - - CALL FD_CLRDSKCHG - - LD A,TRUE - LD (FCD_FDCRDY),A - - ; MARK ALL DRIVES AS NEEDING RECALIBRATION - ; NOTE THAT IF THE VALUE IS CURRENT $FF, - ; WE NEED TO LEAVE IT ALONE, SO WE 'OR' IN THE - ; $FE TO AVOID THIS SCENARIO. - LD A,(FCD_U0TRK) - OR 0FEH - LD (FCD_U0TRK),A - - LD A,(FCD_U1TRK) - OR 0FEH - LD (FCD_U1TRK),A - - RET -; -; FD_DRIVERESET -; -; ATTEMPT TO FULLY RESET FLOPPY DRIVE, PRIMARILY RECALIBRATE -; -FD_DRIVERESET: - CALL FC_SPECIFY - RET NZ ; ERROR, BAIL OUT - - CALL FC_RECAL - RET NZ ; ERROR, BAIL OUT - - ; FIRST RECAL MAY FAIL TO REACH TRACK 0 - ; SO WE TRY ONCE MORE IN CASE OF A FAILURE - CALL FD_WTSEEK - RET Z - - ; SECOND TRY, ONLY IF NEEDED - CALL FC_RECAL - RET NZ ; ERROR, BAIL OUT - - CALL FD_WTSEEK - RET -; -; -; -FD_SELECTUNIT: - LD A,C - AND 0FH ; ISOLATE THE UNIT NIBBLE - - ; GOOD PLACE FOR AN INTEGRITY CHECK - CP 2 - CALL NC,PANIC - - LD HL,FCD_UNITS - LD D,0 - AND 0FH - RLCA - LD E,A - ADD HL,DE - - LD (FDDS_TRKADR),HL ; LOAD TRKADR - INC HL ; SKIP TRK - LD (FDDS_MEDIAADR),HL ; LOAD MEDIAADR - - RET - -FD_READ: - LD A,DOP_READ - JR FD_RUN -; -FD_WRITE: - LD A,DOP_WRITE - JR FD_RUN -; -FD_RUN: - LD (FCD_DOP),A - - ; UPDATE DRIVE SELECTION - LD A,(HSTDSK) ; GET THE NEW DRIVE SELECTION - AND 0FH - LD (FCD_DS),A ; UPDATE FCD_DS TO NEW VALUE - LD C,A - CALL FD_SELECTUNIT - - ; MAP HSTTRK TO FCD_H, FCD_C - LD BC,(HSTTRK) - LD A,C ; HEAD IS LOW ORDER BIT - AND 1 ; ISOLATE IT - LD (FCD_H),A ; SAVE IT - LD A,C ; LOAD TRACK IN A - SRL A ; DIVIDE BY 2 FOR PHYSICAL TRACK - LD (FCD_C),A ; SAVE IT - - ; MAP HSTSEC TO FCD_R - LD BC,(HSTSEC) - LD A,C - INC A ; SWITCH FROM ZERO BASED TO ONE BASED - LD (FCD_R),A - - ; SET RETRY COUNTER - LD B,5 -FD_RETRY: - PUSH BC - CALL FD_START - POP BC - - LD A,(FST_RC) ; CHECK RESULT - OR A - RET Z ; SUCCESS - - DJNZ FD_RETRY ; RETRY TILL COUNTER EXHAUSTED - -#IF (FDTRACE == 1) - CALL FC_PRTRESULTS -#ENDIF - - LD A,(FST_RC) - OR A ; OTHERWISE SET FLAGS BASED ON RC (IN A) - RET ; AND GIVE UP -; -; -; -FD_START: - LD A,(FCD_FDCRDY) - CP TRUE - CALL NZ,FD_FDCRESET - - ; COPY MEDIA CONFIG INTO FCD - ; THIS IS HERE TO ACCOMMODATE DIFFERENT MEDIA - ; IN DIFFERENT FLOPPY UNITS. - LD HL,(FDDS_MEDIAADR) - LD A,(HL) ; A = MEDIA BYTE - RLCA ; TABLE IS 4 BYTE ENTRIES - RLCA ; A = A * 4 - LD HL,FCD_TBL ; HL = START OF TABLE - LD D,0 ; SET DE TO TABLE OFFSET - LD E,A - ADD HL,DE ; OFFSET BASED ON DESIRED MEDIA - CALL JPHL ; CALL THE TABLE ENTRY (SEE FCD_TBL) - LD DE,FCD ; DE = DESTINATION - LD BC,FCD_LEN ; BC = BYTES TO COPY - LDIR ; BYTES COPY FROM MDB TO FCD - - CALL FC_MOTORON ; INCLUDES LATCH SETUP - - LD HL,(FDDS_TRKADR) - LD A,(HL) - CP 0FEH ; FF = DRIVE NEEDS TO BE RESET - JR C,FD_RUN0 ; NO RESET NEEDED, BYPASS - - CALL FD_DRIVERESET - JR NZ,FD_RUNERR - - ; RECORD CURRENT TRACK POSITION - LD A,0 - LD HL,(FDDS_TRKADR) - LD (HL),A - -FD_RUN0: - ; COMPARE CURRENT TRACK WITH REQUESTED TRACK TO SEE IF SEEK NEEDED - LD HL,(FDDS_TRKADR) - LD A,(HL) - LD B,A - LD A,(FCD_C) - CP B - JR Z,FD_RUN1 ; FDDS_TRKADR == FCD_C, SKIP SEEK - - ; INITIATE SEEK TO NEW TRACK - CALL FC_SEEK - JR NZ,FD_RUNERR - - ; WAIT FOR SEEK TO COMPLETE - CALL FD_WTSEEK - JR NZ,FD_RUNERR - - ; RECORD NEW CURRENT TRACK - LD A,(FCD_C) - LD HL,(FDDS_TRKADR) - LD (HL),A - -FD_RUN1: - ; GET THE REQUESTED OPERATION - LD A,(FCD_DOP) - - ; SETUP RETURN ADDRESS - LD HL,FD_RUNCHK - PUSH HL - - ; DISPATCH TO FUNCTION - CP DOP_READ - JR Z,FC_READ - CP DOP_WRITE - JR Z,FC_WRITE - CP DOP_READID - JR Z,FC_READID - CALL PANIC - -FD_RUNCHK: -#IF (DSKYENABLE) - CALL FD_DSKY -#ENDIF - -FD_RUNEXIT: - LD A,(FST_RC) - OR A - RET Z - -FD_RUNERR: - ; INDICATE THAT A CONTROLLER RESET IS DESIRED - LD A,FALSE - LD (FCD_FDCRDY),A - - ; FLAG DRIVE IN ERROR STATUS BY SETTING TRKADR == FF - LD A,0FFH - LD HL,(FDDS_TRKADR) - LD (HL),A - - JP FD_RETRC - -#IF (DSKYENABLE) -FD_DSKY: - LD HL,DSKY_HEXBUF - LD A,(FCD_C) - LD (HL),A - INC HL - LD A,(FCD_R) - LD (HL),A - INC HL - LD A,(FRB_ST0) - LD (HL),A - INC HL - LD A,(FRB_ST1) - LD (HL),A - CALL DSKY_HEXOUT - RET -#ENDIF -; -;=============================================================================== -; FLOPPY DISK CONTROL SERVICES (PHYSICAL DEVICE CONTROL FOR FDC HARDWARE) -;=============================================================================== -; -; ENTRY POINTS FOR FDC COMMANDS -; -FC_READ: - LD A,CMD_READ | 11100000B - CALL FC_SETUPIO - JP FOP - -FC_WRITE: - LD A,CMD_WRITE | 11000000B - CALL FC_SETUPIO - JP FOP - -FC_READID: - LD A,CMD_READID | 01000000B - CALL FC_SETUPCMD - JP FOP - -FC_RECAL: - LD A,CMD_RECAL | 00000000B - CALL FC_SETUPCMD - JP FOP ; FIX: DO WE NEED TO REMOVE HDS BITS FROM SECOND BYTE? - -FC_SENSEINT: - LD A,CMD_SENSEINT | 00000000B - CALL FC_SETUPCMD - LD A,1 ; GENERIC COMMAND, BUT JUST FIRST COMMAND CODE - LD (FCP_LEN),A - JP FOP - -FC_SPECIFY: - LD A,CMD_SPECIFY | 00000000B - CALL FC_SETUPSPECIFY - JP FOP - -FC_DRVSTAT: - LD A,CMD_DRVSTAT | 00000000B - CALL FC_SETUPCMD - JP FOP - -FC_SEEK: - LD A,CMD_SEEK | 00000000B - CALL FC_SETUPSEEK - JP FOP -; -; HELPER FUNCTIONS TO SETUP CMDBUF -; -FC_SETUPCMD: - ; TRICKY... THE INCOMING BYTE IN A MUST CONTAIN THE COMMAND CODE ITSELF - ; IN THE LOW 5 BITS PLUS IT MUST SET WHICH OF THE DESIRED BITS IT WANTS - ; IN THE HIGH 3 BITS. WE 'AND' THIS WITH THE TEMPATE BITS TO PRODUCE - ; THE CORRECT FINAL COMMAND BYTE - LD DE,FCP_BUF - AND 5FH ; MT=0, MFM=1, SK=0, CMD=11111 - LD (DE),A ; SAVE THE BYTE - AND 00011111B ; ISOLATE JUST THE COMMAND BITS - LD (FCP_CMD),A ; SAVE IT FOR LATER - INC DE - - LD A,(FCD_H) ; START WITH HDS - AND 01H ; MASK TO REMOVE IRRELEVANT BITS FOR SAFETY - RLCA ; MAKE ROOM FOR DS BITS - RLCA ; - LD B,A ; SAVE WHAT WE HAVE SO FAR IN B - LD A,(FCD_DS) ; GET DS VALUE - AND 03H ; MASK TO REMOVE IRRELEVANT BITS FOR SAFETY - OR B ; COMBINE WITH SAVED - LD (DE),A ; SAVE THE BYTE - INC DE - - LD A,2 ; LENGTH IS 2 BYTES AT THIS POINT - LD (FCP_LEN),A - - RET - -FC_SETUPIO: - CALL FC_SETUPCMD - - LD A,(FCD_C) - LD (DE),A - INC DE - - LD A,(FCD_H) - LD (DE),A - INC DE - - LD A,(FCD_R) - LD (DE),A - INC DE - - LD A,FCD_N - LD (DE),A - INC DE - - LD A,(FCD_EOT) - LD (DE),A - INC DE - - LD A,(FCD_GPL) - LD (DE),A - INC DE - - LD A,FCD_DTL - LD (DE),A - INC DE - - LD A,9 - LD (FCP_LEN),A - - RET - -FC_SETUPSEEK: - CALL FC_SETUPCMD ; START WITH GENERIC IO CMD - - LD A,(FCD_C) - LD (DE),A - INC DE - - LD A,3 - LD (FCP_LEN),A - - RET - -FC_SETUPSPECIFY: - CALL FC_SETUPCMD - DEC DE ; BACKUP 1 BYTE, WE ONLY WANT FIRST BYTE - - LD A,(FCD_SRTHUT) - LD (DE),A ; SAVE THE BYTE - INC DE - - LD A,(FCD_HLTND) - LD (DE),A ; SAVE THE BYTE - INC DE - - LD A,3 - LD (FCP_LEN),A - - RET -; -; SET FST_DOR -; -FC_SETDOR - LD (FST_DOR),A - OUT (FDC_DOR),A -#IF (FDTRACE >= 3) - CALL NEWLINE - LD DE,FDSTR_DOR - CALL WRITESTR - LD DE,FDSTR_ARROW - CALL WRITESTR - CALL PC_SPACE - LD A,(FST_DOR) - CALL PRTHEXBYTE -#ENDIF - RET -; -; RESET FDC BY PULSING BIT 7 OF LATCH LOW -; -FC_RESETFDC: -#IF (FDTRACE >= 3) - LD DE,FDSTR_RESETFDC - CALL WRITESTR -#ENDIF - LD A,(FST_DOR) - PUSH AF - -#IF ((FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3)) - RES 7,A -#ENDIF -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8)) - LD A,0 -#ENDIF - CALL FC_SETDOR - CALL DELAY - POP AF - CALL FC_SETDOR - - LD DE,100 ; DELAY: 25us * 100 = 2.5ms - CALL VDELAY - RET -; -; PULSE TERMCT TO TERMINATE ANY ACTIVE EXECUTION PHASE -; -FC_PULSETC: -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8)) - IN A,(FDC_TC) -#ELSE - LD A,(FST_DOR) - SET 0,A - OUT (FDC_DOR),A - RES 0,A - OUT (FDC_DOR),A -#ENDIF - RET -; -; SET FST_DOR FOR MOTOR CONTROL ON -; -FC_MOTORON: - LD BC,300H -; LD BC,10H - LD (FCD_IDLECNT),BC - -#IF (FDTRACE >= 3) - LD DE,FDSTR_MOTON - CALL WRITESTR -#ENDIF -#IF ((FDMODE == FDMODE_DIO) | (FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3)) - LD A,(FST_DOR) - PUSH AF - - LD A,(FCD_DOR) ; GET NEW LATCH VALUE (W/ MOTOR ON) - CALL FC_SETDOR ; AND IMPLEMENT IT - - POP AF -#IF ((FDMODE == FDMODE_ZETA) | (FDMODE == FDMODE_DIO3)) - XOR 00000010B ; MOTOR BIT INVERTED ON ZETA -#ENDIF - BIT 1,A ; SET FLAGS SET BASED ON CURRENT MOTOR BIT - RET Z ; MOTOR WAS PREVIOUSLY ON, WE ARE DONE -#ENDIF -#IF ((FDMODE == FDMODE_DIDE) | (FDMODE == FDMODE_N8)) - ; SETUP DCR FOR DIDE HARDWARE - LD A,(FCD_DCR) - OUT (FDC_DCR),A - - LD HL,FST_DOR ; POINT TO FDC_DOR - LD A,(HL) ; START WITH CURRENT DOR - PUSH AF - AND 11111100B ; GET RID OF ANY ACTIVE DS BITS - LD C,A ; SAVE IT FOR NOW - LD A,(FCD_DS) ; NOW GET CURRENT DS - LD B,A ; PUT IN B FOR LATER - OR C ; COMBINE WITH SAVED DOR - LD C,A ; RE-SAVE IT - INC B ; SET UP B AS LOOP COUNTER (DS + 1) - LD A,00001000B ; STARTING BIT PATTERN FOR MOTOR -FC_MOTORON1: - RLA ; SHIFT LEFT - DJNZ FC_MOTORON1 ; DS TIMES - OR C ; COMBINE WITH SAVED - LD (HL),A ; COMMIT THE NEW VALUE TO FST_DOR - CALL FC_SETDOR ; OUTPUT TO CONTROLLER - - LD C,A - POP AF - CP C - RET Z ; MOTOR WAS PREVIOUSLY ON -#ENDIF - -#IF (FDTRACE >= 3) - LD DE,FDSTR_MOTDELAY - CALL WRITESTR -#ENDIF - CALL LDELAY ; DELAY FOR MOTOR SPINUP IF NOT PREVIOUSLY ON - RET -; -; SET FST_DOR FOR MOTOR CONTROL OFF -; -FC_MOTOROFF: - LD A,(FCD_FDCRDY) - CP TRUE - CALL NZ,FD_FDCRESET - - LD A,DOR_INIT - CALL FC_SETDOR ; OUTPUT TO CONTROLLER - -#IF (FDTRACE >= 3) - LD DE,FDSTR_MOTOFF - CALL WRITESTR -#ENDIF - RET -; -;=============================================================================== -; FDC OPERATIONS -;=============================================================================== -; -FOP: -; -; INITIALIZATION -; - LD A,0 - LD (FRB_LEN),A - - LD A,FRC_OK - LD (FST_RC),A -; -; CLEAR FDC, DISCARD ANY PENDING BYTES (GARBAGE?) -; - LD B,0 ; B IS LOOP COUNTER -FOP_CLR1: - CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR - IN A,(FDC_MSR) ; GET STATUS - AND 0C0H ; ISOLATE HIGH NIBBLE, RQM/DIO/NDM/CB - CP 0C0H ; LOOKING FOR RQM=1, DIO=1, BYTES PENDING - JR NZ,FOP_CMD1 ; NO BYTES PENDING, GO TO NEXT PHASE - IN A,(FDC_DATA) ; GET THE PENDING BYTE AND DISCARD - DJNZ FOP_CLR1 - JP FOP_TOFDCRDY ; OTHERWISE, TIMEOUT -; -; SEND COMMAND -; -FOP_CMD1: - LD HL,FCP_BUF - LD A,(FCP_LEN) - LD D,A ; D = CMD BYTES TO SEND - -FOP_CMD2: ; START OF LOOP TO SEND NEXT BYTE - LD B,0 ; B IS LOOP COUNTER - -FOP_CMD4: ; START OF STATUS LOOP, WAIT FOR FDC TO BE READY FOR BYTE - CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR - IN A,(FDC_MSR) ; READ MAIN STATUS REGISTER - AND 0C0H ; ISOLATE RQM/DIO - CP 080H ; LOOKING FOR RQM=1, DIO=0 (FDC READY FOR A BYTE) - JR Z,FOP_CMD6 ; GOOD, GO TO SEND BYTE - CP 0C0H ; HMMMM... RQM=1 & DIO=1, FDC WANTS TO SEND US DATA, UNEXPECTED - JR Z,FOP_RES ; GO IMMEDIATELY TO RESULTS??? - DJNZ FOP_CMD4 ; LOOP TILL COUNTER EXHAUSTED - JR FOP_TOSNDCMD ; COUNTER EXHAUSTED, TIMEOUT / EXIT - -FOP_CMD6: ; SEND NEXT BYTE - LD A,(HL) ; POINT TO NEXT BYTE TO SEND - OUT (FDC_DATA),A ; PUSH IT TO FDC - INC HL ; INCREMENT POINTER FOR NEXT TIME - DEC D ; DECREMENT NUM BYTES LEFT TO SEND - JR NZ,FOP_CMD2 ; DO NEXT BYTE -; -; EXECUTION PHASE -; -FOP_X1: - LD A,(FCP_CMD) - - LD HL,FOP_RES - PUSH HL - - CP CMD_READ - JP Z,FXR_READ - CP CMD_WRITE - JP Z,FXR_WRITE - CP CMD_READID - JP Z,FXR_NULL - RET ; RET ACTUALLY JUST JUMPS RIGHT TO FOP_RES -; -; RESULTS PHASE -; -FOP_RES: - LD HL,FRB ; POINT TO RECEIVE BUFFER - -FOP_RES0: - LD B,0 ; B IS LOOP COUNTER - -FOP_RES1: - CALL DELAY ; FDC MAY TAKE UP TO 12us TO UPDATE MSR - IN A,(FDC_MSR) ; READ MAIN STATUS REGISTER - AND 0F0H ; ISOLATE RQM/DIO/EXEC/BUSY - CP 0D0H ; LOOKING FOR RQM/DIO/BUSY - JR Z,FOP_RES2 ; GOOD, GO TO RECEIVE BYTE - CP 080H ; CHECK FOR RQM=1, DIO=0 (NOTHING LEFT) - JR Z,FOP_EVAL ; IF NOTHING LEFT, ALL DONE, GO TO EOD/EXIT - DJNZ FOP_RES1 ; LOOP TILL COUNTER EXHAUSTED - JR FOP_TOGETRES ; OTHERWISE TIMEOUT ERROR - -FOP_RES2: ; PROCESS NEXT PENDING BYTE - LD A,FRB_SIZ ; GET BUF SIZE - CP D ; REACHED MAX? - JR Z,FOP_BUFMAX ; HANDLE BUF MAX/EXIT - IN A,(FDC_DATA) ; GET THE BYTE - LD (HL),A ; SAVE VALUE - INC HL ; INCREMENT BUF POS - INC D ; INCREMENT BYTES RECEIVED - PUSH HL - LD HL,FRB_LEN ; POINT TO BUFFER LENGTH - LD (HL),D ; UPDATE NUMBER OF BYTES RECEIVED - POP HL - JR FOP_RES0 ; CONTINUE READ LOOP -; -; EXIT POINTS -; -FOP_NOTIMPL: - LD A,FRC_NOTIMPL - JR FOP_ERR - -FOP_CMDERR: - LD A,FRC_CMDERR - JR FOP_ERR - -FOP_ERROR: - LD A,FRC_ERROR - JR FOP_ERR - -FOP_ABORT: - LD A,FRC_ABORT - JR FOP_ERR - -FOP_BUFMAX: - LD A,FRC_BUFMAX - JR FOP_ERR - -FOP_TOFDCRDY: - LD A,FRC_TOFDCRDY - JR FOP_ERR - -FOP_TOSNDCMD: - LD A,FRC_TOSNDCMD - JR FOP_ERR - -FOP_TOGETRES: - LD A,FRC_TOGETRES - JR FOP_ERR - -FOP_TOEXEC: - LD A,FRC_TOEXEC - JR FOP_ERR - -FOP_ERR: - LD (FST_RC),A - -FOP_EVAL: - LD A,(FCP_CMD) - ; DRVSTAT IS WEIRD, HAS ONLY ST3, NOTHING TO EVAL - CP CMD_DRVSTAT - JR Z,FOP_EXIT - ; DO WE HAVE ST0? - LD A,(FRB_LEN) - CP 1 - JP M,FOP_EXIT - -FOP_EVALST0: - LD A,(FRB_ST0) - AND 11000000B - CP 01000000B ; ABTERM - JR Z,FOP_ABTERM - CP 10000000B ; INVCMD - JR Z,FOP_INVCMD - CP 11000000B ; DSKCHG - JR Z,FOP_DSKCHG - JR FOP_EXIT - -FOP_ABTERM: - ; SENSEINT DOES NOT USE ST1 - LD A,(FCP_CMD) - CP CMD_SENSEINT - JR Z,FOP_ABTERM1 - ; DO WE HAVE ST1? - LD A,(FRB_LEN) - CP 2 - JP M,FOP_ABTERM1 - JR FOP_EVALST1 -FOP_ABTERM1: ; NO FURTHER DATA, SET FST TO ABTERM - LD C,FRC_ABTERM - JR FOP_SETFST - -FOP_INVCMD: - LD C,FRC_INVCMD - JR FOP_SETFST - -FOP_DSKCHG: - LD C,FRC_DSKCHG - JR FOP_SETFST - -FOP_EVALST1: - LD A,(FRB_ST1) - - LD C,FRC_ENDCYL - BIT 7,A - JR NZ,FOP_SETFST - - LD C,FRC_DATAERR - BIT 5,A - JR NZ,FOP_SETFST - - LD C,FRC_OVERRUN - BIT 4,A - JR NZ,FOP_SETFST - - LD C,FRC_NODATA - BIT 2,A - JR NZ,FOP_SETFST - - LD C,FRC_NOTWRIT - BIT 1,A - JR NZ,FOP_SETFST - - LD C,FRC_MISADR - BIT 0,A - JR NZ,FOP_SETFST - - JR FOP_EXIT - -FOP_SETFST: - LD A,C - LD (FST_RC),A - -FOP_EXIT: -#IF (FDTRACE >= 2) - CALL FC_PRTRESULTS -#ENDIF - JP FD_RETRC -; -; EXECUTION ROUTINES -; -FXR_NOP: - RET -; -; NULL EXECUTION, NO DATA TO READ/WRITE (USED BY READID) -; -FXR_NULL: - LD BC,1000H ; BC IS LOOP COUNTER, 4096 ITERATIONS -FXR_NULL1: - CALL DELAY - IN A,(FDC_MSR) ; GET MSR - AND 0E0H ; ISOLATE RQM/DIO/NDM - CP 0C0H ; WE WANT RQM=1,DIO=1,NDM=0 (READY TO READ A BYTE W/ EXEC INACTIVE) - RET Z ; GOT IT, EXIT CLEAN W/O PULSING TC - DEC BC ; DECREMENT COUNTER (16 BIT) - LD A,B ; CHECK FOR ZERO - OR C ; " - JR NZ,FXR_NULL1 ; NOT ZERO YET, KEEP CHECKING - JP FXR_TO ; OTHERWISE, TIMEOUT ERROR - RET -; -; READ DATA -; -FXR_READ: - LD HL,(DIOBUF) ; POINT TO SECTOR BUFFER START - LD DE,(FCD_SECSZ) - LD A,(CPUFREQ + 3) / 4 - LD (FCD_TO),A -FXRR1 LD C,0 ; OUTER LOOP TIMEOUT COUNTER -FXRR2: LD B,0 ; SETUP FOR 256 ITERATIONS -FXRR3: IN A,(FDC_MSR) ; GET MSR - CP 0F0H ; WE WANT RQM=1,DIO=1,NDM=1,BUSY=1 (READY TO RECEIVE A BYTE W/ EXEC ACTIVE) - JR Z,FXRR4 ; GOT IT, DO BYTE READ - DJNZ FXRR3 ; NOT READY, LOOP IF COUNTER NOT ZERO - JR FXRR5 ; COUNTER ZERO, GO TO OUTER LOOP LOGIC - -FXRR4: IN A,(FDC_DATA) ; GET PENDING BYTE - LD (HL),A ; STORE IT IN BUFFER - INC HL ; INCREMENT THE BUFFER POINTER - DEC DE ; DECREMENT BYTE COUNT - LD A,D - OR E - JR NZ,FXRR2 ; IF NOT ZERO, REPEAT LOOP - JR FXR_END ; CLEAN EXIT - -FXRR5: ; OUTER LOOP, REALLY ONLY HAPPENS WHEN WAITING FOR FIRST BYTE OR ABORTED - CP 0C0H ; IF RQM=1, DIO=1, NDM=0 (EXECUTION ABORTED) - JR Z,FXR_ABORT ; BAIL OUT TO ERR ROUTINE, FIX: GO TO SPECIFIC ROUTINE FOR THIS??? - DEC C - JR NZ,FXRR2 ; IF NOT ZERO, LOOP SOME MORE - LD A,(FCD_TO) - DEC A - LD (FCD_TO),A - JR NZ,FXRR1 - JR FXR_TO ; OTHERWISE, TIMEOUT ERROR -; -; WRITE DATA -; -FXR_WRITE: - LD HL,(DIOBUF) ; POINT TO SECTOR BUFFER START - LD DE,(FCD_SECSZ) - LD A,(CPUFREQ + 3) / 4 - LD (FCD_TO),A -FXRW1 LD C,0 ; OUTER LOOP TIMEOUT COUNTER -FXRW2: LD B,0 ; SETUP FOR 256 ITERATIONS -FXRW3: IN A,(FDC_MSR) ; GET MSR - CP 0B0H ; WE WANT RQM=1,DIO=0,NDM=1,BUSY=1 (READY TO SEND A BYTE W/ EXEC ACTIVE) - JR Z,FXRW4 ; GOT IT, DO BYTE WRITE - DJNZ FXRW3 ; NOT READY, LOOP IF COUNTER NOT ZERO - JR FXRW5 ; COUNTER ZERO, GO TO OUTER LOOP LOGIC -FXRW4: LD A,(HL) ; GET NEXT BYTE TO WRITE - OUT (FDC_DATA),A ; WRITE IT - INC HL ; INCREMENT THE BUFFER POINTER - DEC DE ; DECREMENT LOOP COUNTER - LD A,D - OR E - JR NZ,FXRW2 ; IF NOT ZERO, REPEAT LOOP - JR FXR_END ; CLEAN EXIT -FXRW5: ; OUTER LOOP, REALLY ONLY HAPPENS WHEN WAITING FOR FIRST BYTE OR ABORTED - CP 0C0H ; IF RQM=1, DIO=1, NDM=0 (EXECUTION ABORTED) - JR Z,FXR_ABORT ; BAIL OUT TO ERR ROUTINE - DEC C - JR NZ,FXRW2 ; IF NOT ZERO, LOOP SOME MORE - LD A,(FCD_TO) - DEC A - LD (FCD_TO),A - JR NZ,FXRW1 - JR FXR_TO ; OTHERWISE, TIMEOUT ERROR -; -FXR_TO: - LD A,FRC_TOEXEC - JR FXR_ERR - -FXR_ABORT: - LD A,FRC_ABORT - JR FXR_ERR -; -; COMMON COMPLETION CODE FOR ALL EXECUTION ROUTINES -; -FXR_ERR: - LD (FST_RC),A - RET - -FXR_END: - CALL FC_PULSETC - RET - -#IF (FDTRACE > 0) -; -;=============================================================================== -; COMMAND PROCESSING STATUS DISPLAY -;=============================================================================== -; -; PRINT STATUS -; -FC_PRTFST: - PUSH AF - PUSH BC - PUSH DE - PUSH HL - LD A,(FST_RC) ; A GETS FST_RC - LD B,FSST_COUNT ; B GETS TABLE ENTRY COUNT - LD HL,FSST - LD DE,FSST_ENTSIZ ; TABLE ENTRY LENGTH - -FC_PRTFST0: ; START OF LOOP - LD C,(HL) - CP C - JR Z,FC_PRTFST1 ; FOUND CODE - - ADD HL,DE ; POINT TO NEXT ENTRY - DJNZ FC_PRTFST0 ; CHECK NEXT ENTRY TILL COUNT IS ZERO - - ; NO MATCHING ENTRY, PRINT THE HEX VALUE - CALL PC_SPACE - CALL PC_LBKT - CALL PRTHEXBYTE - CALL PC_RBKT - JR FC_PRTFSTX - -FC_PRTFST1: ; ENTRY FOUND, PRINT IT - CALL PC_SPACE - INC HL - LD E,(HL) - INC HL - LD D,(HL) - CALL PC_LBKT - CALL WRITESTR - CALL PC_RBKT - - -FC_PRTFSTX: - POP HL - POP DE - POP BC - POP AF - RET -; -; PRINT COMMAND -; -FC_PRTCMD: - PUSH AF - PUSH BC - PUSH DE - PUSH HL - LD A,(FCP_CMD) ; A GETS THE COMMAND CODE - LD B,FCT_COUNT ; B GETS TABLE ENTRY COUNT - LD HL,FCT - LD DE,FCT_ENTSIZ ; TABLE ENTRY LENGTH - -FCPC_LOOP: ; START OF LOOP - LD C,(HL) - CP C - JR Z,FCPC_MATCH ; FOUND CODE - - ADD HL,DE ; POINT TO NEXT ENTRY - DJNZ FCPC_LOOP ; CHECK NEXT ENTRY TILL COUNT IS ZERO - - ; NO MATCHING ENTRY, PRINT THE HEX VALUE - CALL PC_SPACE - CALL PC_LBKT - CALL PRTHEXBYTE - CALL PC_RBKT - JR FCPC_EXIT - -FCPC_MATCH: ; ENTRY FOUND, PRINT IT - INC HL - LD E,(HL) - INC HL - LD D,(HL) - CALL WRITESTR - -FCPC_EXIT: - POP HL - POP DE - POP BC - POP AF - RET -; -; PRINT RESULTS -; -FC_PRTRESULTS: - ; IF TRACE IS SET, FORCE PRINT RESULTS - LD A,(FCD_TRACE) - OR A - RET Z ; IF TRACE = 0, BE SILENT! - - CP 3 ; IS TRACE >= 3 ? - JR NC,FCPR2 ; YES, SO FORCE PRINT EVERYTHING! - - ; IF RC=OK, GET OUT, NOTHING TO PRINT - LD A,(FST_RC) - CP FRC_OK - RET Z - - ; SPECIAL CASE, DON'T PRINT IF SENSEINT & INVCMD/DSK CHG/ABTERM - LD A,(FCP_CMD) - CP CMD_SENSEINT - JR NZ,FCPR2 - - LD A,(FST_RC) - CP FRC_INVCMD - JR Z,FCPR_EXIT - CP FRC_DSKCHG - JR Z,FCPR_EXIT - CP FRC_ABTERM - JR Z,FCPR_EXIT - JR FCPR_EXIT - -FCPR2: - CALL NEWLINE - - LD DE,FDSTR_FD - CALL WRITESTR - CALL PC_COLON - CALL PC_SPACE - - CALL FC_PRTCMD - - LD A,(FCP_LEN) - LD DE,FCP_BUF - CALL PRTHEXBUF - - LD DE,FDSTR_ARROW - CALL WRITESTR - - LD A,(FRB_LEN) - LD DE,FRB - CALL PRTHEXBUF - - LD A,(FST_RC) - CALL FC_PRTFST - -FCPR_EXIT: - RET -; -; STRING CONSTANTS -; -FDSTR_ARROW .TEXT " -->$" -FDSTR_NORESP .TEXT "DRIVE NOT RESPONDING$" -FDSTR_FD .TEXT "FD$" -#IF (FDTRACE >= 3) -FDSTR_MOTON .TEXT "\r\nMOTOR ON$" -FDSTR_MOTOFF .TEXT "\r\nMOTOR OFF$" -FDSTR_MOTDELAY .TEXT "\r\nMOTOR DELAY$" -FDSTR_DOR .TEXT "DOR$" -FDSTR_RESETFDC .TEXT "\r\nRESET FDC$" -FDSTR_SELECT .TEXT "\r\nSELECT: $" -#ENDIF ; (FDTRACE >= 3) -#ENDIF ; (FDTRACE > 0) -; -; -;================================================================================================== -; FLOPPY DISK DRIVER - DATA -;================================================================================================== -; -; FDC COMMAND PHASE -; -FCP_CMD .DB 000H -FCP_LEN .DB 00H -FCP_BUF: -FCP_CMDX .DB 0 -FCP_HDSDS .DB 0 -FCP_C .DB 0 -FCP_H .DB 0 -FCP_R .DB 0 -FCP_N .DB 0 -FCP_EOT .DB 0 -FCP_GPL .DB 0 -FCP_DTL .DB 0 -FCP_BUFSIZ .EQU $-FCP_BUF -; -; FDC STATUS -; -FST_RC .DB 00H -FST_DOR .DB 00H -; -; FDC RESULTS BUFFER -; -FRB_LEN .DB 00H -FRB -FRB_ST0 -FRB_ST3 .DB 0 -FRB_ST1 -FRB_PCN .DB 0 -FRB_ST2 .DB 0 -FRB_C .DB 0 -FRB_H .DB 0 -FRB_R .DB 0 -FRB_N .DB 0 -FRB_SIZ .EQU $-FRB -; -; FDC COMMAND DATA -; -FCD: ; FLOPPY CONFIGURATION DATA (PUBLIC) MANAGED AS A "BLOCK" -FCD_NUMCYL .DB 000H ; NUMBER OF CYLINDERS -FCD_NUMHD .DB 000H ; NUMBER OF HEADS -FCD_NUMSEC .DB 000H ; NUMBER OF SECTORS -FCD_SOT .DB 000H ; START OF TRACK (ID OF FIRST SECTOR, USUALLY 1) -FCD_EOT ; END OF TRACK SECTOR (SAME AS SC SINCE SOT ALWAYS 1) -FCD_SC .DB 000H ; SECTOR COUNT -FCD_SECSZ .DW 000H ; SECTOR SIZE IN BYTES -FCD_GPL .DB 000H ; GAP LENGTH (R/W) -FCD_GPLF .DB 000H ; GAP LENGTH (FORMAT) -FCD_SRTHUT .DB 000H ; STEP RATE, IBM PS/2 CALLS FOR 3ms, 0DH = 3ms SRT, HEAD UNLOAD TIME -FCD_HLTND .DB 000H ; HEAD LOAD TIME, IBM PS/2 CALLS FOR 15ms 08H = 16ms HUT -FCD_DOR .DB 000H ; DOR VALUE -FCD_DCR .DB 000H ; DCR VALUE -FCD_LEN .EQU $ - FCD - ; DYNAMICALLY MANAGED (PUBLIC) -FCD_DS .DB 001H ; DRIVE SELECT (UNIT NUMBER 0-3) -FCD_C .DB 000H ; CYLINDER -FCD_H .DB 000H ; HEAD -FCD_R .DB 001H ; RECORD -FCD_D .DB 0E5H ; DATA FILL BYTE - ; STATUS MANAGEMENT -FCD_DOP .DB 0FFH ; CURRENT OPERATION (SEE DOP_...) -FCD_IDLECNT .DW 0 ; IDLE COUNT -FCD_TRACE .DB 0 ; TRACE LEVEL -FCD_TO .DB 0 ; TIMEOUT COUNTDOWN TIMER -FCD_FDCRDY .DB 0 ; FALSE MEANS FDC RESET NEEDED -; -; FLOPPY UNIT DATA -; -FCD_UNITS: -FCD_U0TRK .DB 0FFH ; CURRENT TRACK -FCD_U0MEDIA .DB FDMEDIA ; MEDIA BYTE -; .DW FDDPH0 ; ADDRESS OF DPH -; -FCD_U1TRK .DB 0FFH ; CURRENT TRACK -FCD_U1MEDIA .DB FDMEDIA ; MEDIA BYTE -; -; WORKING STORAGE (DERIVED FROM ABOVE FOR ACTIVE DRIVE UNIT) -; -FDDS_TRKADR .DW 0 ; POINTER TO FDCUXTRK ABOVE -FDDS_MEDIAADR .DW 0 ; POINTER TO FDCUXMEDIA ABOVE diff --git a/branches/s100/Source/fd_data.asm b/branches/s100/Source/fd_data.asm deleted file mode 100644 index f1ddff25..00000000 --- a/branches/s100/Source/fd_data.asm +++ /dev/null @@ -1,173 +0,0 @@ -; -;================================================================================================== -; FLOPPY DISK DRIVER - DATA -;================================================================================================== -; -#IF (FDMEDIA == FDM720) - #DEFINE FDDPB DPB_FD720 ; DPB_FD720 OR DPB_FD144 - #DEFINE FDCKS CKS_FD720 - #DEFINE FDALS ALS_FD720 -#ENDIF -#IF (FDMEDIA == FDM144) - #DEFINE FDDPB DPB_FD144 ; DPB_FD720 OR DPB_FD144 - #DEFINE FDCKS CKS_FD144 - #DEFINE FDALS ALS_FD144 -#ENDIF -#IF (FDMEDIA == FDM360) - #DEFINE FDDPB DPB_FD360 ; DPB_FD720 OR DPB_FD144 - #DEFINE FDCKS CKS_FD360 - #DEFINE FDALS ALS_FD360 -#ENDIF -#IF (FDMEDIA == FDM120) - #DEFINE FDDPB DPB_FD120 ; DPB_FD720 OR DPB_FD144 - #DEFINE FDCKS CKS_FD120 - #DEFINE FDALS ALS_FD120 -#ENDIF -#IF (FDMEDIA == FDM111) - #DEFINE FDDPB DPB_FD111 ; DPB_FD720 OR DPB_FD144 - #DEFINE FDCKS CKS_FD111 - #DEFINE FDALS ALS_FD111 -#ENDIF -; -; -; - .DB DIODEV_FD + 0 -FDDPH0: .DW 0000, 0000 - .DW 0000, 0000 - .DW DIRBF, FDDPB - .DW FDCSV0, FDALV0 - .DB DIODEV_FD + 1 -FDDPH1: .DW 0000, 0000 - .DW 0000, 0000 - .DW DIRBF, FDDPB - .DW FDCSV1, FDALV1 -; .EXPORT FDDPH0, FDDPH1 -;; -;; DISK PARAMETER BLOCKS USED FOR FLOPPY DRIVER -;; -;; IBM 720KB 3.5" FLOPPY DRIVE, 80 TRKS, 36 SECS/TRK, 512 BYTES/SEC -;; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 128 -;; -;#IF ((FDMEDIA == FDM720) | (FDMEDIAALT == FDM720)) -;DPB_FD720: -; .DW 36 ; SPT: SECTORS PER TRACK -; .DB 4 ; BSH: BLOCK SHIFT FACTOR -; .DB 15 ; BLM: BLOCK MASK -; .DB 0 ; EXM: EXTENT MASK -; .DW 350 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((720K - 18K OFF) / 2K BLS) - 1 = 350 -; .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 -; .DB 11000000B ; AL0: DIR BLK BIT MAP, FIRST BYTE -; .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE -; .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 -; .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K -;#ELSE -;DPB_FD720 .EQU 0 -;#ENDIF -CKS_FD720 .EQU 32 ; CKS: DIR ENT / 4 = 128 / 4 = 32 -ALS_FD720 .EQU 44 ; ALS: BLKS / 8 = 351 / 8 = 44 (ROUNDED UP) -; .EXPORT DPB_FD720 -;#ENDIF -;; -;; IBM 1.44MB 3.5" FLOPPY DRIVE, 80 TRKS, 72 SECS/TRK, 512 BYTES/SEC -;; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -;; -;#IF ((FDMEDIA == FDM144) | (FDMEDIAALT == FDM144)) -;DPB_FD144: -; .DW 72 ; SPT: SECTORS PER TRACK -; .DB 4 ; BSH: BLOCK SHIFT FACTOR -; .DB 15 ; BLM: BLOCK MASK -; .DB 0 ; EXM: EXTENT MASK -; .DW 710 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,440K - 18K OFF) / 2K BLS) - 1 = 710 -; .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 -; .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE -; .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE -; .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 -; .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 72 SEC/TRK) = 18K -;#ELSE -;DPB_FD144 .EQU 0 -;#ENDIF -CKS_FD144 .EQU 64 ; CKS: DIR ENT / 4 = 256 / 4 = 64 -ALS_FD144 .EQU 89 ; ALS: BLKS / 8 = 711 / 8 = 89 (ROUNDED UP) -; .EXPORT DPB_FD144 -;#ENDIF -;; -;; IBM 360KB 5.25" FLOPPY DRIVE, 40 TRKS, 9 SECS/TRK, 512 BYTES/SEC -;; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 128 -;; -;#IF ((FDMEDIA == FDM360) | (FDMEDIAALT == FDM360)) -;DPB_FD360: -; .DW 36 ; SPT: SECTORS PER TRACK -; .DB 4 ; BSH: BLOCK SHIFT FACTOR -; .DB 15 ; BLM: BLOCK MASK -; .DB 0 ; EXM: EXTENT MASK -; .DW 170 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((360K - 18K OFF) / 2K BLS) - 1 = 170 -; .DW 127 ; DRM: DIR ENTRIES - 1 = 128 - 1 = 127 -; .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE -; .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE -; .DW 32 ; CKS: DIRECTORY CHECK VECTOR SIZE = 128 / 4 -; .DW 4 ; OFF: RESERVED TRACKS = 4 TRKS * (512 B/SEC * 36 SEC/TRK) = 18K -;#ELSE -;DPB_FD360 .EQU 0 -;#ENDIF -CKS_FD360 .EQU 32 ; CKS: DIR ENT / 4 = 128 / 4 = 32 -ALS_FD360 .EQU 89 ; ALS: BLKS / 8 = 171 / 8 = 22 (ROUNDED UP) -; .EXPORT DPB_FD360 -;#ENDIF -;; -;; IBM 1.20MB 5.25" FLOPPY DRIVE, 80 TRKS, 60 SECS/TRK, 512 BYTES/SEC -;; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -;; -;#IF ((FDMEDIA == FDM120) | (FDMEDIAALT == FDM120)) -;DPB_FD120: -; .DW 60 ; SPT: SECTORS PER TRACK -; .DB 4 ; BSH: BLOCK SHIFT FACTOR -; .DB 15 ; BLM: BLOCK MASK -; .DB 0 ; EXM: EXTENT MASK -; .DW 591 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,200K - 15K OFF) / 2K BLS) - 1 = 591 -; .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 -; .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE -; .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE -; .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 -; .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K -;#ELSE -;DPB_FD120 .EQU 0 -;#ENDIF -CKS_FD120 .EQU 64 ; CKS: DIR ENT / 4 = 256 / 4 = 64 -ALS_FD120 .EQU 74 ; ALS: BLKS / 8 = 592 / 8 = 74 (ROUNDED UP) -; .EXPORT DPB_FD120 -;#ENDIF -;; -;; IBM 1.11MB 8" FLOPPY DRIVE, 74 TRKS, 60 SECS/TRK, 512 BYTES/SEC -;; BLOCKSIZE (BLS) = 2K, DIRECTORY ENTRIES = 256 -;; -;#IF ((FDMEDIA == FDM111) | (FDMEDIAALT == FDM111)) -;DPB_FD111: -; .DW 60 ; SPT: SECTORS PER TRACK -; .DB 4 ; BSH: BLOCK SHIFT FACTOR -; .DB 15 ; BLM: BLOCK MASK -; .DB 0 ; EXM: EXTENT MASK -; .DW 546 ; DSM: TOTAL STORAGE IN BLOCKS - 1 BLK = ((1,110K - 15K OFF) / 2K BLS) - 1 = 546 -; .DW 255 ; DRM: DIR ENTRIES - 1 = 256 - 1 = 255 -; .DB 11110000B ; AL0: DIR BLK BIT MAP, FIRST BYTE -; .DB 00000000B ; AL1: DIR BLK BIT MAP, SECOND BYTE -; .DW 64 ; CKS: DIRECTORY CHECK VECTOR SIZE = 256 / 4 -; .DW 2 ; OFF: RESERVED TRACKS = 2 TRKS * (512 B/SEC * 60 SEC/TRK) = 15K -CKS_FD111 .EQU 64 ; CKS: DIR ENT / 4 = 256 / 4 = 64 -ALS_FD111 .EQU 69 ; ALS: BLKS / 8 = 592 / 8 = 74 (ROUNDED UP) -; .EXPORT DPB_FD111 -;#ENDIF -; -; -; -#IF (FDMAUTO) -; ASSUME WORST CASE SIZES -FDCSV0: .FILL CKS_FD144 -FDALV0: .FILL ALS_FD144 -FDCSV1: .FILL CKS_FD144 -FDALV1: .FILL ALS_FD144 -#ELSE -FDCSV0: .FILL FDCKS -FDALV0: .FILL FDALS -FDCSV1: .FILL FDCKS -FDALV1: .FILL FDALS -#ENDIF diff --git a/branches/s100/Source/hbfill.asm b/branches/s100/Source/hbfill.asm deleted file mode 100644 index a0abddb5..00000000 --- a/branches/s100/Source/hbfill.asm +++ /dev/null @@ -1,10 +0,0 @@ -; -;================================================================================================== -; FILLER FOR HBIOS PROXY, JUST A 256 BYTE FILLER -;================================================================================================== -; -#INCLUDE "std.asm" -; - .FILL HB_SIZ,0FFH -; - .END diff --git a/branches/s100/Source/hbios.asm b/branches/s100/Source/hbios.asm deleted file mode 100644 index f6357d6c..00000000 --- a/branches/s100/Source/hbios.asm +++ /dev/null @@ -1,873 +0,0 @@ -; -;================================================================================================== -; HBIOS -;================================================================================================== -; - -; bnk1.asm 11/16/2012 dwg - specify hl=0 before calling N8V_INIT -; This causes the TMS9918 character bitmaps to be loaded from the -; default bitmaps included in bnk1.asm -; bnk1.asm 5/23/2012 dwg Beta 4 - Enhanced SYS_GETCFG and SYS_SETCFG - - .ORG 1000H -; -; INCLUDE GENERIC STUFF -; -#INCLUDE "std.asm" -; -;================================================================================================== -; SYSTEM INITIALIZATION -;================================================================================================== -; -; AT THIS POINT, IT IS ASSUMED WE ARE OPERATING FROM RAM PAGE 1 -; -INITSYS: -; -; ANNOUNCE HBIOS -; - CALL NEWLINE - CALL NEWLINE - PRTX(STR_PLATFORM) - PRTS(" @ $") - LD HL,CPUFREQ - CALL PRTDEC - PRTS("MHz ROM=$") - LD HL,ROMSIZE - CALL PRTDEC - PRTS("KB RAM=$") - LD HL,RAMSIZE - CALL PRTDEC - PRTS("KB$") -; -; INSTALL HBIOS PROXY IN UPPER MEMORY -; - LD HL,HB_IMG ; HL := SOURCE OF HBIOS PROXY IMAGE - LD DE,HB_LOC ; DE := DESTINATION TO INSTALL IT - LD BC,HB_SIZ ; SIZE - LDIR ; DO THE COPY -; -; DURING INITIALIZATION, CONSOLE IS UART! -; POST-INITIALIZATION, WILL BE SWITCHED TO USER CONFIGURED CONSOLE -; - LD A,CIODEV_UART - LD (CONDEV),A -; -; PERFORM DEVICE INITIALIZATION -; - LD B,HB_INITTBLLEN - LD DE,HB_INITTBL -INITSYS2: - CALL NEWLINE - LD A,(DE) - LD L,A - INC DE - LD A,(DE) - LD H,A - INC DE - PUSH DE - PUSH BC - CALL JPHL -; OR A -; JR Z,INITSYS3 -; PUSH AF -; CALL PC_SPACE -; POP AF -; CALL PC_LBKT -; CALL PRTHEXBYTE -; CALL PC_RBKT -; JR INITSYS4 -;INITSYS3: -; PRTS(" [OK]$") -;INITSYS4: - POP BC - POP DE - DJNZ INITSYS2 -; -; SET UP THE DEFAULT DISK BUFFER ADDRESS -; - LD HL,$8000 ; DEFAULT DISK XFR BUF ADDRESS - LD (DIOBUF),HL ; SAVE IT -; -; NOW SWITCH TO USER CONFIGURED CONSOLE -; -#IF ((PLATFORM == PLT_N8) | (PLATFORM == PLT_S100)) - LD A,DEFCON -#ELSE - IN A,(RTC) ; RTC PORT, BIT 6 HAS STATE OF CONFIG JUMPER - BIT 6,A ; BIT 6 HAS CONFIG JUMPER STATE - LD A,DEFCON ; ASSUME WE WANT DEFAULT CONSOLE - JR NZ,INITSYS1 ; IF NZ, JUMPER OPEN, DEF CON IS CORRECT - LD A,ALTCON ; JUMPER SHORTED, USE ALTERNATE CONSOLE -INITSYS1: -#ENDIF - LD (CONDEV),A ; SET THE ACTIVE CONSOLE DEVICE -; -; DISPLAY THE POST-INITIALIZATION BANNER -; - CALL NEWLINE - CALL NEWLINE - PRTX(STR_BANNER) - CALL NEWLINE -; - RET -; -;================================================================================================== -; TABLE OF INITIALIZATION ENTRY POINTS -;================================================================================================== -; -HB_INITTBL: -#IF (UARTENABLE) - .DW UART_INIT -#ENDIF -#IF (VDUENABLE) - .DW VDU_INIT -#ENDIF -#IF (CVDUENABLE) - .DW CVDU_INIT -#ENDIF -#IF (UPD7220ENABLE) - .DW UPD7220_INIT -#ENDIF -#IF (N8VENABLE) - .DW N8V_INIT -#ENDIF -#IF (PRPENABLE) - .DW PRP_INIT -#ENDIF -#IF (PPPENABLE) - .DW PPP_INIT -#ENDIF -#IF (DSKYENABLE) - .DW DSKY_INIT -#ENDIF -#IF (FDENABLE) - .DW FD_INIT -#ENDIF -#IF (IDEENABLE) - .DW IDE_INIT -#ENDIF -#IF (PPIDEENABLE) - .DW PPIDE_INIT -#ENDIF -#IF (SDENABLE) - .DW SD_INIT -#ENDIF -#IF (HDSKENABLE) - .DW HDSK_INIT -#ENDIF -#IF (PPKENABLE) - .DW PPK_INIT -#ENDIF -#IF (KBDENABLE) - .DW KBD_INIT -#ENDIF -#IF (TTYENABLE) - .DW TTY_INIT -#ENDIF -#IF (ANSIENABLE) - .DW ANSI_INIT -#ENDIF -; -HB_INITTBLLEN .EQU (($ - HB_INITTBL) / 2) -; -;================================================================================================== -; IDLE -;================================================================================================== -; -;__________________________________________________________________________________________________ -; -IDLE: -#IF (FDENABLE) - CALL FD_IDLE -#ENDIF - RET -; -;================================================================================================== -; BIOS FUNCTION DISPATCHER -;================================================================================================== -; -; MAIN BIOS FUNCTION -; B: FUNCTION -;__________________________________________________________________________________________________ -; -BIOS_DISPATCH: - LD A,B ; REQUESTED FUNCTION IS IN B - CP BF_CIO + $10 ; $00-$0F: CHARACTER I/O - JR C,CIO_DISPATCH - CP BF_DIO + $10 ; $10-$1F: DISK I/O - JR C,DIO_DISPATCH - CP BF_RTC + $10 ; $20-$2F: REAL TIME CLOCK (RTC) - JR C,RTC_DISPATCH - CP BF_EMU + $10 ; $30-$3F: EMULATION - JP C,EMU_DISPATCH - CP BF_VDA + $10 ; $40-$4F: VIDEO DISPLAY ADAPTER - JP C,VDA_DISPATCH - - CP BF_SYS ; SKIP TO BF_SYS VALUE AT $F0 - CALL C,PANIC ; PANIC IF LESS THAN BF_SYS - JP SYS_DISPATCH ; OTHERWISE SYS CALL - CALL PANIC ; THIS SHOULD NEVER BE REACHED -; -;================================================================================================== -; CHARACTER I/O DEVICE DISPATCHER -;================================================================================================== -; -; ROUTE CALL TO SPECIFIED CHARACTER I/O DRIVER -; B: FUNCTION -; C: DEVICE/UNIT -; -CIO_DISPATCH: - LD A,C ; REQUESTED DEVICE/UNIT IS IN C - AND $F0 ; ISOLATE THE DEVICE PORTION -#IF (UARTENABLE) - CP CIODEV_UART - JP Z,UART_DISPATCH -#ENDIF -#IF (PRPENABLE & PRPCONENABLE) - CP CIODEV_PRPCON - JP Z,PRPCON_DISPATCH -#ENDIF -#IF (PPPENABLE & PPPCONENABLE) - CP CIODEV_PPPCON - JP Z,PPPCON_DISPATCH -#ENDIF -#IF (VDUENABLE) - CP CIODEV_VDU - JP Z,VDU_DISPCIO -#ENDIF -#IF (CVDUENABLE) - CP CIODEV_CVDU - JP Z,CVDU_DISPCIO -#ENDIF -#IF (UPD7220ENABLE) - CP CIODEV_UPD7220 - JP Z,UPD7220_DISPCIO -#ENDIF -#IF (N8VENABLE) - CP CIODEV_N8V - JP Z,N8V_DISPCIO -#ENDIF - CP CIODEV_CRT - JR Z,CIOEMU - CALL PANIC -; -CIOEMU: - LD A,B - ADD A,BF_EMU - BF_CIO ; TRANSLATE FUNCTION CIOXXX -> EMUXXX - LD B,A - JP EMU_DISPATCH -; -;================================================================================================== -; DISK I/O DEVICE DISPATCHER -;================================================================================================== -; -; ROUTE CALL TO SPECIFIED DISK I/O DRIVER -; B: FUNCTION -; C: DEVICE/UNIT -; -DIO_DISPATCH: - ; GET THE REQUESTED FUNCTION TO SEE IF SPECIAL HANDLING - ; IS NEEDED - LD A,B -; - ; DIO FUNCTIONS STARTING AT DIOGETBUF ARE COMMON FUNCTIONS - ; AND DO NOT DISPATCH TO DRIVERS (HANDLED GLOBALLY) - CP BF_DIOGETBUF ; TEST FOR FIRST OF THE COMMON FUNCTIONS - JR NC,DIO_COMMON ; IF >= DIOGETBUF HANDLE AS COMMON DIO FUNCTION -; - ; HACK TO FILL IN HSTTRK AND HSTSEC - ; BUT ONLY FOR READ/WRITE FUNCTION CALLS - ; ULTIMATELY, HSTTRK AND HSTSEC ARE TO BE REMOVED - CP BF_DIOST ; BEYOND READ/WRITE FUNCTIONS ? - JR NC,DIO_DISPATCH1 ; YES, BYPASS - LD (HSTTRK),HL ; RECORD TRACK - LD (HSTSEC),DE ; RECORD SECTOR -; -DIO_DISPATCH1: - ; START OF THE ACTUAL DRIVER DISPATCHING LOGIC - LD A,C ; GET REQUESTED DEVICE/UNIT FROM C - LD (HSTDSK),A ; TEMP HACK TO FILL IN HSTDSK - AND $F0 ; ISOLATE THE DEVICE PORTION -; -#IF (FDENABLE) - CP DIODEV_FD - JP Z,FD_DISPATCH -#ENDIF -#IF (IDEENABLE) - CP DIODEV_IDE - JP Z,IDE_DISPATCH -#ENDIF -#IF (PPIDEENABLE) - CP DIODEV_PPIDE - JP Z,PPIDE_DISPATCH -#ENDIF -#IF (SDENABLE) - CP DIODEV_SD - JP Z,SD_DISPATCH -#ENDIF -#IF (PRPENABLE & PRPSDENABLE) - CP DIODEV_PRPSD - JP Z,PRPSD_DISPATCH -#ENDIF -#IF (PPPENABLE & PPPSDENABLE) - CP DIODEV_PPPSD - JP Z,PPPSD_DISPATCH -#ENDIF -#IF (HDSKENABLE) - CP DIODEV_HDSK - JP Z,HDSK_DISPATCH -#ENDIF - CALL PANIC -; -; HANDLE COMMON DISK FUNCTIONS (NOT DEVICE DRIVER SPECIFIC) -; -DIO_COMMON: - SUB BF_DIOGETBUF ; FUNCTION = DIOGETBUF? - JR Z,DIO_GETBUF ; YES, HANDLE IT - DEC A ; FUNCTION = DIOSETBUF? - JR Z,DIO_SETBUF ; YES, HANDLE IT - CALL PANIC ; INVALID FUNCTION SPECFIED -; -; DISK: GET BUFFER ADDRESS -; -DIO_GETBUF: - LD HL,(DIOBUF) ; HL = DISK BUFFER ADDRESS - XOR A ; SIGNALS SUCCESS - RET -; -; DISK: SET BUFFER ADDRESS -; -DIO_SETBUF: - BIT 7,H ; IS HIGH ORDER BIT SET? - CALL Z,PANIC ; IF NOT, ADR IS IN LOWER 32K, NOT ALLOWED!!! - LD (DIOBUF),HL ; RECORD NEW DISK BUFFER ADDRESS - XOR A ; SIGNALS SUCCESS - RET -; -;================================================================================================== -; REAL TIME CLOCK DEVICE DISPATCHER -;================================================================================================== -; -; ROUTE CALL TO REAL TIME CLOCK DRIVER (NOT YET IMPLEMENTED) -; B: FUNCTION -; -RTC_DISPATCH: - CALL PANIC -; -;================================================================================================== -; EMULATION HANDLER DISPATCHER -;================================================================================================== -; -; ROUTE CALL TO EMULATION HANDLER CURRENTLY ACTIVE -; B: FUNCTION -; -EMU_DISPATCH: - ; EMU FUNCTIONS STARTING AT EMUINI ARE COMMON - ; AND DO NOT DISPATCH TO DRIVERS - LD A,B ; GET REQUESTED FUNCTION - CP BF_EMUINI - JR NC,EMU_COMMON -; - LD A,(CUREMU) ; GET ACTIVE EMULATION -; -#IF (TTYENABLE) - DEC A ; 1 = TTY - JP Z,TTY_DISPATCH -#ENDIF -#IF (ANSIENABLE) - DEC A ; 2 = ANSI - JP Z,ANSI_DISPATCH -#ENDIF - CALL PANIC ; INVALID -; -; HANDLE COMMON EMULATION FUNCTIONS (NOT HANDLER SPECIFIC) -; -EMU_COMMON: - ; REG A CONTAINS FUNCTION ON ENTRY - CP BF_EMUINI - JR Z,EMU_INI - CP BF_EMUQRY - JR Z,EMU_QRY - CALL PANIC -; -; INITIALIZE EMULATION -; C: VDA DEVICE/UNIT TO USE GOING FORWARD -; E: EMULATION TYPE TO USE GOING FORWARD -; -EMU_INI: - LD A,E ; LOAD REQUESTED EMULATION TYPE - LD (CUREMU),A ; SAVE IT - LD A,C ; LOAD REQUESTED VDA DEVICE/UNIT - LD (CURVDA),A ; SAVE IT -; - ; UPDATE EMULATION VDA DISPATCHING ADDRESS -#IF (VDUENABLE) - LD HL,VDU_DISPVDA - CP VDADEV_VDU - JR Z,EMU_INI1 -#ENDIF -#IF (CVDUENABLE) - LD HL,CVDU_DISPVDA - CP VDADEV_CVDU - JR Z,EMU_INI1 -#ENDIF -#IF (UPD7220ENABLE) - LD HL,UPD7220_DISPVDA - CP VDADEV_UPD7220 - JR Z,EMU_INI1 -#ENDIF -#IF (N8VENABLE) - LD HL,N8V_DISPVDA - CP VDADEV_N8V - JR Z,EMU_INI1 -#ENDIF - CALL PANIC -; -EMU_INI1: - LD (EMU_VDADISPADR),HL ; RECORD NEW VDA DISPATCH ADDRESS - JP EMU_VDADISP ; NOW LET EMULATOR INITIALIZE -; -; QUERY CURRENT EMULATION CONFIGURATION -; RETURN CURRENT EMULATION TARGET VDA DEVICE/UNIT IN C -; RETURN CURRENT EMULATION TYPE IN E -; -EMU_QRY: - LD A,(CURVDA) - LD C,A - LD A,(CUREMU) - LD E,A - JP EMU_VDADISP ; NOW LET EMULATOR COMPLETE THE FUNCTION -; -;================================================================================================== -; VDA DISPATCHING FOR EMULATION HANDLERS -;================================================================================================== -; -; SINCE THE EMULATION HANDLERS WILL ONLY HAVE A SINGLE ACTIVE -; VDA TARGET AT ANY TIME, THE FOLLOWING IMPLEMENTS A FAST DISPATCHING -; MECHANISM THAT THE EMULATION HANDLERS CAN USE TO BYPASS SOME OF THE -; VDA DISPATCHING LOGIC. EMU_VDADISP CAN BE CALLED TO DISPATCH DIRECTLY -; TO THE CURRENT VDA EMULATION TARGET. IT IS A JUMP INSTRUCTION THAT -; IS DYNAMICALLY MODIFIED TO POINT TO THE VDA DISPATCHER FOR THE -; CURRENT EMULATION VDA TARGET. -; -; BELOW IS USED TO INITIALIZE THE EMULATION VDA DISPATCH TARGET -; BASED ON THE DEFAULT VDA. -; -VDA_DISPADR .EQU 0 -#IF (VDUENABLE & (DEFVDA == VDADEV_VDU)) -VDA_DISPADR .SET VDU_DISPVDA -#ENDIF -#IF (CVDUENABLE & (DEFVDA == VDADEV_CVDU)) -VDA_DISPADR .SET CVDU_DISPVDA -#ENDIF -#IF (VDUENABLE & (DEFVDA == VDADEV_UPD7220)) -VDA_DISPADR .SET UPD7220_DISPVDA -#ENDIF -#IF (N8VENABLE & (DEFVDA == VDADEV_N8V)) -VDA_DISPADR .SET N8V_DISPVDA -#ENDIF -; -; BELOW IS THE DYNAMICALLY MANAGED EMULATION VDA DISPATCH. -; EMULATION HANDLERS CAN CALL EMU_VDADISP TO INVOKE A VDA -; FUNCTION. EMU_VDADISPADR IS USED TO MARK THE LOCATION -; OF THE VDA DISPATCH ADDRESS. THIS ALLOWS US TO MODIFY -; THE CODE DYNAMICALLY WHEN EMULATION IS INITIALIZED AND -; A NEW VDA TARGET IS SPECIFIED. -; -EMU_VDADISPADR .EQU $ + 1 -EMU_VDADISP: - JP VDA_DISPADR -; -;================================================================================================== -; VIDEO DISPLAY ADAPTER DEVICE DISPATCHER -;================================================================================================== -; -; ROUTE CALL TO SPECIFIED VDA DEVICE DRIVER -; B: FUNCTION -; C: DEVICE/UNIT -; -VDA_DISPATCH: - LD A,C ; REQUESTED DEVICE/UNIT IS IN C - AND $F0 ; ISOLATE THE DEVICE PORTION -#IF (VDUENABLE) - CP VDADEV_VDU - JP Z,VDU_DISPVDA -#ENDIF -#IF (CVDUENABLE) - CP VDADEV_CVDU - JP Z,CVDU_DISPVDA -#ENDIF -#IF (UPD7220ENABLE) - CP VDADEV_7220 - JP Z,UPD7220_DISPVDA -#ENDIF -#IF (N8VENABLE) - CP VDADEV_N8V - JP Z,N8V_DISPVDA -#ENDIF - CALL PANIC -; -;================================================================================================== -; SYSTEM FUNCTION DISPATCHER -;================================================================================================== -; -; B: FUNCTION -; -SYS_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,SYS_GETCFG ; $F0 - DEC A - JR Z,SYS_SETCFG ; $F1 - DEC A - JR Z,SYS_BNKCPY ; $F2 - DEC A - JR Z,SYS_GETVER ; $F3 - CALL PANIC ; INVALID -; -; GET ACTIVE CONFIGURATION -; DE: DESTINATION TO RECEIVE CONFIGURATION DATA BLOCK -; MUST BE IN UPPER 32K -; -SYS_GETCFG: - LD HL,$0200 ; SETUP SOURCE OF CONFIG DATA - LD BC,$0100 ; SIZE OF CONFIG DATA - LDIR ; COPY IT - RET -; -; SET ACTIVE CONFIGURATION -; DE: SOURCE OF NEW CONFIGURATION DATA BLOCK -; MUST BE IN UPPER 32K -; -; HBIOS IS NOT REALLY SET UP TO DYNAMICALLY RECONFIGURE ITSELF!!! -; THIS FUNCTION IS NOT USEFUL YET. -; -SYS_SETCFG: - LD HL,$0200 ; SETUP SOURCE OF CONFIG DATA - LD BC,$0100 - EX DE,HL - LDIR - RET -; -; PERFORM A BANKED MEMORY COPY -; C: BANK TO SWAP INTO LOWER 32K PRIOR TO COPY OPERATION -; IX: COUNT OF BYTES TO COPY -; HL: SOURCE ADDRESS FOR COPY -; DE: DESTINATION ADDRESS FOR COPY -; -SYS_BNKCPY: - LD A,C ; BANK SELECTION TO A - PUSH IX - POP BC ; BC = BYTE COUNT TO COPY - JP HB_BNKCPY ; JUST PASS CONTROL TO HBIOS STUB IN UPPER MEMORY -; -; GET THE CURRENT HBIOS VERSION -; RETURNS VERSION IN DE AS BCD -; D: MAJOR VERION IN TOP 4 BITS, MINOR VERSION IN LOW 4 BITS -; E: UPDATE VERION IN TOP 4 BITS, PATCH VERSION IN LOW 4 BITS -; -SYS_GETVER: - LD DE,0 | (RMJ<<12) | (RMN<<8) | (RUP<<4) | RTP - XOR A - RET -; -;================================================================================================== -; GLOBAL HBIOS FUNCTIONS -;================================================================================================== -; -; COMMON ROUTINE THAT IS CALLED BY CHARACTER IO DRIVERS WHEN -; AN IDLE CONDITION IS DETECTED (WAIT FOR INPUT/OUTPUT) -; -CIO_IDLE: - LD HL,IDLECOUNT ; POINT TO IDLE COUNT - DEC (HL) ; 256 TIMES? - CALL Z,IDLE ; RUN IDLE PROCESS EVERY 256 ITERATIONS - XOR A ; SIGNAL NO CHAR READY - RET ; AND RETURN -; -;================================================================================================== -; DEVICE DRIVERS -;================================================================================================== -; -#IF (UARTENABLE) -ORG_UART .EQU $ - #INCLUDE "uart.asm" -SIZ_UART .EQU $ - ORG_UART - .ECHO "UART occupies " - .ECHO SIZ_UART - .ECHO " bytes.\n" -#ENDIF -; -#IF (VDUENABLE) -ORG_VDU .EQU $ - #INCLUDE "vdu.asm" -SIZ_VDU .EQU $ - ORG_VDU - .ECHO "VDU occupies " - .ECHO SIZ_VDU - .ECHO " bytes.\n" -#ENDIF -; -#IF (CVDUENABLE) -ORG_CVDU .EQU $ - #INCLUDE "cvdu.asm" -SIZ_CVDU .EQU $ - ORG_CVDU - .ECHO "CVDU occupies " - .ECHO SIZ_CVDU - .ECHO " bytes.\n" -#ENDIF -; -#IF (UPD7220ENABLE) -ORG_UPD7220 .EQU $ - #INCLUDE "upd7220.asm" -SIZ_UPD7220 .EQU $ - ORG_UPD7220 - .ECHO "UPD7220 occupies " - .ECHO SIZ_UPD7220 - .ECHO " bytes.\n" -#ENDIF -; -#IF (N8VENABLE) -ORG_N8V .EQU $ - #INCLUDE "n8v.asm" -SIZ_N8V .EQU $ - ORG_N8V - .ECHO "N8V occupies " - .ECHO SIZ_N8V - .ECHO " bytes.\n" -#ENDIF -; -#IF (PRPENABLE) -ORG_PRP .EQU $ - #INCLUDE "prp.asm" -SIZ_PRP .EQU $ - ORG_PRP - .ECHO "PRP occupies " - .ECHO SIZ_PRP - .ECHO " bytes.\n" -#ENDIF -; -#IF (PPPENABLE) -ORG_PPP .EQU $ - #INCLUDE "ppp.asm" -SIZ_PPP .EQU $ - ORG_PPP - .ECHO "PPP occupies " - .ECHO SIZ_PPP - .ECHO " bytes.\n" -#ENDIF -; -#IF (FDENABLE) -ORG_FD .EQU $ - #INCLUDE "fd.asm" -SIZ_FD .EQU $ - ORG_FD - .ECHO "FD occupies " - .ECHO SIZ_FD - .ECHO " bytes.\n" -#ENDIF - -#IF (IDEENABLE) -ORG_IDE .EQU $ - #INCLUDE "ide.asm" -SIZ_IDE .EQU $ - ORG_IDE - .ECHO "IDE occupies " - .ECHO SIZ_IDE - .ECHO " bytes.\n" -#ENDIF - -#IF (PPIDEENABLE) -ORG_PPIDE .EQU $ - #INCLUDE "ppide.asm" -SIZ_PPIDE .EQU $ - ORG_PPIDE - .ECHO "PPIDE occupies " - .ECHO SIZ_PPIDE - .ECHO " bytes.\n" -#ENDIF - -#IF (SDENABLE) -ORG_SD .EQU $ - #INCLUDE "sd.asm" -SIZ_SD .EQU $ - ORG_SD - .ECHO "SD occupies " - .ECHO SIZ_SD - .ECHO " bytes.\n" -#ENDIF - -#IF (HDSKENABLE) -ORG_HDSK .EQU $ - #INCLUDE "hdsk.asm" -SIZ_HDSK .EQU $ - ORG_HDSK - .ECHO "HDSK occupies " - .ECHO SIZ_HDSK - .ECHO " bytes.\n" -#ENDIF - -#IF (PPKENABLE) -ORG_PPK .EQU $ - #INCLUDE "ppk.asm" -SIZ_PPK .EQU $ - ORG_PPK - .ECHO "PPK occupies " - .ECHO SIZ_PPK - .ECHO " bytes.\n" -#ENDIF - -#IF (KBDENABLE) -ORG_KBD .EQU $ - #INCLUDE "kbd.asm" -SIZ_KBD .EQU $ - ORG_KBD - .ECHO "KBD occupies " - .ECHO SIZ_KBD - .ECHO " bytes.\n" -#ENDIF - -#IF (TTYENABLE) -ORG_TTY .EQU $ - #INCLUDE "tty.asm" -SIZ_TTY .EQU $ - ORG_TTY - .ECHO "TTY occupies " - .ECHO SIZ_TTY - .ECHO " bytes.\n" -#ENDIF - -#IF (ANSIENABLE) -ORG_ANSI .EQU $ - #INCLUDE "ansi.asm" -SIZ_ANSI .EQU $ - ORG_ANSI - .ECHO "ANSI occupies " - .ECHO SIZ_ANSI - .ECHO " bytes.\n" -#ENDIF -; -#DEFINE CIOMODE_CONSOLE -#DEFINE DSKY_KBD -#INCLUDE "util.asm" -; -;================================================================================================== -; HBIOS GLOBAL DATA -;================================================================================================== -; -CONDEV .DB CIODEV_UART -; -IDLECOUNT .DB 0 -; -HSTDSK .DB 0 ; DISK IN BUFFER -HSTTRK .DW 0 ; TRACK IN BUFFER -HSTSEC .DW 0 ; SECTOR IN BUFFER -; -CUREMU .DB DEFEMU ; CURRENT EMULATION -CURVDA .DB DEFVDA ; CURRENT VDA TARGET FOR EMULATION -; -DIOBUF .DW $FD00 ; PTR TO 512 BYTE DISK XFR BUFFER -; -STR_BANNER .DB "N8VEM HBIOS v", BIOSVER, " (" -VAR_LOC .DB VARIANT, "-" -TST_LOC .DB TIMESTAMP, ")" -; .DB "\r\n", PLATFORM_NAME, DSKYLBL, VDULBL, CVDULBL, UPD7220LBL, N8VLBL -; .DB FDLBL, IDELBL, PPIDELBL, SDLBL, PRPLBL, PPPLBL, HDSKLBL - .DB "$" -STR_PLATFORM .DB PLATFORM_NAME, "$" -; -;================================================================================================== -; FILL REMAINDER OF HBIOS -;================================================================================================== -; -SLACK: .EQU (7F00H - $) - .FILL SLACK,0FFH -; - .ECHO "HBIOS space remaining: " - .ECHO SLACK - .ECHO " bytes.\n" -; -;================================================================================================== -; HBIOS UPPER MEMORY STUB -;================================================================================================== -; -; THE FOLLOWING CODE IS RELOCATED TO THE TOP PAGE IN MEMORY TO HANDLE INVOCATION DISPATCHING -; -HB_IMG .EQU $ - .ORG HB_LOC -; -;================================================================================================== -; HBIOS INTERRUPT VECTOR TABLE -;================================================================================================== -; -; AREA RESERVED FOR UP TO 16 INTERRUPT VECTOR ENTRIES (MODE 2) -; -HB_IVT: - .FILL 20H,0FFH -; -;================================================================================================== -; HBIOS INITIALIZATION -;================================================================================================== -; -; SETUP RST 08 VECTOR TO HANDLE MAIN BIOS FUNCTIONS -; -HB_INIT: - LD A,0C3H ; $C3 = JP - LD (8H),A - LD HL,HB_ENTRY - LD (9H),HL - RET -; -; MEMORY MANAGER -; -#INCLUDE "memmgr.asm" -; -;================================================================================================== -; HBIOS BNKCPY ROUTINE -;================================================================================================== -; -; SELECT A DESIGNATED RAM/ROM BANK INTO LOWER 32K, THEN PERFORM A BULK MEMORY COPY -; A: BANK SELECTION (BIT 7: 1=RAM/0=ROM, BITS 0-6: BANK NUMBER) -; DE: DESTINATION ADDRESS -; HL: SOURCE ADDRESS -; BC: COUNT OF BYTES TO COPY; -; -HB_BNKCPY: - BIT 7,A ; CHECK BIT 7 - JR NZ,HB_BNKCPY1 ; RAM PAGE -; - CALL ROMPG ; SELECT ROM PAGE - JR HB_BNKCPY2 ; GO TO COMMON STUFF -; -HB_BNKCPY1: - RES 7,A ; CLEAR BIT 7 - CALL RAMPG ; SELECT RAM PAGE AND FALL THRU -; -HB_BNKCPY2: - LDIR ; DO THE COPY - LD A,1 ; RESELECT RAM PAGE 1 - CALL RAMPG ; DO IT - RET ; BACK TO LOWER MEMORY -; -;================================================================================================== -; HBIOS ENTRY FOR RST 08 PROCESSING -;================================================================================================== -; -; ENTRY POINT FOR BIOS FUNCTIONS (TARGET OF RST 08) -; -HB_ENTRY: - EX AF,AF' ; SAVE AF' SO WE CAN USE IT BELOW - PUSH AF ; " - - PGRAMF(1) ; MAP RAM PAGE 1 INTO LOWER 32K - - LD (HB_STKSAV),SP ; SAVE ORIGINAL STACK FRAME - LD SP,8000H ; SETUP NEW STACK FRAME AT END OF HBIOS - - CALL BIOS_DISPATCH ; CALL HBIOS FUNCTION DISPATCHER - - EX AF,AF' ; SAVE AF IN AF' - PGRAMF(0) ; MAP RAM PAGE 0 INTO LOWER 32K - - LD SP,(HB_STKSAV) ; RESTORE ORIGINAL STACK FRAME - - POP AF ; RECOVER ORIGINAL AF' - EX AF,AF' ; RESTORE AF' AND GET AF RETURNED FROM DISPATCH BACK - - RET ; RETURN TO CALLER -; -HB_STKSAV .DW 0 ; PREVIOUS STACK POINTER -; -HB_SLACK .EQU (HB_END - $) - .ECHO "STACK space remaining: " - .ECHO HB_SLACK - .ECHO " bytes.\n" -; - .FILL HB_SLACK,0FFH - .END diff --git a/branches/s100/Source/hdsk.asm b/branches/s100/Source/hdsk.asm deleted file mode 100644 index 33fcfa58..00000000 --- a/branches/s100/Source/hdsk.asm +++ /dev/null @@ -1,280 +0,0 @@ -; -;================================================================================================== -; HDSK DISK DRIVER -;================================================================================================== -; -; IO PORT ADDRESSES -; -HDSK_IO .EQU $FD -; -HDSK_CMDNONE .EQU 0 -HDSK_CMDRESET .EQU 1 -HDSK_CMDREAD .EQU 2 -HDSK_CMDWRITE .EQU 3 -HDSK_CMDPARAM .EQU 4 -; -; STATUS -; -HDSKRC_OK .EQU 0 -; -; UNIT CONFIGURATION -; -HDSK0_DEVICE .DB 11100000B ; LBA, MASTER DEVICE -HDSK1_DEVICE .DB 11110000B ; LBA, SLAVE DEVICE -; -; -; -HDSK_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JR Z,HDSK_RD - DEC A - JR Z,HDSK_WR - DEC A - JR Z,HDSK_ST - DEC A - JR Z,HDSK_MED - CALL PANIC -; -HDSK_RD: - JP HDSK_READ -HDSK_WR: - JP HDSK_WRITE -HDSK_ST: - JP HDSK_STATUS -HDSK_MED: - JP HDSK_MEDIA -; -; HDSK_MEDIA -; -HDSK_MEDIA: - LD A,MID_HD - RET -; -; -; -HDSK_INIT: - PRTS("HDSK: UNITS=4$") -; - XOR A - DEC A ; INITIAL STATUS IS NOT READY $FF - LD (HDSK_STAT),A ; SAVE IT - XOR A ; INIT SUCCEEDED - RET ; RETURN -; -; -; -HDSK_STATUS: - LD A,(HDSK_STAT) ; LOAD STATUS - OR A ; SET FLAGS - RET -; -; -; -HDSK_READ: - LD A,HDSK_CMDREAD - JR HDSK_RW -; -; -; -HDSK_WRITE: - LD A,HDSK_CMDWRITE - JR HDSK_RW -; -; -; -HDSK_RW: - LD (HDSK_CMD),A - - ; CLEAR RESULTS - XOR A ; A = 0 - LD (HDSK_RC),A ; CLEAR RETURN CODE - - ; INIT IF NEEDED - LD A,(HDSK_STAT) ; GET CURRENT STATUS - OR A ; SET FLAGS - CALL NZ,HDSK_RESET ; RESET IF NOT READY - - ; SET DEVICE - LD A,(HSTDSK) - AND 0FH - LD (HDSK_DEVICE),A - - ; SET SECTOR (IGNORES MSB) - LD A,(HSTSEC) - LD (HDSK_SEC),A - - ; SET TRACK - LD BC,(HSTTRK) - LD (HDSK_TRK),BC - - ; SET TRANSFER ADDRESS - LD BC,(DIOBUF) - LD (HDSK_DMA),BC - - ; EXECUTE COMMAND - LD B,7 ; SIZE OF PARAMETER BLOCK - LD HL,HDSK_PARMBLK ; START ADDRESS OF PARAMETER BLOCK -HDSK_RW1: - LD A,(HL) ; GET BYTE OF PARAMETER BLOCK - OUT (0FDH),A ; SEND IT TO PORT - INC HL ; POINT TO NEXT BYTE - DJNZ HDSK_RW1 - - IN A,(0FDH) ; GET RESULT CODE - LD (HDSK_RC),A - OR A - JR Z,HDSK_OK - JR HDSK_ERR - -HDSK_ERR: - XOR A - DEC A ; A=$FF TO SIGNAL ERROR - LD (HDSK_STAT),A ; SAVE IT -#IF (HDSKTRACE >= 1) - PUSH AF - CALL HDSK_PRT - POP AF -#ENDIF - RET - -HDSK_OK: -#IF (HDSKTRACE >= 2) - CALL HDSK_PRT -#ENDIF - XOR A - RET -; -; -; -HDSK_RESET: - LD B,32 - LD A,HDSK_CMDRESET -HDSK_RESET1: - OUT (0FDH),A - DJNZ HDSK_RESET1 - - XOR A ; STATUS = OK - LD (HDSK_STAT),A ; SAVE IT - -#IF (HDSKTRACE >= 2) - CALL NEWLINE - LD DE,HDSKSTR_PREFIX - CALL WRITESTR - CALL PC_SPACE - LD DE,HDSKSTR_RESET - CALL WRITESTR -#ENDIF - - RET -; -; -; -HDSK_PRT: - CALL NEWLINE - - LD DE,HDSKSTR_PREFIX - CALL WRITESTR - - CALL PC_SPACE - LD DE,HDSKSTR_CMD - CALL WRITESTR - LD A,(HDSK_CMD) - CALL PRTHEXBYTE - - CALL PC_SPACE - CALL PC_LBKT - LD A,(HDSK_CMD) - LD DE,HDSKSTR_NONE - CP HDSK_CMDNONE - JP Z,HDSK_PRTCMD - LD DE,HDSKSTR_RESET - CP HDSK_CMDRESET - JP Z,HDSK_PRTCMD - LD DE,HDSKSTR_READ - CP HDSK_CMDREAD - JP Z,HDSK_PRTCMD - LD DE,HDSKSTR_WRITE - CP HDSK_CMDWRITE - JP Z,HDSK_PRTCMD - LD DE,HDSKSTR_PARAM - CP HDSK_CMDPARAM - JP Z,HDSK_PRTCMD - LD DE,HDSKSTR_UNKCMD -HDSK_PRTCMD: - CALL WRITESTR - CALL PC_RBKT - - LD A,(HDSK_CMD) - CP HDSK_CMDREAD - JR Z,HDSK_PRTRW - CP HDSK_CMDWRITE - JR Z,HDSK_PRTRW - RET - -HDSK_PRTRW: - CALL PC_SPACE - LD A,(HDSK_DEVICE) - CALL PRTHEXBYTE - CALL PC_SPACE - LD BC,(HDSK_TRK) - CALL PRTHEXWORD - CALL PC_SPACE - LD A,(HDSK_SEC) - CALL PRTHEXBYTE - CALL PC_SPACE - LD BC,(HDSK_DMA) - CALL PRTHEXWORD - - CALL PC_SPACE - LD DE,HDSKSTR_ARROW - CALL WRITESTR - - CALL PC_SPACE - LD DE,HDSKSTR_RC - CALL WRITESTR - LD A,(HDSK_RC) - CALL PRTHEXBYTE - - CALL PC_SPACE - CALL PC_LBKT - LD A,(HDSK_RC) - LD DE,HDSKSTR_RCOK - CP HDSKRC_OK - JP Z,HDSK_PRTRC - LD DE,HDSKSTR_RCUNK - -HDSK_PRTRC: - CALL WRITESTR - CALL PC_RBKT - - RET -; -; -; -HDSKSTR_PREFIX .TEXT "HDSK:$" -HDSKSTR_CMD .TEXT "CMD=$" -HDSKSTR_RC .TEXT "RC=$" -HDSKSTR_ARROW .TEXT "-->$" -HDSKSTR_NONE .TEXT "NONE$" -HDSKSTR_RESET .TEXT "RESET$" -HDSKSTR_READ .TEXT "READ$" -HDSKSTR_WRITE .TEXT "WRITE$" -HDSKSTR_PARAM .TEXT "PARAM$" -HDSKSTR_UNKCMD .TEXT "UNKCMD$" -HDSKSTR_RCOK .TEXT "OK$" -HDSKSTR_RCUNK .TEXT "UNKNOWN ERROR$" -; -;================================================================================================== -; HDSK DISK DRIVER - DATA -;================================================================================================== -; -HDSK_STAT .DB 0 -HDSK_RC .DB 0 -; -HDSK_PARMBLK: -HDSK_CMD .DB 0 ; HDSK_READ OR HDSK_WRITE -HDSK_DEVICE .DB 0 ; 0 .. 7, DEFINES HARD DISK TO BE USED -HDSK_SEC .DB 0 ; 0 .. 31, DEFINES SECTOR -HDSK_TRK .DW 0 ; 0 .. 2047, DEFINES TRACK -HDSK_DMA .DW 0 ; DEFINES WHERE RESULT IS PLACED IN MEMORY \ No newline at end of file diff --git a/branches/s100/Source/hdsk_data.asm b/branches/s100/Source/hdsk_data.asm deleted file mode 100644 index 2e52e51c..00000000 --- a/branches/s100/Source/hdsk_data.asm +++ /dev/null @@ -1,61 +0,0 @@ -; -;================================================================================================== -; HDSK DISK DRIVER - DATA -;================================================================================================== -; -HDSK_SLICETRKS .EQU 65 ; TRACKS PER SLICE -HDSK_TRKSIZE .EQU 128 ; SIZE OF TRACK (IN KB) -HDSK_SLICESIZE .EQU ((HDSK_SLICETRKS * HDSK_TRKSIZE) + 1023) / 1024 ; SIZE OF EACH SLICE (IN MB) -HDSK_NUMSLICES .EQU HDSKCAPACITY / HDSK_SLICESIZE ; TOTAL SLICES IN DEVICE -HDSK0_SLICEDEF .EQU 0 ; DEFAULT SLICE FOR UNIT 0 -HDSK1_SLICEDEF .EQU 1 ; DEFAULT SLICE FOR UNIT 1 -HDSK2_SLICEDEF .EQU 2 ; DEFAULT SLICE FOR UNIT 0 -HDSK3_SLICEDEF .EQU 3 ; DEFAULT SLICE FOR UNIT 1 -; - .DB DIODEV_HDSK + 0 -HDSKDPH0 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW HDSKCSV0,HDSKALV0 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -HDSK0_SLICE .DW HDSK0_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW HDSK_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_HDSK + 0 -HDSKDPH1 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW HDSKCSV1,HDSKALV1 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -HDSK1_SLICE .DW HDSK1_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW HDSK_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_HDSK + 0 -HDSKDPH2 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW HDSKCSV2,HDSKALV2 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -HDSK2_SLICE .DW HDSK2_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW HDSK_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_HDSK + 0 -HDSKDPH3 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW HDSKCSV3,HDSKALV3 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -HDSK3_SLICE .DW HDSK3_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW HDSK_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; -HDSKCKS .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -HDSKALS .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) -; -HDSKCSV0: .FILL HDSKCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -HDSKALV0: .FILL HDSKALS ; MAX OF 2048 DATA BLOCKS -HDSKCSV1: .FILL HDSKCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -HDSKALV1: .FILL HDSKALS ; MAX OF 2048 DATA BLOCKS -HDSKCSV2: .FILL HDSKCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -HDSKALV2: .FILL HDSKALS ; MAX OF 2048 DATA BLOCKS -HDSKCSV3: .FILL HDSKCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -HDSKALV3: .FILL HDSKALS ; MAX OF 2048 DATA BLOCKS diff --git a/branches/s100/Source/ide.asm b/branches/s100/Source/ide.asm deleted file mode 100644 index 12f6c861..00000000 --- a/branches/s100/Source/ide.asm +++ /dev/null @@ -1,515 +0,0 @@ -; -;================================================================================================== -; IDE DISK DRIVER -;================================================================================================== -; -; IO PORT ADDRESSES -; -#IF (IDEMODE == IDEMODE_DIO) -#IF (IDE8BIT) -IDEDATA: .EQU 20H ; DATA PORT (8 BIT) -#ELSE -IDEDATALO: .EQU 20H ; DATA PORT (16 BIT LO BYTE) -IDEDATAHI: .EQU 28H ; DATA PORT (16 BIT HI BYTE) -IDEDATA: .EQU IDEDATALO -#ENDIF -#ENDIF -; -#IF (IDEMODE == IDEMODE_DIDE) -#IF (IDE8BIT) -IDEDATA: .EQU 20H ; DATA PORT (8 BIT OR 16 BIT PIO LO/HI BYTES) -#ELSE -IDEDATA: .EQU 28H ; DATA PORT (16 BIT PIO LO/HI BYTES) -IDEDMA: .EQU 29H ; DATA PORT (16 BIT DMA LO/HI BYTES) -#ENDIF -#ENDIF -; -IDEERR: .EQU 21H ; READ: ERROR REGISTER; WRITE: PRECOMP -IDESECTC: .EQU 22H ; SECTOR COUNT -IDESECTN: .EQU 23H ; SECTOR NUMBER -IDECYLLO: .EQU 24H ; CYLINDER LOW -IDECYLHI: .EQU 25H ; CYLINDER HIGH -IDEDEVICE: .EQU 26H ; DRIVE/HEAD -IDESTTS: .EQU 27H ; READ: STATUS; WRITE: COMMAND -IDECTRL: .EQU 2EH ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL -IDEADDR: .EQU 2FH ; DRIVE ADDRESS (READ ONLY) -; -; -; -IDECMD_READ .EQU 020H -IDECMD_WRITE .EQU 030H -IDECMD_SETFEAT .EQU 0EFH -; -IDERC_OK .EQU 0 -IDERC_CMDERR .EQU 1 -IDERC_RDYTO .EQU 2 -IDERC_BUFTO .EQU 3 -; -; UNIT CONFIGURATION -; -IDE0_DEVICE .DB 11100000B ; LBA, MASTER DEVICE -IDE1_DEVICE .DB 11110000B ; LBA, SLAVE DEVICE -; -; -; -IDE_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JR Z,IDE_RD - DEC A - JR Z,IDE_WR - DEC A - JR Z,IDE_ST - DEC A - JR Z,IDE_MED - CALL PANIC -; -IDE_RD: - JP IDE_READ -IDE_WR: - JP IDE_WRITE -IDE_ST: - JP IDE_STATUS -IDE_MED: - JP IDE_MEDIA -; -; IDE_MEDIA -; -IDE_MEDIA: - LD A,MID_HD - RET -; -; -; -IDE_INIT: - PRTS("IDE: IO=0x$") - LD A,IDEDATA - CALL PRTHEXBYTE - PRTS(" UNITS=2$") -; - CALL IDE_RESET - XOR A - DEC A ; INITIAL STATUS IS NOT READY $FF - LD (IDE_STAT),A ; SAVE IT - RET -; -; -; -IDE_STATUS: - LD A,(IDE_STAT) ; LOAD STATUS - OR A ; SET FLAGS - RET -; -; -; -IDE_READ: - LD A,IDECMD_READ - LD (IDE_CMD),A - JP IDE_RW -; -; -; -IDE_WRITE: - LD A,IDECMD_WRITE - LD (IDE_CMD),A - JP IDE_RW -; -; -; -IDE_RW: - ; CLEAR RESULTS - XOR A ; A = 0 - LD (IDE_RC),A ; CLEAR RETURN CODE - LD (IDE_STTS),A ; CLEAR SAVED STTS - LD (IDE_ERRS),A ; CLEAR SAVED ERR - - ; INIT REQUIRED? - LD A,(IDE_STAT) ; GET CURRENT STATUS - OR A ; SET FLAGS - JR Z,IDE_RW0 ; IF STATUS OK, BYPASS RESET - - CALL IDE_RESET ; DO THE RESET - -#IF (IDE8BIT) - CALL IDE_WAITRDY - - LD A,01H - OUT (IDEERR),A - LD A,IDECMD_SETFEAT - OUT (IDESTTS),A - CALL IDE_WAITRDY - JP NC,IDE_ERR - CALL IDE_CHKERR ; CHECK FOR ERRORS - JP NC,IDE_ERR -#IF (IDETRACE >= 2) - CALL IDE_PRT -#ENDIF -#ENDIF - -IDE_RW0: - CALL IDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,IDE_ERR - CALL IDE_SETUP ; SETUP CYL, TRK, HEAD - LD A,(IDE_CMD) - OUT (IDESTTS),A - CALL IDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,IDE_ERR - CALL IDE_CHKERR ; CHECK FOR ERRORS - JP NC,IDE_ERR - CALL IDE_WAITBUF ; WAIT FOR BUFFER READY - JP NC,IDE_ERR - - LD A,(IDE_CMD) ; DISPATCH TO READ OR WRITE SPECIFIC LOGIC - CP IDECMD_WRITE - JP Z,IDE_RW1 - - CALL IDE_BUFRD ; READ BUFFER - CALL IDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,IDE_ERR - CALL IDE_CHKERR ; CHECK FOR ERRORS - JP NC,IDE_ERR - JP IDE_OK - -IDE_RW1: - CALL IDE_BUFWR ; WRITE BUFFER - CALL IDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,IDE_ERR - CALL IDE_CHKERR ; CHECK FOR ERRORS - JP NC,IDE_ERR - JP IDE_OK - -IDE_ERR: - XOR A - DEC A ; A = $FF TO SIGNAL ERROR - LD (IDE_STAT),A ; SAVE IT -#IF (IDETRACE >= 1) - PUSH AF - CALL IDE_PRT - POP AF -#ENDIF - RET - -IDE_OK: -#IF (IDETRACE >= 2) - CALL IDE_PRT -#ENDIF - XOR A - RET -; -; -; -IDE_RESET: - LD A,000001110B ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES - OUT (IDECTRL),A - LD DE,8 ; DELAY ABOUT 200ms - CALL VDELAY - LD A,000001010B ; NO INTERRUPTS, DEASSERT RESET - OUT (IDECTRL),A - XOR A - LD (IDE_STAT),A ; STATUS OK - RET ; SAVE IT -; -; -; -IDE_WAITRDY: - LD DE,0 ; TIMEOUT IS 250us * 65536 = 15 SECONDS -IDE_WBSY: - PUSH DE - LD DE,10 ; INNER LOOP DELAY IS 250us (25us * 10) - CALL VDELAY - POP DE - DEC DE - LD A,D - OR E - JP Z,IDE_TO - IN A,(IDESTTS) ; READ STATUS - LD (IDE_STTS),A ; SAVE IT - AND 011000000b ; ISOLATE BUSY AND RDY BITS - XOR 001000000b ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 - JP NZ,IDE_WBSY - SCF ; CARRY 1 = OK - RET -IDE_TO: - LD A,IDERC_RDYTO - LD (IDE_RC),A - XOR A ; CARRY 0 = TIMEOUT - RET -; -; -; -IDE_CHKERR: - IN A,(IDESTTS) ; GET STATUS - LD (IDE_STTS),A ; SAVE IT - AND 000000001B ; ERROR BIT SET? - SCF ; ASSUME NO ERR - RET Z ; NO ERR, RETURN WITH CF SET - - IN A,(IDEERR) ; READ ERROR FLAGS - LD (IDE_ERRS),A ; SAVE IT - - LD A,IDERC_CMDERR ; COMMAND ERROR - LD (IDE_RC),A ; SAVE IT - - OR A ; CLEAR CF TO SIGNAL ERROR - RET -; -; -; -IDE_WAITBUF: - LD DE,0 -IDE_WDRQ: - CALL DELAY - INC DE - LD A,D - OR E - JP Z,IDE_TO2 - IN A,(IDESTTS) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER - LD (IDE_STTS),A ; SAVE IT - AND 000001000B ; TO FILL (OR READY TO FILL) - JP Z,IDE_WDRQ - SCF ; CARRY 1 = OK - RET -IDE_TO2: - LD A,IDERC_BUFTO - LD (IDE_RC),A - XOR A ; CARRY 0 = TIMED OUT - RET -; -; -; -IDE_BUFRD: - LD HL,(DIOBUF) - LD B,0 - -#IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE)) - LD C,IDEDATA - INIR - INIR -#ELSE - LD C,IDEDATAHI -IDE_BUFRD1: - IN A,(IDEDATALO) ; READ THE LO BYTE - LD (HL),A ; SAVE IN BUFFER - INC HL ; INC BUFFER POINTER - INI ; READ AND SAVE HI BYTE, INC HL, DEC B - JP NZ,IDE_BUFRD1 ; LOOP AS NEEDED -#ENDIF - RET -; -; -; -IDE_BUFWR: - LD HL,(DIOBUF) - LD B,0 - -#IF (IDE8BIT | (IDEMODE == IDEMODE_DIDE)) - LD C,IDEDATA - OTIR - OTIR -#ELSE - LD C,IDEDATAHI -IDE_BUFWR1: - LD A,(HL) ; GET THE LO BYTE AND KEEP IT IN A FOR LATER - INC HL ; BUMP TO NEXT BYTE IN BUFFER - OUTI ; WRITE HI BYTE, INC HL, DEC B - OUT (IDEDATALO),A ; NOW WRITE THE SAVED LO BYTE TO LO BYTE - JP NZ,IDE_BUFWR1 ; LOOP AS NEEDED -#ENDIF - RET -; -; -; -IDE_SETUP: - LD A,1 - OUT (IDESECTC),A - - LD A,(HSTDSK) ; HSTDSK -> HEAD BIT 4 TO SELECT UNIT - AND 0FH - CP 0 - JP Z,IDE_SETUP_UNIT0 - CP 1 - JP Z,IDE_SETUP_UNIT1 - CALL NC,PANIC -IDE_SETUP_UNIT0: - LD A,(IDE0_DEVICE) -; LD DE,(IDE0_OFFSET) - JP IDE_SETUP1 -IDE_SETUP_UNIT1: - LD A,(IDE1_DEVICE) -; LD DE,(IDE1_OFFSET) - JP IDE_SETUP1 -IDE_SETUP1: - LD (IDE_DEVICE),A - OUT (IDEDEVICE),A - - LD HL,(HSTTRK) ; HSTTRK -> IDECYLHI/LO - LD A,H - LD (IDE_CYLHI),A - OUT (IDECYLHI),A - LD A,L - LD (IDE_CYLLO),A - OUT (IDECYLLO),A - - LD BC,(HSTSEC) ; HSTSEC -> IDESECTN - LD A,C - LD (IDE_SEC),A - OUT (IDESECTN),A - -#IF (DSKYENABLE) - CALL IDE_DSKY -#ENDIF - - RET -; -; -; -#IF (DSKYENABLE) -IDE_DSKY: - LD HL,DSKY_HEXBUF - LD A,(IDE_DEVICE) - LD (HL),A - INC HL - LD A,(IDE_CYLHI) - LD (HL),A - INC HL - LD A,(IDE_CYLLO) - LD (HL),A - INC HL - LD A,(IDE_SEC) - LD (HL),A - CALL DSKY_HEXOUT - RET -#ENDIF -; -; -; -IDE_PRT: - CALL NEWLINE - - LD DE,IDESTR_PREFIX - CALL WRITESTR - - CALL PC_SPACE - LD DE,IDESTR_CMD - CALL WRITESTR - LD A,(IDE_CMD) - CALL PRTHEXBYTE - - CALL PC_SPACE - CALL PC_LBKT - LD A,(IDE_CMD) - LD DE,IDESTR_READ - CP IDECMD_READ - JP Z,IDE_PRTCMD - LD DE,IDESTR_WRITE - CP IDECMD_WRITE - JP Z,IDE_PRTCMD - LD DE,IDESTR_UNKCMD -IDE_PRTCMD: - CALL WRITESTR - CALL PC_RBKT - - CALL PC_SPACE - LD A,(IDE_DEVICE) - CALL PRTHEXBYTE - LD A,(IDE_CYLHI) - CALL PRTHEXBYTE - LD A,(IDE_CYLLO) - CALL PRTHEXBYTE - LD A,(IDE_SEC) - CALL PRTHEXBYTE - - CALL PC_SPACE - LD DE,IDESTR_ARROW - CALL WRITESTR - - CALL PC_SPACE - IN A,(IDESTTS) - CALL PRTHEXBYTE - - CALL PC_SPACE - IN A,(IDEERR) - CALL PRTHEXBYTE - - CALL PC_SPACE - LD DE,IDESTR_RC - CALL WRITESTR - LD A,(IDE_RC) - CALL PRTHEXBYTE - - CALL PC_SPACE - CALL PC_LBKT - LD A,(IDE_RC) - LD DE,IDESTR_RCOK - CP IDERC_OK - JP Z,IDE_PRTRC - LD DE,IDESTR_RCCMDERR - CP IDERC_CMDERR - JP Z,IDE_PRTRC - LD DE,IDESTR_RCRDYTO - CP IDERC_RDYTO - JP Z,IDE_PRTRC - LD DE,IDESTR_RCBUFTO - CP IDERC_BUFTO - JP Z,IDE_PRTRC - LD DE,IDESTR_RCUNK -IDE_PRTRC: - CALL WRITESTR - CALL PC_RBKT - - RET -; -; -; -IDESTR_PREFIX .TEXT "IDE:$" -IDESTR_CMD .TEXT "CMD=$" -IDESTR_RC .TEXT "RC=$" -IDESTR_ARROW .TEXT "-->$" -IDESTR_READ .TEXT "READ$" -IDESTR_WRITE .TEXT "WRITE$" -IDESTR_UNKCMD .TEXT "UNKCMD$" -IDESTR_RCOK .TEXT "OK$" -IDESTR_RCCMDERR .TEXT "COMMAND ERROR$" -IDESTR_RCRDYTO .TEXT "READY TIMEOUT$" -IDESTR_RCBUFTO .TEXT "BUFFER TIMEOUT$" -IDESTR_RCUNK .TEXT "UNKNOWN ERROR$" -; -;================================================================================================== -; IDE DISK DRIVER - DATA -;================================================================================================== -; -IDE_STAT .DB 0 -IDE_RC .DB 0 -; -IDE_CMD: .DB 0 -IDE_DEVICE .DB 0 -IDE_CYLHI: .DB 0 -IDE_CYLLO: .DB 0 -IDE_SEC: .DB 0 -IDE_STTS: .DB 0 -IDE_ERRS .DB 0 -; -; -; -; -; Error Register (ERR bit being set in the Status Register) -; -; Bit 7: BBK (Bad Block Detected) Set when a Bad Block is detected. -; Bit 6: UNC (Uncorrectable Data Error) Set when Uncorrectable Error is encountered. -; Bit 5: MC (Media Changed) Set to 0. -; Bit 4: IDNF (ID Not Found) Set when Sector ID not found. -; Bit 3: MCR (Media Change Request) Set to 0. -; Bit 2: ABRT (Aborted Command) Set when Command Aborted due to drive error. -; Bit 1: TKONF (Track 0 Not Found) Set when Executive Drive Diagnostic Command. -; Bit 0: AMNF (Address mark Not Found) Set in case of a general error. -; -; Status Register (When the contents of this register are read by the host, the IREQ# bit is cleared) -; -; Bit 7: BSY (Busy) Set when the drive is busy and unable to process any new ATA commands. -; Bit 6: DRDY (Data Ready) Set when the device is ready to accept ATA commands from the host. -; Bit 5: DWF (Drive Write Fault) Always set to 0. -; Bit 4: DSC (Drive Seek Complete) Set when the drive heads have been positioned over a specific track. -; Bit 3: DRQ (Data Request) Set when device is ready to transfer a word or byte of data to or from the host and the device. -; Bit 2: CORR (Corrected Data) Always set to 0. -; Bit 1: IDX (Index) Always set to 0. -; Bit 0: ERR (Error) Set when an error occurred during the previous ATA command. \ No newline at end of file diff --git a/branches/s100/Source/ide_data.asm b/branches/s100/Source/ide_data.asm deleted file mode 100644 index d4c20c90..00000000 --- a/branches/s100/Source/ide_data.asm +++ /dev/null @@ -1,61 +0,0 @@ -; -;================================================================================================== -; IDE DISK DRIVER - DATA -;================================================================================================== -; -IDE_SLICETRKS .EQU 65 ; TRACKS PER SLICE -IDE_TRKSIZE .EQU 128 ; SIZE OF TRACK (IN KB) -IDE_SLICESIZE .EQU ((IDE_SLICETRKS * IDE_TRKSIZE) + 1023) / 1024 ; SIZE OF EACH SLICE (IN MB) -IDE_NUMSLICES .EQU IDECAPACITY / IDE_SLICESIZE ; TOTAL SLICES IN DEVICE -IDE0_SLICEDEF .EQU 0 ; DEFAULT SLICE FOR UNIT 0 -IDE1_SLICEDEF .EQU 1 ; DEFAULT SLICE FOR UNIT 1 -IDE2_SLICEDEF .EQU 2 ; DEFAULT SLICE FOR UNIT 0 -IDE3_SLICEDEF .EQU 3 ; DEFAULT SLICE FOR UNIT 1 -; - .DB DIODEV_IDE + 0 -IDEDPH0 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW IDECSV0,IDEALV0 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -IDE0_SLICE .DW IDE0_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW IDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_IDE + 0 -IDEDPH1 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW IDECSV1,IDEALV1 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -IDE1_SLICE .DW IDE1_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW IDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_IDE + 0 -IDEDPH2 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW IDECSV2,IDEALV2 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -IDE2_SLICE .DW IDE2_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW IDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_IDE + 0 -IDEDPH3 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW IDECSV3,IDEALV3 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -IDE3_SLICE .DW IDE3_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW IDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; -IDECKS .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -IDEALS .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) -; -IDECSV0: .FILL IDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -IDEALV0: .FILL IDEALS ; MAX OF 2048 DATA BLOCKS -IDECSV1: .FILL IDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -IDEALV1: .FILL IDEALS ; MAX OF 2048 DATA BLOCKS -IDECSV2: .FILL IDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -IDEALV2: .FILL IDEALS ; MAX OF 2048 DATA BLOCKS -IDECSV3: .FILL IDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -IDEALV3: .FILL IDEALS ; MAX OF 2048 DATA BLOCKS diff --git a/branches/s100/Source/infolist.inc b/branches/s100/Source/infolist.inc deleted file mode 100644 index 1a062407..00000000 --- a/branches/s100/Source/infolist.inc +++ /dev/null @@ -1,24 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; infolist.inc 6/ 7/2012 dwg - removed DSK_MAP pointer ; -; infolist.inc 5/16/2012 dwg - BIOS information pointers ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; The putpose of this table is to provide pointers that can -; be used by utility programs to access BIOS internals for -; debugging and informative purposes. Any time the format -; changes, the first word should be incremented to the Apps -; can determine the lineage of a specific BIOS. This table -; was created in support of the 2.0.0.0 banked BIOS. - -INFOLIST: - .DW 2 ; INFOLIST version 2 6/7/2012 - .DW STR_BANNER - .DW VAR_LOC - .DW TST_LOC - .DW DPB_MAP - .DW DPH_MAP - .DW CIO_MAP - -;;;;;;;;;;;;;;;;;;;;;; -; eof - infolist.inc ; -;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/branches/s100/Source/kbd.asm b/branches/s100/Source/kbd.asm deleted file mode 100644 index a060cfbd..00000000 --- a/branches/s100/Source/kbd.asm +++ /dev/null @@ -1,754 +0,0 @@ -;__________________________________________________________________________________________________ -; -; 8242 BASED PS/2 KEYBOARD DRIVER FOR N8VEM -; -; ORIGINAL CODE BY DR JAMES MOXHAM -; ROMWBW ADAPTATION BY WAYNE WARTHEN -;__________________________________________________________________________________________________ -; -; TODO: -; CONSIDER DETECTING ERRORS IN STATUS BYTE (PERR, TO) -;__________________________________________________________________________________________________ -; DATA CONSTANTS -;__________________________________________________________________________________________________ -; -; IO PORTS -; -KBD_IOBASE .EQU $E0 -; -KBD_ST .EQU KBD_IOBASE + $0A -KBD_CMD .EQU KBD_IOBASE + $0A -KBD_DATA .EQU KBD_IOBASE + $02 -; -; TIMING CONSTANTS -; -KBD_WAITTO .EQU 150 -; -; STATUS BITS (FOR KBD_STATUS) -; -KBD_EXT .EQU 01H ; BIT 0, EXTENDED SCANCODE ACTIVE -KBD_BREAK .EQU 02H ; BIT 1, THIS IS A KEY UP (BREAK) EVENT -KBD_KEYRDY .EQU 80H ; BIT 7, INDICATES A DECODED KEYCODE IS READY -; -; STATE BITS (FOR KBD_STATE, KBD_LSTATE, KBD_RSTATE) -; -KBD_SHIFT .EQU 01H ; BIT 0, SHIFT ACTIVE (PRESSED) -KBD_CTRL .EQU 02H ; BIT 1, CONTROL ACTIVE (PRESSED) -KBD_ALT .EQU 04H ; BIT 2, ALT ACTIVE (PRESSED) -KBD_WIN .EQU 08H ; BIT 3, WIN ACTIVE (PRESSED) -KBD_SCRLCK .EQU 10H ; BIT 4, CAPS LOCK ACTIVE (TOGGLED ON) -KBD_NUMLCK .EQU 20H ; BIT 5, NUM LOCK ACTIVE (TOGGLED ON) -KBD_CAPSLCK .EQU 40H ; BIT 6, SCROLL LOCK ACTIVE (TOGGLED ON) -KBD_NUMPAD .EQU 80H ; BIT 7, NUM PAD KEY (KEY PRESSED IS ON NUM PAD) -; -KBD_DEFRPT .EQU $40 ; DEFAULT REPEAT RATE (.5 SEC DELAY, 30CPS) -KBD_DEFSTATE .EQU KBD_NUMLCK ; DEFAULT STATE (NUM LOCK ON) -; -;__________________________________________________________________________________________________ -; DATA -;__________________________________________________________________________________________________ -; -KBD_SCANCODE .DB 0 ; RAW SCANCODE -KBD_KEYCODE .DB 0 ; RESULTANT KEYCODE AFTER DECODING -KBD_STATE .DB 0 ; STATE BITS (SEE ABOVE) -KBD_LSTATE .DB 0 ; STATE BITS FOR "LEFT" KEYS -KBD_RSTATE .DB 0 ; STATE BITS FOR "RIGHT" KEYS -KBD_STATUS .DB 0 ; CURRENT STATUS BITS (SEE ABOVE) -KBD_REPEAT .DB 0 ; CURRENT REPEAT RATE -KBD_IDLE .DB 0 ; IDLE COUNT -; -;__________________________________________________________________________________________________ -; KEYBOARD INITIALIZATION -;__________________________________________________________________________________________________ -; -KBD_INIT: - PRTS("KBD: IO=0x$") - LD A,KBD_IOBASE - CALL PRTHEXBYTE -; - LD A,KBD_DEFRPT ; GET DEFAULT REPEAT RATE - LD (KBD_REPEAT),A ; SAVE IT - LD A,KBD_DEFSTATE ; GET DEFAULT STATE - LD (KBD_STATE),A ; SAVE IT - - LD A,$AA ; CONTROLLER SELF TEST - CALL KBD_PUTCMD ; SEND IT - CALL KBD_GETDATA ; CONTROLLER SHOULD RESPOND WITH $55 (ACK) - LD A,$60 ; SET COMMAND REGISTER - CALL KBD_PUTCMD ; SEND IT -; LD A,$60 ; XLAT ENABLED, MOUSE DISABLED, NO INTS - LD A,$20 ; XLAT DISABLED, MOUSE DISABLED, NO INTS - CALL KBD_PUTDATA ; SEND IT - - CALL KBD_GETDATA ; GOBBLE UP $AA FROM POWER UP, AS NEEDED - -; LD A,$AE ; COMMAND = ENABLE KEYBOARD -; CALL KBD_PUTCMD ; SEND IT -; LD A,$A7 ; COMMAND = DISABLE MOUSE -; CALL KBD_PUTCMD ; SEND IT - - CALL KBD_RESET ; RESET THE KEYBOARD - CALL KBD_SETLEDS ; UPDATE LEDS BASED ON CURRENT TOGGLE STATE BITS - CALL KBD_SETRPT ; UPDATE REPEAT RATE BASED ON CURRENT SETTING - - XOR A ; SIGNAL SUCCESS - RET -; -;__________________________________________________________________________________________________ -; KEYBOARD STATUS -;__________________________________________________________________________________________________ -; -KBD_STAT: - LD A,(KBD_STATUS) ; GET STATUS - AND KBD_KEYRDY ; ISOLATE READY BIT - JR NZ,KBD_STAT3 ; KEY READY, DONE - -KBD_STAT2: - CALL Z,KBD_DECODE ; NOT READY, RUN THE DECODING ENGINE - LD A,(KBD_STATUS) ; GET STATUS - AND KBD_KEYRDY ; ISOLATE READ BIT - -KBD_STAT3: - RLCA ; ROTATE READY BIT TO LOW ORDER BIT - RET -; -;__________________________________________________________________________________________________ -; KEYBOARD READ -; -; RETURNS ASCII VALUE IN E. SEE END OF FILE FOR VALUES RETURNED FOR SPECIAL KEYS -; LIKE PGUP, ARROWS, FUNCTION KEYS, ETC. -;__________________________________________________________________________________________________ -; -KBD_READ: - LD A,(KBD_STATUS) ; GET STATUS - AND KBD_KEYRDY ; ISOLIATE KEY READY BIT - JR NZ,KBD_READ1 ; READY, GO GET THE KEY AND RETURN - CALL KBD_DECODE ; TRY TO GET A KEY - JR KBD_READ ; AND LOOP -; -KBD_READ1: - LD A,(KBD_STATE) ; GET STATE - AND $01 ; ISOLATE EXTENDED SCANCODE BIT - RRCA ; ROTATE IT TO HIGH ORDER BIT - LD E,A ; SAVE IT IN E FOR NOW - LD A,(KBD_SCANCODE) ; GET SCANCODE - OR E ; COMBINE WITH EXTENDED BIT - LD C,A ; STORE IT IN C FOR RETURN - LD A,(KBD_KEYCODE) ; GET KEYCODE - LD E,A ; SAVE IT IN E - LD A,(KBD_STATE) ; GET STATE FLAGS - LD D,A ; SAVE THEM IN D - XOR A ; SIGNAL SUCCESS - LD (KBD_STATUS),A ; CLEAR STATUS TO INDICATE BYTE RECEIVED - RET -; -;__________________________________________________________________________________________________ -; KEYBOARD FLUSH -;__________________________________________________________________________________________________ -; -KBD_FLUSH: - XOR A ; A = 0 - LD (KBD_STATUS),A ; CLEAR STATUS - RET -; -;__________________________________________________________________________________________________ -; HARDWARE INTERFACE -;__________________________________________________________________________________________________ -; -;__________________________________________________________________________________________________ -KBD_IST: -; -; KEYBOARD INPUT STATUS -; A=0, Z SET FOR NOTHING PENDING, OTHERWISE DATA PENDING -; - IN A,(KBD_ST) ; GET STATUS - AND $01 ; ISOLATE INPUT PENDING BIT - RET -; -;__________________________________________________________________________________________________ -KBD_OST: -; -; KEYBOARD OUTPUT STATUS -; A=0, Z SET FOR NOT READY, OTHERWISE READY TO WRITE -; - IN A,(KBD_ST) ; GET STATUS - AND $02 ; ISOLATE OUTPUT EMPTY BIT - XOR $02 ; FLIP IT FOR APPROPRIATE RETURN VALUES - RET -; -;__________________________________________________________________________________________________ -KBD_PUTCMD: -; -; PUT A CMD BYTE FROM A TO THE KEYBOARD INTERFACE WITH TIMEOUT -; - LD E,A ; SAVE INCOMING VALUE IN E - LD B,KBD_WAITTO ; SETUP TO LOOP -KBD_PUTCMD0: - CALL KBD_OST ; GET OUTPUT REGISTER STATUS - JR NZ,KBD_PUTCMD1 ; EMPTY, GO TO WRITE - CALL DELAY ; WAIT A BIT - DJNZ KBD_PUTCMD0 ; LOOP UNTIL COUNTER EXHAUSTED - RET -KBD_PUTCMD1: - LD A,E ; RECOVER VALUE TO WRITE -#IF (KBDTRACE >= 2) - CALL PC_SPACE - CALL PC_GT - CALL PC_GT - CALL PRTHEXBYTE -#ENDIF - OUT (KBD_CMD),A ; WRITE IT - XOR A ; SIGNAL SUCCESS - RET -; -;__________________________________________________________________________________________________ -KBD_PUTDATA: -; -; PUT A DATA BYTE FROM A TO THE KEYBOARD INTERFACE WITH TIMEOUT -; - LD E,A ; SAVE INCOMING VALUE IN E - LD B,KBD_WAITTO ; SETUP TO LOOP -KBD_PUTDATA0: - CALL KBD_OST ; GET OUTPUT REGISTER STATUS - JR NZ,KBD_PUTDATA1 ; EMPTY, GO TO WRITE - CALL DELAY ; WAIT A BIT - DJNZ KBD_PUTDATA0 ; LOOP UNTIL COUNTER EXHAUSTED - RET -KBD_PUTDATA1: - LD A,E ; RECOVER VALUE TO WRITE -#IF (KBDTRACE >= 2) - CALL PC_SPACE - CALL PC_GT - CALL PRTHEXBYTE -#ENDIF - OUT (KBD_DATA),A ; WRITE IT - XOR A ; SIGNAL SUCCESS - RET -; -;__________________________________________________________________________________________________ -KBD_GETDATA: -; -; GET A RAW DATA BYTE FROM KEYBOARD INTERFACE INTO A WITH TIMEOUT -; - LD B,KBD_WAITTO ; SETUP TO LOOP -KBD_GETDATA0: - CALL KBD_IST ; GET INPUT REGISTER STATUS - JR NZ,KBD_GETDATA1 ; BYTE PENDING, GO GET IT - CALL DELAY ; WAIT A BIT - DJNZ KBD_GETDATA0 ; LOOP UNTIL COUNTER EXHAUSTED - XOR A ; NO DATA, RETURN ZERO - RET -KBD_GETDATA1: - IN A,(KBD_DATA) ; GET THE DATA VALUE -#IF (KBDTRACE >= 2) - PUSH AF - CALL PC_SPACE - CALL PC_LT - CALL PRTHEXBYTE - POP AF -#ENDIF - OR A ; SET FLAGS - RET -; -;__________________________________________________________________________________________________ -; RESET KEYBOARD -;__________________________________________________________________________________________________ -; -KBD_RESET: - LD A,$FF ; RESET COMMAND - CALL KBD_PUTDATA ; SEND IT - CALL KBD_GETDATA ; GET THE ACK - LD B,0 ; SETUP LOOP COUNTER -KBD_RESET0: - PUSH BC ; PRESERVE COUNTER - CALL KBD_GETDATA ; TRY TO GET THE RESPONSE - POP BC ; RECOVER COUNTER - JR NZ,KBD_RESET1 ; GOT A BYTE? IF SO, GET OUT OF LOOP - DJNZ KBD_RESET0 ; LOOP TILL COUNTER EXHAUSTED -KBD_RESET1: - LD A,B - XOR A ; SIGNAL SUCCESS (RESPONSE IS IGNORED...) - RET ; DONE -; -;__________________________________________________________________________________________________ -; UPDATE KEYBOARD LEDS BASED ON CURRENT TOGGLE FLAGS -;__________________________________________________________________________________________________ -; -KBD_SETLEDS: - LD A,$ED ; SET/RESET LED'S COMMAND - CALL KBD_PUTDATA ; SEND THE COMMAND - CALL KBD_GETDATA ; READ THE RESPONSE - CP $FA ; MAKE SURE WE GET ACK - RET NZ ; ABORT IF NO ACK - LD A,(KBD_STATE) ; LOAD THE STATE BYTE - RRCA ; ROTATE TOGGLE KEY BITS AS NEEDED - RRCA - RRCA - RRCA - AND $07 ; CLEAR THE IRRELEVANT BITS - CALL KBD_PUTDATA ; SEND THE LED DATA - CALL KBD_GETDATA ; READ THE ACK - JP KBD_DECNEW ; RESTART DECODER FOR A NEW KEY - RET ; DONE -; -;__________________________________________________________________________________________________ -; UPDATE KEYBOARD REPEAT RATE BASED ON CURRENT SETTING -;__________________________________________________________________________________________________ -; -KBD_SETRPT: - LD A,$F3 ; COMMAND = SET TYPEMATIC RATE/DELAY - CALL KBD_PUTDATA ; SEND IT - CALL KBD_GETDATA ; GET THE ACK - CP $FA ; MAKE SURE WE GET ACK - RET NZ ; ABORT IF NO ACK - LD A,(KBD_REPEAT) ; LOAD THE CURRENT RATE/DELAY BYTE - CALL KBD_PUTDATA ; SEND IT - CALL KBD_GETDATA ; GET THE ACK - RET -; -;__________________________________________________________________________________________________ -; DECODING ENGINE -;__________________________________________________________________________________________________ -; -;__________________________________________________________________________________________________ -KBD_DECODE: -; -; RUN THE DECODING ENGINE UNTIL EITHER: 1) NO MORE SCANCODES ARE AVAILABLE -; FROM THE KEYBOARD, OR 2) A DECODED KEY VALUE IS AVAILABLE -; -; RETURNS A=0 AND Z SET IF NO KEYCODE READY, OTHERWISE A DECODED KEY VALUE IS AVAILABLE. -; THE DECODED KEY VALUE AND KEY STATE IS STORED IN KBD_KEYCODE AND KBD_STATE. -; -; KBD_STATUS IS NOT CLEARED AT START. IT IS THE CALLER'S RESPONSIBILITY -; TO CLEAR KBD_STATUS WHEN IT HAS RETRIEVED A PENDING VALUE. IF DECODE IS CALLED -; WITH A KEYCODE STILL PENDING, IT WILL JUST RETURN WITHOUT DOING ANYTHING. -; -; Step 0: Check keycode buffer -; if status[keyrdy] -; return -; -; Step 1: Get scancode -; if no scancode ready -; return -; read scancode -; -; Step 2: Detect and handle special keycodes -; if scancode == $AA -; *** handle hot insert somehow *** -; -; Step 3: Detect and handle scancode prefixes -; if scancode == $E0 -; set status[extended] -; goto Step 1 -; -; if scancode == $E1 -; *** handle pause key somehow *** -; -; Step 4: Detect and flag break event -; *** scancode set #1 variation *** -; set status[break] = high bit of scancode -; clear high order bit -; continue to Step 5 -; *** scancode set #2 variation *** -; if scancode == $F0 -; set status[break] -; goto Step 1 -; -; Step 5: Map scancode to keycode -; if status[extended] -; apply extended-map[scancode] -> keycode -; else if state[shifted] -; apply shifted-map[scancode] -> keycode -; else -; apply normal-map[scancode] -> keycode -; -; Step 6: Handle modifier keys -; if keycode is modifier (shift, ctrl, alt, win) -; set (l/r)state[] = not status[break] -; clear modifier bits in state -; set state = (lstate OR rstate OR state) -; goto New Key -; -; Step 7: Complete procesing of key break events -; if status[break] -; goto New Key -; -; Step 8: Handle toggle keys -; if keycode is toggle (capslock, numlock, scrolllock) -; invert (XOR) state[] -; update keyboard LED's -; goto New Key -; -; Step 9: Adjust keycode for control modifier -; if state[ctrl] -; if keycode is 'a'-'z' -; subtract 20 (clear bit 5) from keycode -; if keycode is '@'-'_' -; subtract 40 (clear bit 6) from keycode -; -; Step 10: Adjust keycode for caps lock -; if state[capslock] -; if keycode is 'a'-'z' OR 'A'-'Z' -; toggle (XOR) bit 5 of keycode -; -; Step 11: Handle num pad keys -; clear state[numpad] -; if keycode is numpad -; set state[numpad] -; if state[numlock] -; toggle (XOR) bit 4 of keycode -; apply numpad-map[keycode] -> keycode -; -; Step 12: Detect unknown/invalid keycodes -; if keycode == $FF -; goto New Key -; -; Step 13: Done -; set status[keyrdy] -; return -; -; New Key: -; clear status -; goto Step 1 -; -KBD_DEC0: ; CHECK KEYCODE BUFFER - LD A,(KBD_STATUS) ; GET CURRENT STATUS - AND KBD_KEYRDY ; ISOLATE KEY READY FLAG - RET NZ ; ABORT IF KEY IS ALREADY PENDING - -KBD_DEC1: ; PROCESS NEXT SCANCODE - CALL KBD_IST ; IS A SCANCODE WAITING? - RET Z ; NOPE, ABORT - CALL KBD_GETDATA ; GET THE SCANCODE - RET Z ; TIMEOUT, RETURN WITH A=0, Z SET - LD (KBD_SCANCODE),A ; SAVE SCANCODE - -KBD_DEC2: ; DETECT AND HANDLE SPECIAL KEYCODES - LD A,(KBD_SCANCODE) ; GET THE CURRENT SCANCODE - CP $AA ; KEYBOARD INSERTION? - JR NZ,KBD_DEC3 ; NOPE, BYPASS - CALL LDELAY ; WAIT A BIT - CALL KBD_RESET ; RESET KEYBOARD - CALL KBD_SETLEDS ; SET LEDS - CALL KBD_SETRPT ; SET REPEAT RATE - JP KBD_DECNEW ; RESTART THE ENGINE - -KBD_DEC3: ; DETECT AND HANDLE SCANCODE PREFIXES - LD A,(KBD_SCANCODE) ; GET THE CURRENT SCANCODE - -KBD_DEC3A: ; HANDLE SCANCODE PREFIX $E0 (EXTENDED SCANCODE FOLLOWS) - CP $E0 ; EXTENDED KEY PREFIX $E0? - JR NZ,KBD_DEC3B ; NOPE MOVE ON - LD A,(KBD_STATUS) ; GET STATUS - OR KBD_EXT ; SET EXTENDED BIT - LD (KBD_STATUS),A ; SAVE STATUS - JR KBD_DEC1 ; LOOP TO DO NEXT SCANCODE - -KBD_DEC3B: ; HANDLE SCANCODE PREFIX $E1 (PAUSE KEY) - CP $E1 ; EXTENDED KEY PREFIX $E1 - JR NZ,KBD_DEC4 ; NOPE MOVE ON - LD A,$EE ; MAP TO KEYCODE $EE - LD (KBD_KEYCODE),A ; SAVE IT - ; SWALLOW NEXT 7 SCANCODES - LD B,7 ; LOOP 5 TIMES -KBD_DEC3B1: - PUSH BC - CALL KBD_GETDATA ; RETRIEVE NEXT SCANCODE - POP BC - DJNZ KBD_DEC3B1 ; LOOP AS NEEDED - JP KBD_DEC6 ; RESUME AFTER MAPPING - -KBD_DEC4: ; DETECT AND FLAG BREAK EVENT - CP $F0 ; BREAK (KEY UP) PREFIX? - JR NZ,KBD_DEC5 ; NOPE MOVE ON - LD A,(KBD_STATUS) ; GET STATUS - OR KBD_BREAK ; SET BREAK BIT - LD (KBD_STATUS),A ; SAVE STATUS - JR KBD_DEC1 ; LOOP TO DO NEXT SCANCODE - -KBD_DEC5: ; MAP SCANCODE TO KEYCODE - LD A,(KBD_STATUS) ; GET STATUS - AND KBD_EXT ; EXTENDED BIT SET? - JR Z,KBD_DEC5C ; NOPE, MOVE ON - - ; PERFORM EXTENDED KEY MAPPING - LD A,(KBD_SCANCODE) ; GET SCANCODE - LD E,A ; STASH IT IN E - LD HL,KBD_MAPEXT ; POINT TO START OF EXT MAP TABLE -KBD_DEC5A: - LD A,(HL) ; GET FIRST BYTE OF PAIR - CP $00 ; END OF TABLE? - JP Z,KBD_DECNEW ; UNKNOWN OR BOGUS, START OVER - INC HL ; INC HL FOR FUTURE - CP E ; DOES MATCH BYTE EQUAL SCANCODE? - JR Z,KBD_DEC5B ; YES! JUMP OUT - INC HL ; BUMP TO START OF NEXT PAIR - JR KBD_DEC5A ; LOOP TO CHECK NEXT TABLE ENTRY -KBD_DEC5B: - LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE - LD (KBD_KEYCODE),A ; SAVE IT - JR KBD_DEC6 - -KBD_DEC5C: ; PERFORM REGULAR KEY (NOT EXTENDED) KEY MAPPING - LD A,(KBD_SCANCODE) ; GET THE SCANCODE - CP KBD_MAPSIZ ; COMPARE TO SIZE OF TABLE - JR NC,KBD_DEC6 ; PAST END, SKIP OVER LOOKUP - - ; SETUP POINTER TO MAPPING TABLE BASED ON SHIFTED OR UNSHIFTED STATE - LD A,(KBD_STATE) ; GET STATE - AND KBD_SHIFT ; SHIFT ACTIVE? - LD HL,KBD_MAPSTD ; LOAD ADDRESS OF NON-SHIFTED MAPPING TABLE - JR Z,KBD_DEC5D ; NON-SHIFTED, MOVE ON - LD HL,KBD_MAPSHIFT ; LOAD ADDRESS OF SHIFTED MAPPING TABLE -KBD_DEC5D: - LD A,(KBD_SCANCODE) ; GET THE SCANCODE - LD E,A ; SCANCODE TO E FOR TABLE OFFSET - LD D,0 ; D -> 0 - ADD HL,DE ; COMMIT THE TABLE OFFSET TO HL - LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE - LD (KBD_KEYCODE),A ; SAVE IT - -KBD_DEC6: ; HANDLE MODIFIER KEYS - LD A,(KBD_KEYCODE) ; MAKE SURE WE HAVE KEYCODE - CP $B8 ; END OF MODIFIER KEYS - JR NC,KBD_DEC7 ; BYPASS MODIFIER KEY CHECKING - CP $B0 ; START OF MODIFIER KEYS - JR C,KBD_DEC7 ; BYPASS MODIFIER KEY CHECKING - - LD B,4 ; LOOP COUNTER TO LOOP THRU 4 MODIFIER BITS - LD E,$80 ; SETUP E TO ROATE THROUGH MODIFIER STATE BITS - SUB $B0 - 1 ; SETUP A TO DECREMENT THROUGH MODIFIER VALUES - -KBD_DEC6A: - RLC E ; SHIFT TO NEXT MODIFIER STATE BIT - DEC A ; L-MODIFIER? - JR Z,KBD_DEC6B ; YES, HANDLE L-MODIFIER MAKE/BREAK - DEC A ; R-MODIFIER? - JR Z,KBD_DEC6C ; YES, HANDLE R-MODIFIER MAKE/BREAK - DJNZ KBD_DEC6A ; LOOP THRU 4 MODIFIER BITS - JR KBD_DEC7 ; FAILSAFE, SHOULD NEVER GET HERE! - -KBD_DEC6B: ; LEFT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) - LD HL,KBD_LSTATE ; POINT TO LEFT STATE BYTE - JR KBD_DEC6D ; CONTINUE - -KBD_DEC6C: ; RIGHT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) - LD HL,KBD_RSTATE ; POINT TO RIGHT STATE BYTE - JR KBD_DEC6D ; CONTINUE - -KBD_DEC6D: ; BRANCH BASED ON WHETHER THIS IS A MAKE OR BREAK EVENT - LD A,(KBD_STATUS) ; GET STATUS FLAGS - AND KBD_BREAK ; BREAK EVENT? - JR Z,KBD_DEC6E ; NO, HANDLE A MODIFIER KEY MAKE EVENT - JR KBD_DEC6F ; YES, HANDLE A MODIFIER BREAK EVENT - -KBD_DEC6E: ; HANDLE STATE KEY MAKE EVENT - LD A,E ; GET THE BIT TO SET - OR (HL) ; OR IN THE CURRENT BITS - LD (HL),A ; SAVE THE RESULT - JR KBD_DEC6G ; CONTINUE - -KBD_DEC6F: ; HANDLE STATE KEY BREAK EVENT - LD A,E ; GET THE BIT TO CLEAR - XOR $FF ; FLIP ALL BITS TO SETUP FOR A CLEAR OPERATION - AND (HL) ; AND IN THE FLIPPED BITS TO CLEAR DESIRED BIT - LD (HL),A ; SAVE THE RESULT - JR KBD_DEC6G ; CONTINUE - -KBD_DEC6G: ; COALESCE L/R STATE FLAGS - LD A,(KBD_STATE) ; GET EXISTING STATE BITS - AND $F0 ; GET RID OF OLD MODIFIER BITS - LD DE,(KBD_LSTATE) ; LOAD BOTH L/R STATE BYTES IN D/E - OR E ; MERGE IN LEFT STATE BITS - OR D ; MERGE IN RIGHT STATE BITS - LD (KBD_STATE),A ; SAVE IT - JP KBD_DECNEW ; DONE WITH CURRENT KEYSTROKE - -KBD_DEC7: ; COMPLETE PROCESSING OF EXTENDED AND KEY BREAK EVENTS - LD A,(KBD_STATUS) ; GET CURRENT STATUS FLAGS - AND KBD_BREAK ; IS THIS A KEY BREAK EVENT? - JP NZ,KBD_DECNEW ; PROCESS NEXT KEY - -KBD_DEC8: ; HANDLE TOGGLE KEYS - LD A,(KBD_KEYCODE) ; GET THE CURRENT KEYCODE INTO A - LD E,KBD_CAPSLCK ; SETUP E WITH CAPS LOCK STATE BIT - CP $BC ; IS THIS THE CAPS LOCK KEY? - JR Z,KBD_DEC8A ; YES, GO TO BIT SET ROUTINE - LD E,KBD_NUMLCK ; SETUP E WITH NUM LOCK STATE BIT - CP $BD ; IS THIS THE NUM LOCK KEY? - JR Z,KBD_DEC8A ; YES, GO TO BIT SET ROUTINE - LD E,KBD_SCRLCK ; SETUP E WITH SCROLL LOCK STATE BIT - CP $BE ; IS THIS THE SCROLL LOCK KEY? - JR Z,KBD_DEC8A ; YES, GO TO BIT SET ROUTINE - JR KBD_DEC9 ; NOT A TOGGLE KEY, CONTINUE - -KBD_DEC8A: ; RECORD THE TOGGLE - LD A,(KBD_STATE) ; GET THE CURRENT STATE FLAGS - XOR E ; SET THE TOGGLE KEY BIT FROM ABOVE - LD (KBD_STATE),A ; SAVE IT - CALL KBD_SETLEDS ; UPDATE LED LIGHTS ON KBD - JP KBD_DECNEW ; RESTART DECODER FOR A NEW KEY - -KBD_DEC9: ; ADJUST KEYCODE FOR CONTROL MODIFIER - LD A,(KBD_STATE) ; GET THE CURRENT STATE BITS - AND KBD_CTRL ; CHECK THE CONTROL BIT - JR Z,KBD_DEC10 ; CONTROL KEY NOT PRESSED, MOVE ON - LD A,(KBD_KEYCODE) ; GET CURRENT KEYCODE IN A - CP 'a' ; COMPARE TO LOWERCASE A - JR C,KBD_DEC9A ; BELOW IT, BYPASS - CP 'z' + 1 ; COMPARE TO LOWERCASE Z - JR NC,KBD_DEC9A ; ABOVE IT, BYPASS - RES 5,A ; KEYCODE IN LOWERCASE A-Z RANGE CLEAR BIT 5 TO MAKE IT UPPERCASE -KBD_DEC9A: - CP '@' ; COMPARE TO @ - JR C,KBD_DEC10 ; BELOW IT, BYPASS - CP '_' + 1 ; COMPARE TO _ - JR NC,KBD_DEC10 ; ABOVE IT, BYPASS - RES 6,A ; CONVERT TO CONTROL VALUE BY CLEARING BIT 6 - LD (KBD_KEYCODE),A ; UPDATE KEYCODE TO CONTROL VALUE - -KBD_DEC10: ; ADJUST KEYCODE FOR CAPS LOCK - LD A,(KBD_STATE) ; LOAD THE STATE FLAGS - AND KBD_CAPSLCK ; CHECK CAPS LOCK - JR Z,KBD_DEC11 ; CAPS LOCK NOT ACTIVE, MOVE ON - LD A,(KBD_KEYCODE) ; GET THE CURRENT KEYCODE VALUE - CP 'a' ; COMPARE TO LOWERCASE A - JR C,KBD_DEC10A ; BELOW IT, BYPASS - CP 'z' + 1 ; COMPARE TO LOWERCASE Z - JR NC,KBD_DEC10A ; ABOVE IT, BYPASS - JR KBD_DEC10B ; IN RANGE LOWERCASE A-Z, GO TO CASE SWAPPING LOGIC -KBD_DEC10A: - CP 'A' ; COMPARE TO UPPERCASE A - JR C,KBD_DEC11 ; BELOW IT, BYPASS - CP 'Z' + 1 ; COMPARE TO UPPERCASE Z - JR NC,KBD_DEC11 ; ABOVE IT, BYPASS - JR KBD_DEC10B ; IN RANGE UPPERCASE A-Z, GO TO CASE SWAPPING LOGIC -KBD_DEC10B: - LD A,(KBD_KEYCODE) ; GET THE CURRENT KEYCODE - XOR $20 ; FLIP BIT 5 TO SWAP UPPER/LOWER CASE - LD (KBD_KEYCODE),A ; SAVE IT - -KBD_DEC11: ; HANDLE NUM PAD KEYS - LD A,(KBD_STATE) ; GET THE CURRENT STATE FLAGS - AND ~KBD_NUMPAD ; ASSUME NOT A NUMPAD KEY, CLEAR THE NUMPAD BIT - LD (KBD_STATE),A ; SAVE IT - - LD A,(KBD_KEYCODE) ; GET THE CURRENT KEYCODE - AND 11100000B ; ISOLATE TOP 3 BITS - CP 11000000B ; IS IN NUMPAD RANGE? - JR NZ,KBD_DEC12 ; NOPE, GET OUT - - LD A,(KBD_STATE) ; LOAD THE CURRENT STATE FLAGS - OR KBD_NUMPAD ; TURN ON THE NUMPAD BIT - LD (KBD_STATE),A ; SAVE IT - - AND KBD_NUMLCK ; IS NUM LOCK BIT SET? - JR Z,KBD_DEC11A ; NO, SKIP NUMLOCK PROCESSING - LD A,(KBD_KEYCODE) ; GET THE KEYCODE - XOR $10 ; FLIP VALUES FOR NUMLOCK - LD (KBD_KEYCODE),A ; SAVE IT - -KBD_DEC11A: ; APPLY NUMPAD MAPPING - LD A,(KBD_KEYCODE) ; GET THE CURRENT KEYCODE - LD HL,KBD_MAPNUMPAD ; LOAD THE START OF THE MAPPING TABLE - SUB $C0 ; KEYCODES START AT $C0 - LD E,A ; INDEX TO E - LD D,0 ; D IS ZERO - ADD HL,DE ; POINT TO RESULT OF MAPPING - LD A,(HL) ; GET IT IN A - LD (KBD_KEYCODE),A ; SAVE IT - -KBD_DEC12: ; DETECT UNKNOWN/INVALID KEYCODES - LD A,(KBD_KEYCODE) ; GET THE FINAL KEYCODE - CP $FF ; IS IT $FF (UNKNOWN/INVALID) - JP Z,KBD_DECNEW ; IF SO, JUST RESTART THE ENGINE - -KBD_DEC13: ; DONE - RECORD RESULTS - LD A,(KBD_STATUS) ; GET CURRENT STATUS - OR KBD_KEYRDY ; SET KEY READY BIT - LD (KBD_STATUS),A ; SAVE IT - XOR A ; A=0 - INC A ; SIGNAL SUCCESS WITH A=1 - RET - -KBD_DECNEW: ; START NEW KEYPRESS (CLEAR ALL STATUS BITS) - XOR A ; A = 0 - LD (KBD_STATUS),A ; CLEAR STATUS - JP KBD_DEC1 ; RESTART THE ENGINE -; -;__________________________________________________________________________________________________ -; MAPPING TABLES -;__________________________________________________________________________________________________ -; -KBD_MAPSTD: ; SCANCODE IS INDEX INTO TABLE TO RESULTANT LOOKUP KEYCODE - .DB $FF,$E8,$FF,$E4,$E2,$E0,$E1,$EB,$FF,$E9,$E7,$E5,$E3,$09,'`',$FF - .DB $FF,$B4,$B0,$FF,$B2,'q','1',$FF,$FF,$FF,'z','s','a','w','2',$FF - .DB $FF,'c','x','d','e','4','3',$FF,$FF,' ','v','f','t','r','5',$FF - .DB $FF,'n','b','h','g','y','6',$FF,$FF,$FF,'m','j','u','7','8',$FF - .DB $FF,',','k','i','o','0','9',$FF,$FF,'.','/','l',';','p','-',$FF - .DB $FF,$FF,$27,$FF,'[','=',$FF,$FF,$BC,$B1,$0D,']',$FF,'\',$FF,$FF - .DB $FF,$FF,$FF,$FF,$FF,$FF,$08,$FF,$FF,$C0,$FF,$C3,$C6,$FF,$FF,$FF - .DB $C9,$CA,$C1,$C4,$C5,$C7,$1B,$BD,$FA,$CE,$C2,$CD,$CC,$C8,$BE,$FF - .DB $FF,$FF,$FF,$E6,$EC -; -KBD_MAPSIZ .EQU ($ - KBD_MAPSTD) -; -KBD_MAPSHIFT: ; SCANCODE IS INDEX INTO TABLE TO RESULTANT LOOKUP KEYCODE WHEN SHIFT ACTIVE - .DB $FF,$E8,$FF,$E4,$E2,$E0,$E1,$EB,$FF,$E9,$E7,$E5,$E3,$09,'~',$FF - .DB $FF,$B4,$B0,$FF,$B2,'Q','!',$FF,$FF,$FF,'Z','S','A','W','@',$FF - .DB $FF,'C','X','D','E','$','#',$FF,$FF,' ','V','F','T','R','%',$FF - .DB $FF,'N','B','H','G','Y','^',$FF,$FF,$FF,'M','J','U','&','*',$FF - .DB $FF,'<','K','I','O',')','(',$FF,$FF,'>','?','L',':','P','_',$FF - .DB $FF,$FF,$22,$FF,'{','+',$FF,$FF,$BC,$B1,$0D,'}',$FF,'|',$FF,$FF - .DB $FF,$FF,$FF,$FF,$FF,$FF,$08,$FF,$FF,$D0,$FF,$D3,$D6,$FF,$FF,$FF - .DB $D9,$DA,$D1,$D4,$D5,$D7,$1B,$BD,$FA,$DE,$D2,$DD,$DC,$D8,$BE,$FF - .DB $FF,$FF,$FF,$E6,$EC -; -KBD_MAPEXT: ; PAIRS ARE [SCANCODE,KEYCODE] FOR EXTENDED SCANCODES - .DB $11,$B5, $14,$B3, $1F,$B6, $27,$B7 - .DB $2F,$EF, $37,$FA, $3F,$FB, $4A,$CB - .DB $5A,$CF, $5E,$FC, $69,$F3, $6B,$F8 - .DB $6C,$F2, $70,$F0, $71,$F1, $72,$F7 - .DB $74,$F9, $75,$F6, $7A,$F5, $7C,$ED - .DB $7D,$F4, $7E,$FD, $00,$00 -; -KBD_MAPNUMPAD: ; KEYCODE TRANSLATION FROM NUMPAD RANGE TO STD ASCII/KEYCODES - .DB $F3,$F7,$F5,$F8,$FF,$F9,$F2,$F6,$F4,$F0,$F1,$2F,$2A,$2D,$2B,$0D - .DB $31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$2E,$2F,$2A,$2D,$2B,$0D -; -;__________________________________________________________________________________________________ -; KEYCODE VALUES RETURNED BY THE DECODER -;__________________________________________________________________________________________________ -; -; VALUES 0-127 ARE STANDARD ASCII, SPECIAL KEYS WILL HAVE THE FOLLOWING VALUES: -; -; F1 $E0 -; F2 $E1 -; F3 $E2 -; F4 $E3 -; F5 $E4 -; F6 $E5 -; F7 $E6 -; F8 $E7 -; F9 $E8 -; F10 $E9 -; F11 $EA -; F12 $EB -; SYSRQ $EC -; PRTSC $ED -; PAUSE $EE -; APP $EF -; INS $F0 -; DEL $F1 -; HOME $F2 -; END $F3 -; PGUP $F4 -; PGDN $F5 -; UP $F6 -; DOWN $F7 -; LEFT $F8 -; RIGHT $F9 -; POWER $FA -; SLEEP $FB -; WAKE $FC -; BREAK $FD diff --git a/branches/s100/Source/loader.asm b/branches/s100/Source/loader.asm deleted file mode 100644 index f70d7a96..00000000 --- a/branches/s100/Source/loader.asm +++ /dev/null @@ -1,784 +0,0 @@ -; -;================================================================================================== -; LOADER -;================================================================================================== -; -; FIX!!! NEED TO SWITCH FROM CBIOS CALLS TO HBIOS CALLS!!! -; -; INCLUDE GENERIC STUFF -; -#INCLUDE "std.asm" -; -; 12/1/2011 dwg - -DRIVES .EQU 1 ; control diskmap display function -; - .ORG 8400H -; - ; SETUP OUR STACK - LD SP,BL_STACK ; SET UP LOADER STACK - - ; SETUP CBIOS IOBYTE - LD A,DEFIOBYTE ; LOAD DEFAULT IOBYTE - LD (IOBYTE),A ; STORE IT - -#IF ((PLATFORM != PLT_N8) & (PLATFORM != PLT_S100)) - IN A,(RTC) ; RTC PORT, BIT 6 HAS STATE OF CONFIG JUMPER -; LD A,40H ; *DEBUG* SIMULATE JUMPER OPEN -; LD A,00H ; *DEBUG* SIMULATE JUMPER SHORTED - AND 40H ; ISOLATE BIT 6 - JR Z,INIT1 ; IF BIT6=0, SHORTED, USE ALT IOBYTE - LD A,DEFIOBYTE ; LOAD DEF IOBYTE VALUE - JR INIT2 ; CONTINUE -INIT1: - LD A,ALTIOBYTE ; LOAD ALT IOBYTE VALUE -INIT2: - LD (IOBYTE),A ; SET THE ACTIVE IOBYTE -#ENDIF - - ; RUN THE BOOT LOADER MENU - JP DOBOOTMENU -; -;__DOBOOT________________________________________________________________________________________________________________________ -; -; PERFORM BOOT FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; - -DOBOOTMENU: -; LD DE,STR_BANNER -; CALL WRITESTR - - CALL LISTDRIVES - LD DE,STR_BOOTMENU - CALL WRITESTR - -#IF (DSKYENABLE) - LD HL,BOOT ; POINT TO BOOT MESSAGE - CALL SEGDISPLAY ; DISPLAY MESSAGE -#ENDIF - -#IF (BOOTTYPE == BT_AUTO) - LD BC,1000 * BOOT_TIMEOUT - LD (BL_TIMEOUT),BC -#ENDIF - -DB_BOOTLOOP: -; -; CHECK FOR CONSOLE BOOT KEYPRESS -; -#IF (UARTENABLE | VDUENABLE | (PRPENABLE & PRPCONENABLE) | (PPPENABLE & PPPCONENABLE)) - CALL CST - OR A - JR Z,DB_CONEND - CALL CINUC - CP 'S' ; SETUP - JR Z,GOSETUP - CP 'M' ; MONITOR - JR Z,GOMONUART - CP 'R' ; ROM BOOT - JR Z,GOROM - CP 'A' ; A-P, DISK BOOT - JR C,DB_INVALID - CP 'P' + 1 ; HMMM... 'M' DRIVE CONFLICTS WITH MONITOR SELECTION - JR NC,DB_INVALID - SUB 'A' - JR GOBOOTDISK -DB_CONEND: -#ENDIF -; -; CHECK FOR DSKY BOOT KEYPRESS -; -#IF (DSKYENABLE) - CALL KY_STAT ; GET KEY FROM KB INTO A - OR A - JR Z,DB_DSKYEND - CALL KY_GET - CP KY_GO ; GO = MONITOR - JR Z,GOMONDSKY - CP KY_BO ; BO = BOOT ROM - JR Z,GOROM - CP 0AH ; A-F, DISK BOOT - JR C,DB_INVALID - CP 0FH + 1 - JR NC,DB_INVALID - SUB 0AH - JR GOBOOTDISK -; LD HL,BOOT ; POINT TO BOOT MESSAGE -; LD A,00H ; BLANK OUT SELECTION,IT WAS INVALID -; LD (HL),A ; STORE IT IN DISPLAY BUFFER -; CALL SEGDISPLAY ; DISPLAY THE BUFFER -DB_DSKYEND: -#ENDIF -; -; IF CONFIGURED, CHECK FOR AUTOBOOT TIMEOUT -; -#IF (BOOTTYPE == BT_AUTO) - - ; DELAY FOR 1MS TO MAKE TIMEOUT CALC EASY - LD DE,40 - CALL VDELAY - - ; CHECK/INCREMENT TIMEOUT - LD BC,(BL_TIMEOUT) - DEC BC - LD (BL_TIMEOUT),BC - LD A,B - OR C - JR NZ,DB_BOOTLOOP - - ; TIMEOUT EXPIRED, PERFORM DEFAULT BOOT ACTION - LD A,BOOT_DEFAULT - CP 'M' ; MONITOR - JR Z,GOMONUART - CP 'R' ; ROM BOOT - JR Z,GOROM - CP 'A' ; A-P, DISK BOOT - JR C,DB_INVALID - CP 'P' + 1 ; HMMM... DRIVE M CONFLICTS WITH "MONITOR" SELECTION - JR NC,DB_INVALID - SUB 'A' - JR GOBOOTDISK -#ENDIF - - JP DB_BOOTLOOP -; -; BOOT OPTION PROCESSING -; -DB_INVALID: - LD DE,STR_INVALID - CALL WRITESTR - JP DOBOOTMENU -; -GOSETUP: - LD DE,STR_SETUP - CALL WRITESTR - JP DOSETUPMENU -; -GOMONUART: - LD DE,STR_BOOTMON - CALL WRITESTR - JP MON_UART -; -GOMONDSKY: - LD DE,STR_BOOTMON - CALL WRITESTR - JP MON_DSKY -; -GOROM: - LD DE,STR_BOOTROM - CALL WRITESTR - JP CPM_ENT -; -GOBOOTDISK: - LD C,A - LD DE,STR_BOOTDISK - CALL WRITESTR - JP BOOTDISK -; -; BOOT FROM DISK DRIVE -; -BOOTDISK: - LD DE,STR_BOOTDISK1 - CALL WRITESTR - - ; SAVE BOOT DRIVE - LD A,C - LD (BL_BOOTDRIVE),A - - ; SAVE BOOT DEVICE/SLICE - CALL CBIOS_GETDSK - LD A,B - LD (BL_BOOTDEVICE),A - LD (BL_BOOTLU),DE - - ; SELECT THE REQUESTED DRIVE - LD A,(BL_BOOTDRIVE) ; GET CBIOS BOOT DRIVE BACK - LD C,A ; MOVE TO C - LD E,0 ; BIT0=0 IN E MEANS FIRST SELECT - CALL CBIOS_SELDSK ; CALL CBIOS DSKSEL TO GET DPH ADDRESS - - ; IF HL=0, SELDSK FAILED! SELECTED DRIVE IS NOT AVAILABLE - LD A,H - OR L - JP Z,DB_NODISK - -; ; *DEBUG* PRINT DPH ADDRESS -; CALL NEWLINE -; PUSH HL -; POP BC -; CALL PRTHEXWORD - - ; BUMP HL TO POINT TO DPB AND LOAD IT - LD DE,10 - ADD HL,DE ; HL = ADDRESS OF ADDRESS OF DPB - LD A,(HL) ; DEREFERENCE - INC HL - LD H,(HL) - LD L,A ; NOW HL = ADDRESS OF DPB - -; ; *DEBUG* PRINT DPB ADDRESS -; CALL PC_SPACE -; PUSH HL -; POP BC -; CALL PRTHEXWORD - - ; FIRST WORD OF DPB IS SECTORS PER TRACK, SAVE IT - LD C,(HL) - INC HL - LD B,(HL) ; NOW BC = SECTORS PER TRACK -; LD BC,36 ; *DEBUG* - LD (BL_LDSPT),BC ; SAVE IT - - LD DE,12 ; POINT TO DPB OFFSET FIELD - ADD HL,DE - LD A,(HL) - INC HL - OR (HL) - JP Z,DB_NOBOOT ; IF OFFSET = ZERO, THERE IS NO BOOT AREA!!! - -; ; *DEBUG* PRINT SECTORS PER TRACK -; CALL PC_SPACE -; CALL PRTHEXWORD - - ; SETUP TO LOAD METADATA - LD BC,BL_METABUF - CALL CBIOS_SETDMA - LD BC,0 - CALL CBIOS_SETTRK - LD BC,11 - CALL CBIOS_SETSEC - - ; READ META DATA - CALL CBIOS_READ - OR A - JP NZ,DB_ERR - -; ; PRINT SIGNATURE -; CALL NEWLINE -; LD DE,STR_SIG -; CALL WRITESTR -; LD BC,(BL_SIG) -; CALL PRTHEXWORD - - ; CHECK SIGNATURE - LD BC,(BL_SIG) - LD A,$A5 - CP B - JP NZ,DB_NOBOOT - LD A,$5A - CP C - JP NZ,DB_NOBOOT - - ; PRINT CPMLOC VALUE - CALL NEWLINE - LD DE,STR_CPMLOC - CALL WRITESTR - LD BC,(BL_CPMLOC) - CALL PRTHEXWORD - - ; PRINT CPMEND VALUE - CALL PC_SPACE - LD DE,STR_CPMEND - CALL WRITESTR - LD BC,(BL_CPMEND) - CALL PRTHEXWORD - - ; PRINT CPMENT VALUE - CALL PC_SPACE - LD DE,STR_CPMENT - CALL WRITESTR - LD BC,(BL_CPMENT) - CALL PRTHEXWORD - CALL PC_SPACE - - LD DE,STR_LABEL - CALL WRITESTR - LD A,(BL_TERM) ; Display Disk Label if Present - CP '$' ; (dwg 2/7/2012) - JP NZ,NO_LABEL ; pick up string terminator for label - LD DE,BL_LABEL ; if it is there, then a printable - CALL WRITESTR ; label is there as wellm even if spaces. -NO_LABEL: ; - -; -; SETUP BL_CPM... STUFF -; - ; COMPUTE BL_SIZ - LD HL,(BL_CPMEND) - LD DE,(BL_CPMLOC) - SCF - CCF - SBC HL,DE - LD (BL_LDSIZ),HL - - ; SETUP FOR DATA LOAD - LD HL,BL_LDLOC - LD (BL_LDCLOC),HL - LD DE,(BL_LDSIZ) - ADD HL,DE - LD (BL_LDEND),HL - LD BC,0 - LD (BL_LDCTRK),BC - LD BC,12 - LD (BL_LDCSEC),BC - -; ; *DEBUG* PRINT SPT, SEC, TRK, SIZ, END -; CALL NEWLINE -; LD BC,(BL_LDSPT) -; CALL PRTHEXWORD -; CALL PC_SPACE -; LD BC,(BL_LDCSEC) -; CALL PRTHEXWORD -; CALL PC_SPACE -; LD BC,(BL_LDCTRK) -; CALL PRTHEXWORD -; CALL PC_SPACE -; LD BC,(BL_LDSIZ) -; CALL PRTHEXWORD -; CALL PC_SPACE -; LD BC,(BL_LDEND) -; CALL PRTHEXWORD - - ; LOADING MESSAGE - CALL NEWLINE - LD DE,STR_LOADING - CALL WRITESTR -; -; LOADING LOOP -; -DB_LOOP: - ; SETUP TO READ SECTOR - LD BC,(BL_LDCTRK) -; CALL NEWLINE ; *DEBUG* -; CALL PRTHEXWORD ; *DEBUG* - CALL CBIOS_SETTRK - - LD BC,(BL_LDCSEC) -; CALL PC_SPACE ; *DEBUG* -; CALL PRTHEXWORD ; *DEBUG* - CALL CBIOS_SETSEC - LD BC,(BL_LDCLOC) -; CALL PC_SPACE ; *DEBUG* -; CALL PRTHEXWORD ; *DEBUG* - CALL CBIOS_SETDMA - - ; READ IT - CALL CBIOS_READ - OR A - JP NZ,DB_ERR - CALL PC_PERIOD - -; ; *DEBUG* PRINT FIRST WORD OF DATA LOADED -; CALL PC_SPACE -; LD HL,(BL_LDCLOC) -; LD A,(HL) -; INC HL -; LD B,(HL) -; LD C,A -; CALL PRTHEXWORD - - ; INCREMENT MEMORY POINTER - LD HL,(BL_LDCLOC) - LD DE,128 - ADD HL,DE - LD (BL_LDCLOC),HL - - ; CHECK TO SEE IF WE ARE DONE - LD DE,(BL_LDEND) - LD A,H - CP D - JR NZ,DB_CONT - LD A,L - CP E - JR NZ,DB_CONT - - JP DB_DONE - -DB_CONT: - ; INCREMENT SECTOR - LD BC,(BL_LDCSEC) - INC BC - LD (BL_LDCSEC),BC - - ; TEST FOR END OF TRACK (LDCSEC/BC == LDSPT/DE) - LD DE,(BL_LDSPT) - LD A,C - CP E - JR NZ,DB_LOOP ; B != D, NOT AT EOT - LD A,B - CP D - JR NZ,DB_LOOP ; C != E, NOT AT EOT - - ; END OF TRACK, RESET SECTOR & INCREMENT TRACK - LD BC,0 - LD (BL_LDCSEC),BC - LD BC,(BL_LDCTRK) - INC BC - LD (BL_LDCTRK),BC - - JP DB_LOOP - -DB_NODISK: - ; SELDSK DID NOT LIKE DRIVE SELECTION - LD DE,STR_NODISK - CALL WRITESTR - JP DOBOOTMENU - -DB_NOBOOT: - ; DISK IS NOT BOOTABLE - LD DE,STR_NOBOOT - CALL WRITESTR - JP DOBOOTMENU - -DB_ERR: - ; I/O ERROR DURING BOOT ATTEMPT - LD DE,STR_BOOTERR - CALL WRITESTR - JP DOBOOTMENU - -DB_DONE: - CALL NEWLINE -; ; *DEBUG* -; CALL NEWLINE -; LD BC,BL_LDLOC -; CALL PRTHEXWORD -; CALL PC_SPACE -; LD BC,(BL_CPMLOC) -; CALL PRTHEXWORD -; CALL PC_SPACE -; LD BC,(BL_LDSIZ) -; CALL PRTHEXWORD -; CALL PC_SPACE -; LD BC,(BL_CPMENT) -; CALL PRTHEXWORD - -; JP DOBOOTMENU ; *DEBUG* - - ; ALL DONE, NOW RELOCATE IMAGE BY COPYING - LD DE,(BL_LDSIZ) ; BYTES TO MOVE - LD HL,(BL_CPMLOC) - ADD HL,DE - DEC HL ; HL = PTR TO DEST (TOP) - PUSH HL ; SAVE IT - LD HL,BL_LDLOC - ADD HL,DE - DEC HL ; HL = PTR TO SRC (TOP) - POP DE ; RECOVER DEST PTR - LD BC,(BL_LDSIZ) ; BC = BYTES TO COPY - LDDR - - ; PATCH BOOT DRIVE INFO INTO CONFIG DATA - LD A,1 - CALL RAMPG - LD HL,$020D ; LOCATION OF BOOTINFO IN SYSCFG IN RAM PAGE 0 - CALL PATBI - CALL RAMPGZ - - ; JUMP TO COLD BOOT ENTRY - LD HL,(BL_CPMENT) - JP (HL) - -PATBI: - ; PATCH BOOT DRIVE INFO AT ADDRESS SPECIFIED BY HL - LD A,TRUE ; BOOT FROM DISK = TRUE - LD (HL),A ; SAVE IT - INC HL - LD A,(BL_BOOTDEVICE) ; GET BOOT DEVICE/UNIT - LD (HL),A ; SAVE IT - INC HL - LD DE,(BL_BOOTLU) ; GET BOOT LU - LD (HL),E ; SAVE LSB - INC HL - LD (HL),D ; SAVE MSB - RET -; -; -; -DOSETUPMENU: - LD DE,STR_SETUPMENU - CALL WRITESTR - CALL CINUC - - CP 'F' ; FORMAT RAM DISK - JP Z,FMTRAMDSK - CP 'X' ; EXIT - JP Z,DOBOOTMENU - JP DOSETUPMENU ; NO VALID KEY, LOOP -; -FMTRAMDSK: - JP DOSETUPMENU -; -; DISPLAY LIST OF DRIVES -; -LISTDRIVES: -#IF (DRIVES) - call NEWLINE - - ld c,0 ; start with drive 0 - ld b,16 ; loop through 16 drives -dmloop: - push bc ; preserve drive and loop counter - ld a,c ; drive letter into a - add a,'A' ; convert to alpha version of drive letter - ld (BL_TMPDRV),a ; save it for printing if needed - call CBIOS_GETDSK ; get drive into, c still has drive number - or a ; set flags on result - jr nz,dmdone ; error, skip this drive - ld (BL_TMPLU),de ; save lu for later - ld a,b ; device/unit into a for matching below - - ld de,str_devrom - cp DIODEV_MD+0 ; ROM - jr z,dmprt - - ld de,str_devram - cp DIODEV_MD+1 ; RAM - jr z,dmprt - - and $f0 ; after ram/rom, compare on high nibble only - - ld de,str_devfd - cp DIODEV_FD ; floppy disk - jr z,dmprt - - ld de,str_devide - cp DIODEV_IDE ; IDE - jr z,dmprt - - ld de,str_devatapi - cp DIODEV_ATAPI ; ATAPI - jr z,dmprt - - ld de,str_devppide - cp DIODEV_PPIDE ; PPIDE - jr z,dmprt - - ld de,str_devsd - cp DIODEV_SD ; Generic SD - jr z,dmprt - - ld de,str_devprpsd - cp DIODEV_PRPSD ; PropIO SD - jr z,dmprt - - ld de,str_devpppsd - cp DIODEV_PPPSD ; ParPortProp SD - jr z,dmprt - - ld de,str_devhdsk - cp DIODEV_HDSK ; SIMH HDSK - jr z,dmprt - - jr dmdone - -dmprt: - ld a,(BL_TMPDRV) ; recover drive letter - call COUT ; print it - ld a,'=' ; load equal sign - call COUT ; print it - call WRITESTR ; print device name now (str ptr in de) - ld a,b ; a = device/unit - and $f0 ; isolate device - jr z,dmprt1 ; bypass unit printing for mem disk - ld a,b ; a = device/unit - and $0f ; remove device nibble - add a,'0' ; convert to alpha - call COUT ; print unit number - ld a,h ; load slice max msb - or l ; compare to lsb - jr z,dmprt1 ; if zero, no lu support - ld a,'-' ; slice prefix - call COUT ; print slice prefix - ld de,(BL_TMPLU) ; recover LU - ld a,e ; ignore msb, load lsb in a - call PRTHEXBYTE ; print it - -dmprt1: - call PC_SPACE ; padding - -dmdone: - pop bc ; recover drive num and loop counter - inc c ; increment drive number - dec b ; decrement loop counter - jp nz,dmloop ; loop if more drives to check - ret ; done -#ENDIF -; -#IF (DSKYENABLE) -; -; -;__SEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -;____________________________________________________________________________________________________ -; -SEGDISPLAY: - PUSH AF ; STORE AF - PUSH BC ; STORE BC - PUSH HL ; STORE HL - LD BC,0007H - ADD HL,BC - LD B,08H ; SET DIGIT COUNT - LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF - OUT (PPIC),A ; OUTPUT - CALL DELAY ; WAIT - LD A,0F0H ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - -SEGDISPLAY1: ; - OUT (PPIA),A ; OUTPUT TO PORT - LD A,80H | 30H ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PPIC),A ; OUTPUT TO PORT - CALL DELAY ; WAIT - LD A,40H | 30H ; SET CONTROL PORT 7218 TO OFF - OUT (PPIC),A ; OUTPUT - -SEGDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - OUT (PPIA),A ; OUT TO PPIA - LD A,00H | 30H ; SET WRITE STROBE - OUT (PPIC),A ; OUT TO PPIC - CALL DELAY ; DELAY - LD A,40H | 30H ; SET CONTROL PORT OFF - OUT (PPIC),A ; OUT TO PPIC - CALL DELAY ; WAIT - DEC HL ; INC POINTER - DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - POP HL ; RESTORE HL - POP BC ; RESTORE BC - POP AF ; RESTORE AF - RET -#ENDIF -; -;__TEXT_STRINGS_________________________________________________________________________________________________________________ -; -; STRINGS -;_____________________________________________________________________________________________________________________________ -; -STR_BOOTDISK .DB "BOOT FROM DISK\r\n$" -STR_BOOTDISK1 .DB "\r\nReading disk information...$" -STR_BOOTMON .DB "START MONITOR\r\n$" -STR_BOOTROM .DB "BOOT FROM ROM\r\n$" -STR_INVALID .DB "INVALID SELECTION\r\n$" -STR_SETUP .DB "SYSTEM SETUP\r\n$" -STR_SIG .DB "SIGNATURE=$" -STR_CPMLOC .DB "LOC=$" -STR_CPMEND .DB "END=$" -STR_CPMENT .DB "ENT=$" -STR_LABEL .DB "LABEL=$" -STR_LOADING .DB "\r\nLoading$" -STR_NODISK .DB "\r\nNo disk!$" -STR_NOBOOT .DB "\r\nDisk not bootable!$" -STR_BOOTERR .DB "\r\nBoot failure!$" -; -STR_BANNER .DB "\r\n", PLATFORM_NAME, " Boot Loader$" -STR_BOOTMENU .DB "\r\nBoot: (M)onitor, (R)OM, or Drive Letter ===> $" -; -STR_SETUPMENU: - .DB "\r\n\r\n", PLATFORM_NAME, " Setup & Configuration v", BIOSVER - .DB " (", VARIANT, "-", TIMESTAMP, ")\r\n\r\n" -; .DB "(F)ormat RAM Disk\r\n" - .DB "e(X)it Setup\r\n" - .DB "\r\n===> $" -; - .IF DSKYENABLE -BOOT: -; . . t o o b - .DB 00H, 00H, 80H, 80H, 094H, 09DH, 09DH, 09FH - .ENDIF -; -#DEFINE CIOMODE_CBIOS -#DEFINE DSKY_KBD -#INCLUDE "util.asm" -; -#INCLUDE "memmgr.asm" -; -; READ A CONSOLE CHARACTER AND CONVERT TO UPPER CASE -; -CINUC: - CALL CIN - AND 7FH ; STRIP HI BIT - CP 'A' ; KEEP NUMBERS, CONTROLS - RET C ; AND UPPER CASE - CP 7BH ; SEE IF NOT LOWER CASE - RET NC - AND 5FH ; MAKE UPPER CASE - RET -; -;================================================================================================== -; WORKING DATA STORAGE -;================================================================================================== -; -; WE USE A 256 BYTE AREA JUST AT THE START OF RAM (TOP 32KB) -; FOR WORKING DATA STORAGE. THE FIRST 128 BYTES ARE RESERVED -; TO LOAD THE BLOCK CONTAINING THE BOOT LOAD METADATA. THE -; METADATA IS IN THE LAST 6 BYTES OF THIS BLOCK. -; -;__________________________________________________________________________________________________ -; -BL_METABUF .EQU $ -BL_SIG .DW 0 ; SIGNATURE (WILL BE 0A55AH IF SET) -BL_PLATFORM .DB 0 ; Formatting Platform -BL_DEVICE .DB 0 ; Formatting Device -BL_FORMATTER .FILL 8,0 ; Formatting Program -BL_DRIVE .DB 0 ; Physical Disk Drive # -BL_LU .DW 0 ; Logical Unit (slice) -; - .FILL (BL_METABUF + 128) - $ - 32 -BL_PROTECT .DB 0 ; write protect boolean -BL_UPDATES .DW 0 ; update counter -BL_RMJ .DB 0 ; RMJ Major Version Number -BL_RMN .DB 0 ; RMN Minor Version Number -BL_RUP .DB 0 ; RUP Update Number -BL_RTP .DB 0 ; RTP Patch Level -BL_LABEL .FILL 16,0 ; 16 Character Drive Label -BL_TERM .DB 0 ; LABEL TERMINATOR ('$') -BL_BILOC .DW 0 ; LOC TO PATCH BOOT DRIVE INFO TO (IF NOT ZERO) -BL_CPMLOC .DW 0 ; FINAL RAM DESTINATION FOR CPM/CBIOS -BL_CPMEND .DW 0 ; END ADDRESS FOR LOAD -BL_CPMENT .DW 0 ; CP/M ENTRY POINT (CBIOS COLD BOOT) -; -; WORKING STORAGE STARTS HERE -; -BL_STACKSIZ .EQU 40H - .FILL BL_STACKSIZ,0 -BL_STACK .EQU $ -; -BL_LDSPT .DW 0 ; SECTORS PER TRACK FOR LOAD DEVICE -BL_LDCTRK .DW 0 ; CURRENT TRACK FOR LOAD -BL_LDCSEC .DW 0 ; CURRENT SECTOR FOR LOAD -BL_LDCLOC .DW 0 ; CURRENT MEM LOC BEING LOADED -BL_LDEND .DW 0 ; RAM LOCATION TO STOP LOAD -BL_LDSIZ .DW 0 ; SIZE OF CPM/CBIOS IMAGE TO LOAD -BL_TIMEOUT .DW 0 ; AUTOBOOT TIMEOUT COUNTDOWN COUNTER -BL_BOOTDRIVE .DB 0 ; TEMPORARY STORAGE FOR BOOT DRIVE -BL_BOOTDEVICE .DB 0 ; TEMPORARY STORAGE FOR BOOT DEVICE/UNIT -BL_BOOTLU .DW 0 ; TEMPORARY STORAGE FOR BOOT LU -BL_TMPDRV .DB 0 ; TEMP STORAGE FOR DRIVE LETTER -BL_TMPLU .DW 0 ; TEMP STORAGE FOR LU -; -BL_LDLOC .EQU 100H ; LOAD IMAGE HERE BEFORE RELOCATING -; -#IF (DRIVES) -str_devrom .DB "ROM$" -str_devram .DB "RAM$" -str_devfd .DB "FD$" -str_devide .DB "IDE$" -str_devatapi .DB "ATAPI$" -str_devppide .DB "PPIDE$" -str_devsd .DB "SD$" -str_devprpsd .DB "PRPSD$" -str_devpppsd .DB "PPPSD$" -str_devhdsk .DB "HDSK$" -#ENDIF -; -;================================================================================================== -; FILL REMAINDER OF BANK -;================================================================================================== -; -SLACK: .EQU (9000H - $) - .FILL SLACK -; - .ECHO "LOADER space remaining: " - .ECHO SLACK - .ECHO " bytes.\n" - .END diff --git a/branches/s100/Source/makefile b/branches/s100/Source/makefile deleted file mode 100644 index e60874b9..00000000 --- a/branches/s100/Source/makefile +++ /dev/null @@ -1,226 +0,0 @@ -# -# GCC based makefile -# -# 05/24/2012 2.3 wbw - changed to handle revised build parms -# -# 05/24/2012 2.0 wbw - changed to handle HBIOS -# -# 01/11/2011 1.4 wbw - added support for ZSDOS/ZDDOS/ZCPR -# -# 12/22/2011 1.3 wbw - removed all built-in config stuff, operation is now entirely -# dependent on variables CONFIG, ROMSIZE, and CPU -# -# 12/02/2011 1.3 wbw - replaced makever functionality with built-in makefile stuff -# -# 11/29/2011 1.3 dwg - uses makever to generate stdincl.inc from the version.hpp file -# -# 11/19/2011 1.3 dwg - added n8vem_vdu to "usage" and "all" rules -# enhanced clean to get files in $(OUTDIR) -# added custom to "all" rule - -# -# The operation of this makefile is entirely dependent on the setting -# of five variables: PLATFORM, CONFIG, ROMSIZE, SYS, and optionally ROMNAME: -# -# PLATFORM specifies the base hardware platform you are targeting -# and must be one of N8VEM, ZETA, N8, S2I, or S100 -# -# CONFIG determines which configuration to build which means that -# it will determine the config_xxxx_yyyy.asm config settings file to -# include as well as the output file names. So, for example, -# if PLATFORM is "n8vem" and CONFIG is "cvdu", the config_N8VEM_cvdu.asm -# file will be used for BIOS configuration settings and the output -# files will be N8VEM_cvdu.rom, N8VEM_cvdu.sys, and N8VEM_cvdu.com. -# -# ROMSIZE specifies the size of the ROM image to be produced and -# currently must be either "1024" for a 1MB ROM or "512" for a -# 512KB ROM. -# -# SYS specifies the system variant to build in. CPM will -# build traditional CP/M. ZSYS will build ZSystem which -# currently means ZSDOS 1.2 & ZCPR 1.0 -# -# ROMNAME names the output file. It defaults to -# CONFIG. The output of the build will be: -# .rom, .sys, and .com. -# -# These variables can be passed into the makefile by the command -# line, hardcoded in this file, or set as environment variables -# in the OS. To use a command line, use the following format: -# -# make PLATFORM= CONFIG= ROMSIZE= SYS= -# -# An example of this is: -# -# make PLATFORM=N8VEM CONFIG=cvdu ROMSIZE=512 SYS=CPM -# -# Alternatively, you can specify the variables by hardcoding them -# in this file. To do so, uncomment the five lines after these -# comments and change the values as desired. -# If the variables are specified this way, you would then invoke -# the make by simply using "make" -# -# If you want to set them as environment variables, you can -# do this with commands like the following at an OS command -# prompt or in a batch file: -# -# SET PLATFORM=N8VEM -# SET CONFIG=cvdu -# SET ROMSIZE=512 -# SET SYS=CPM -# SET ROMNAME=n8vem -# -# Note: use "make clean" to delete temporary and output files -# -# A good idea is to do a clean with every build and this can be -# accomplished on one command line doing something like this: -# -# make clean all PLATFORM=N8VEM CONFIG=std ROMSIZE=512 SYS=CPM -# -# or, if you are using hard coded variables above: -# -# make clean all -# -# Uncomment and update values below to hardcode settings: -# -#PLATFORM := N8VEM -#CONFIG := std -#ROMSIZE := 512 -#SYS := CPM -#ROMNAME := n8vem - -ifeq "$(PLATFORM)" "N8" -CPU := 180 -else -CPU := 80 -endif - -ifndef ROMNAME -ROMNAME := $(PLATFORM)_$(CONFIG) -endif - -CPMTOOLSPATH := ../tools/cpmtools -CPMCP := $(CPMTOOLSPATH)/cpmcp.exe - -ROMDSKFILES := ../RomDsk/$(SYS)_$(ROMSIZE)KB/*.* ../RomDsk/cfg_$(PLATFORM)_$(CONFIG)/*.* ../Apps/core/*.* - -ifeq "$(SYS)" "CPM" -DOSBIN := bdosb01.bin -CPBIN := ccpb03.bin -else -DOSBIN := zsdos.bin -CPBIN := zcprw.bin -endif - -OUTDIR := ..\Output - -TASMPATH := ../tools/tasm32 -TASM := $(TASMPATH)/tasm.exe -TASMTABS := $(TASMPATH) -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -NULL := -SPACE := ${NULL} ${NULL} - -%.bin: %.asm - $(ASM80) $< $@ - -%.com: %.asm - $(ASM80) $< $@ - -%.img: %.asm - $(ASMIMG) $< $@ - -%.exe: %.cpp - $(CC) $< -o $@ - -ifneq ($(MAKECMDGOALS),clean) -ifeq "$(and $(PLATFORM) $(CONFIG), $(ROMSIZE), $(SYS), $(ROMNAME))" "" -$(error Usage: make PLATFORM=[N8VEM|ZETA|N8|S2I|S100] CONFIG= ROMSIZE=[512|1024] SYS=[CPM|ZSYS] [ROMNAME=]) -endif -endif - -all: $(OUTDIR)\$(ROMNAME).rom $(OUTDIR)\$(ROMNAME).sys $(OUTDIR)\$(ROMNAME).com - -build.inc: - echo ; >$@ - echo ; RomWBW Configured for $(PLATFORM) $(CONFIG), %date% %time% >>$@ - echo ; >>$@ - echo #DEFINE TIMESTAMP "%date:~-4,4%%date:~-10,2%%date:~-7,2%T%time:~0,2%%time:~3,2%" >>$@ - echo #DEFINE VARIANT "WBW-%username%" >>$@ - echo ; >>$@ - echo ; >>$@ - echo ; INCLUDE PLATFORM SPECIFIC DEVICE DEFINITIONS >>$@ - echo ; >>$@ - echo ROMSIZE .EQU $(ROMSIZE) >>$@ - echo PLATFORM .EQU PLT_$(PLATFORM) >>$@ - echo ; >>$@ - echo #IF (PLATFORM == PLT_S100) >>$@ - echo #INCLUDE "std-s100.inc" >>$@ - echo #ELSE >>$@ - echo #INCLUDE "std-n8vem.inc" >>$@ - echo #ENDIF >>$@ - echo ; >>$@ - echo #INCLUDE "config_$(PLATFORM)_$(CONFIG).asm" >>$@ - echo ; >>$@ - -bootrom.bin : bootrom.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -bootapp.bin : bootapp.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -pgzero.bin : pgzero.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -zcprw.bin : zcprw.asm zcpr.asm - $(TASM) $(ASMOPT85) $< $@ - -zsdos.bin : zsdos.asm zsdos.lib zsdos-gp.z80 - $(TASM) $(ASMOPT80) $< $@ - -cbios.bin: cbios.asm fd_data.asm ide_data.asm ppide_data.asm sd_data.asm prp_data.asm ppp_data.asm uart.asm vdu.asm std.asm ver.inc build.inc - $(TASM) $(ASMOPT80) -dBLD_SYS=SYS_$(SYS) $< $@ - -dbgmon.bin: dbgmon.asm std.asm ver.inc build.inc - -syscfg.bin: syscfg.asm std.asm build.inc ver.inc - -os.bin: $(CPBIN) $(DOSBIN) cbios.bin - copy /B $(subst $(SPACE),+,$(^)) $@ - -rom0.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin - copy /B $(subst $(SPACE),+,$(^)) $@ - -rom1.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin - copy /B $(subst $(SPACE),+,$(^)) $@ - -$(OUTDIR)\$(ROMNAME).rom: rom0.bin rom1.bin $(ROMDISKFILES) $(OUTDIR)\$(ROMNAME).sys - copy blank$(ROMSIZE)KB.dat RomDisk.tmp - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp $(ROMDSKFILES) 0: - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp ../Output/$(ROMNAME).sys 0:$(SYS).sys - copy /B rom0.bin+rom1.bin+RomDisk.tmp $@ - -$(OUTDIR)\$(ROMNAME).com: bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin - copy /B $(subst $(SPACE),+,$(^)) $@ - -$(OUTDIR)\$(ROMNAME).sys: prefix.bin os.bin - copy /B $(subst $(SPACE),+,$(^)) $@ - -clean: - if exist *.bin del *.bin - if exist *.com del *.com - if exist *.img del *.img - if exist *.rom del *.rom - if exist *.lst del *.lst - if exist *.exp del *.exp - if exist *.tmp del *.tmp - if exist build.inc del build.inc - if exist $(OUTDIR)\*.* erase /Q $(OUTDIR)\*.* \ No newline at end of file diff --git a/branches/s100/Source/makefile.linux b/branches/s100/Source/makefile.linux deleted file mode 100644 index 14fd13e6..00000000 --- a/branches/s100/Source/makefile.linux +++ /dev/null @@ -1,206 +0,0 @@ -# -# GCC based makefile -# -# 06/18/2012 2.0 dgg - updated for v2.0 -# -# 02/22/2012 1.5 dgg - modified for assembly under Linux -# -# 01/11/2011 1.4 wbw - added support for ZSDOS/ZDDOS/ZCPR -# -# 12/22/2011 1.3 wbw - removed all built-in config stuff, operation is now entirely -# dependent on variables CONFIG, ROMSIZE, and CPU -# -# 12/02/2011 1.3 wbw - replaced makever functionality with built-in makefile stuff -# -# 11/29/2011 1.3 dwg - uses makever to generate stdincl.inc from the version.hpp file -# -# 11/19/2011 1.3 dwg - added n8vem_vdu to "usage" and "all" rules -# enhanced clean to get files in $(OUTDIR) -# added custom to "all" rule - -# -# The operation of this makefile is entirely dependent on the setting -# of three variables: CONFIG, ROMSIZE, and CPU: -# -# CONFIG determines which configuration to build which means that -# it will determine the config_xxx.asm config settings file to -# include as well as the output file names. So, for example, -# if CONFIG is "n8vem", the config_n8vem.asm file will be used -# for BIOS configuration settings and the output files will be -# n8vem.rom, n8vem.sys, and n8vem.com. -# -# ROMSIZE specifies the size of the ROM image to be produced and -# currently must be either "1024" for a 1MB ROM or "512" for a -# 512KB ROM. -# -# CPU specifies the instruction set to be used in assembly and -# must be either "80" for Z80 or "180" for Z180. Currently, -# you should use 180 for N8 ROMs and 80 for everything else. -# -# SYS specifies the system variant to build in. CPM will -# build traditional CP/M. ZSYS will build ZSystem which -# currently means ZSDOS 1.2 & ZCPR 1.0 -# -# ROMNAME names the output file. It defaults to -# CONFIG. The output of the build will be: -# .rom, .sys, and .com. -# -# These variables can be passed into the makefile by the command -# line, hardcoded in this file, or set as environment variables -# in the OS. To use a command line, use the following format: -# -# make CONFIG= ROMSIZE= CPU= SYS= ROMNAME= -# -# An example of this is: -# -# make CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# Alternatively, you can specify the variables by hardcoding them -# in this file. To do so, uncomment the five lines after these -# comments and change the values as desired. -# If the variables are specified this way, you would then invoke -# the make by simply using "make" -# -# If you want to set them as environment variables, you can -# do this with commands like the following at an OS command -# prompt or in a batch file: -# -# SET CONFIG=n8vem -# SET ROMSIZE=512 -# SET CPU=80 -# SET SYS=CPM -# SET ROMNAME=n8vem -# -# Note: use "make clean" to delete temporary and output files -# -# A good idea is to do a clean with every build and this can be -# accomplished on one command line doing something like this: -# -# make clean all CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# or, if you are using hard coded variables above: -# -# make clean all -# -# Uncomment and update values below to hardcode settings: -# -#CONFIG := n8vem -#ROMSIZE := 512 -#CPU := 80 -#SYS := CPM -#ROMNAME := n8vem - -ifndef ROMNAME -ROMNAME := $(CONFIG) -endif - -CPMCP := /usr/bin/cpmcp - -ROMDSKFILES := ../RomDsk/$(SYS)_$(ROMSIZE)KB/*.* ../RomDsk/cfg_$(CONFIG)/*.* ../Apps/core/*.* - -ifeq "$(SYS)" "CPM" -DOSBIN := bdosb01.bin -CPBIN := ccpb03.bin -else -DOSBIN := zsdos.bin -CPBIN := zcprw.bin -endif - -OUTDIR := ../Output - -TASM := /usr/local/bin/tasm -TASMTABS := /usr/local/lib -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -NULL := -SPACE := ${NULL} ${NULL} - -%.bin: %.asm - $(ASM80) $< $@ - -%.com: %.asm - $(ASM80) $< $@ - -%.img: %.asm - $(ASMIMG) $< $@ - -%.exe: %.cpp - $(CC) $< -o $@ - -ifneq ($(MAKECMDGOALS),clean) -ifeq "$(and $(CONFIG), $(ROMSIZE), $(CPU), $(SYS), $(ROMNAME))" "" -$(error Usage: make CONFIG= ROMSIZE=[512|1024] CPU=[80|180] SYS=[CPM|ZSYS] ROMNAME=) -endif -endif - -all: $(OUTDIR)/$(ROMNAME).rom $(OUTDIR)/$(ROMNAME).sys $(OUTDIR)/$(ROMNAME).com - -build.inc: - echo ';' >$@ - echo -n '; RomWBW Configured for '$(CONFIG)' ' >>$@ - date >> $@ - echo ; >>$@ - echo -n '#DEFINE TIMESTAMP "' >>$@ - date '+%Y %m %d %H%M"' >>$@ - echo ; >>$@ - echo '#DEFINE VARIANT "WBW-$(USERNAME)"' >>$@ - echo ; >>$@ - echo ROMSIZE .EQU $(ROMSIZE) >>$@ - echo ; >>$@ - echo '#INCLUDE "config_'$(CONFIG)'.asm"' >>$@ - echo ; >>$@ - -bootrom.bin : bootrom.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -bootapp.bin : bootapp.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -pgzero.bin : pgzero.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -zcprw.bin : zcprw.asm zcpr.asm - $(TASM) $(ASMOPT85) $< $@ - -zsdos.bin : zsdos.asm zsdos.lib zsdos-gp.z80 - $(TASM) $(ASMOPT80) $< $@ - -cbios.bin: cbios.asm fd_data.asm ide_data.asm ppide_data.asm sd_data.asm prp_data.asm ppp_data.asm uart.asm vdu.asm std.asm ver.inc build.inc - $(TASM) $(ASMOPT80) -dBLD_SYS=SYS_$(SYS) $< $@ - -dbgmon.bin: dbgmon.asm std.asm ver.inc build.inc - -syscfg.bin: syscfg.asm std.asm build.inc ver.inc - -os.bin: $(CPBIN) $(DOSBIN) cbios.bin - cat $(CPBIN) $(DOSBIN) cbios.bin >>$@ - -rom0.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin >>$@ - -rom1.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin bnk1.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin bnk1.bin >>$@ - -$(OUTDIR)/$(ROMNAME).rom: rom0.bin rom1.bin $(ROMDISKFILES) $(OUTDIR)/$(ROMNAME).sys - cp blank$(ROMSIZE)KB.dat RomDisk.tmp - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp $(ROMDSKFILES) 0: - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp ../Output/$(ROMNAME).sys 0:$(SYS).sys - cat rom0.bin rom1.bin RomDisk.tmp >>$@ - -$(OUTDIR)/$(ROMNAME).com: bootapp.bin syscfg.bin loader.bin bnk1.bin dbgmon.bin os.bin - cat bootapp.bin syscfg.bin loader.bin bnk1.bin dbgmon.bin os.bin >>$@ - -$(OUTDIR)/$(ROMNAME).sys: prefix.bin os.bin - cat prefix.bin os.bin >>$@ - -clean: - rm -f *.bin *.com *.img *.rom *.lst *.exp *.tmp - rm -f build.inc - rm -f $(OUTDIR)/*.* diff --git a/branches/s100/Source/master-cfg.asm b/branches/s100/Source/master-cfg.asm deleted file mode 100644 index b6e0d517..00000000 --- a/branches/s100/Source/master-cfg.asm +++ /dev/null @@ -1,3079 +0,0 @@ -; master-dwg.asm 1/14/2013 dwg - prepare for migration to -; RomWBW/branches/s100. - -; dougtest.asm 12/29/2012 dwg - derived dougtest from master - - -; MASTER.Z80 This is the main monitor program for my system. -; It resided in 1 2732 PROM at F000H (or top half of 28C64) -; Assemble and SLR's Z80ASM Assembler (Can also use Cromemco's Assembler) -; Use:- Z80ASM MASTER FH -; -; Note the monitor is is two sections. The F000H-F7FFH is for typical display -; move memory type functions. The second portion starts at F800H and contains -; a series of CPM BIOS compatable jumps. For compatability with some of my old -; CPM V1.4 software these locations should not be changed. You can easily build -; around them. The second section (after the above BIOS jumps section) contains -; CPM boot loader code and other more specilized stuff. -; -; To assemble under windows... -; Load Altair.EXE -; do cpm3 -; I: -; Submit master -; -; Master.HEX is written back to the same windows folder as altair.exe is in. - -; Programming an EEPROM for the Z80 Board with the VP-280 Programmer -; Using a MK28C28A EEPROM or uP28C64:- -; For monitor at F000H-FFFFH -; Load Buffer Address – 1000 -; From File address F000H -; This will put the code (4K) in the top “half” of the 8K EEPROM. It can be seen/edited at 1000H - -; Recent History... - -; 26/2/09 Added ability to switch CO/CI to ACIA serial from PC. -; 5/3/09 Adjust RTS/CTS levels for Modem -; V3.5 6/3/09 Set talker messages for new V-Stamp chip. -; 12/09/09 Add SD Systems IO-8 board Serial ports. -; V3.52 16/9/09 Add SD Systems IO-8 Board clock display on signon -; v3.6 21/9/09 Add display command for greater than 64K RAM, removed -; V4.0 10/26/09 Switched in 8255 driven IDE HD Controller (Removed XComp) -; some old commands to make more room. -; V4.1 11/7/09 Added input ports scan/diagnostic -; V4.2 11/14/09 Remove Date (keep time) from Clock (Chip is messed up by CPM3 routine) -; also modified to switch from the SD System assembler to the SLR one. -; V4.21 11/17/09 Removed 8086 jump far setting code -; V4.3 11/18/09 Implement movement of 8086 Monitor code (EPROM) to correct location in RAM space -; V4.31 11/19/09 Check 8086 Monitor ROM->ROM went OK. Added W command. -; V4.32 12/7/09 Turn off any SD Systems 8024 video screen enhancements (flashing, underline etc). -; V4.33 12/25/09 Correct High/Low byte Sector read for IDE board -; V4.34 2/23/10 "O" command, 8086 Far jump to 500H (IF RAM @ FFFF0H), W command boots 8086 from reset at FFFF0H. -; V4.35 3/25/10 "O" command just puts 8086 Far JMP to 500H (IF RAM @ FFFF0H). Done also at each reset. -; V4.4 7/29/10 Removed all SD Systems IO-8. Added S-100Computers I/O board drivers. -; V4.41 7/29/10 Initilization of V-Stamp chip done. Cleaned up Serial port names etc -; V4.42 7/31/10 Switched RTC over to S-100Computers board (Ports A4,A5) -; V4.50 2/7/11 Added Floppy Boot loader for ZFDC board. Still have the Versafloppy loader but no BIOS functions -; V4.51 2/13/11 Check IDE if Boot sector is valid -; V4.52 2/15/11 Pulse CF/IDE cards twice to reset (some) cards properly -; V4.53 2/16/11 Initilize IDE board with IDE RD/WR lines inactive on power-up. -; V4.54 2/28/11 Incoporated new fast multi-sector boot for CPM floppy loading with ZFDC board -; V4.55 2/28/11 "O" command now jumps to SWITCH_8086 (activates 8086) when done -; V4.55a 3/1/11 "O" cmd will just put 33 on Consol (temporary 8086 board test) -; V4.56 3/15/11 Re-did IDE drive hardware reset pulse to one (delayed) pulse, then wait for drive ready status. -; V4.57 6/3/11 Set up an equate for IDE drive reset pulse, Fixed Z command (Last version using MM58167 RTC chip) -; V4.6 11/27/11 Switched to Dallas Semiconductor/IBM-PC CMOS-RTC chip & MSDOS Support board for time & dates -; V4.7 3/26/12 Cleaned up IOBYTE options. Added 68000 CPU Slave activate option (B menu command) - -; V4.7A 16Oct12 TRL - Fixed console serial port, forced I/O to serial port -; V4.7B 18Oct12 TRL - Added boot code framwork for RomWBW testing -; V4.7C 19Oct12 TRL - Converted to TASM syntax -; V4.7C 10Nov12 DWG - Added to S100Bios as ../Source/master.asm - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -#INCLUDE "std.asm" ; Add standard .asm files -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;#INCLUDE "config_s100.asm" config_s100.asm is included by std.asm -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -BIGROM .EQU FALSE ; will put Monitor at 0E000h -;SERIAL .EQU TRUE ; Will use S100 Serial Board -;VERSA .EQU FALSE ; Will load Versi Floppy code -;SPEAK .EQU FALSE ; Will allow speach talker board -;RTC .EQU FALSE ; Will load RTC code - - -SCROLL .EQU 01H ;Set scrool direction UP. -BELL .EQU 07H -SPACE .EQU 20H -TAB .EQU 09H ;TAB ACROSS (8 SPACES FOR SD-BOARD) -CR .EQU 0DH -LF .EQU 0AH -FF .EQU 0CH -QUIT .EQU 11H ;Turns off any screen enhancements (flashing, underline etc). -NO_ENHANCEMENT .EQU 17H ;Turns off whatever is on -FAST .EQU 10H ;High speed scrool -ESC .EQU 1BH -DELETE .EQU 7FH -BACKS .EQU 08H -CLEAR .EQU 1AH ;TO CLEAR SCREEN -RST7 .EQU 38H ;RST 7 (LOCATION FOR TRAP) -IOBYTE1 .EQU 0EFH ;IOBYTE (SEE BELOW) -NN .EQU 0H ;[I] INITIAL VALUE -; - -STARTCPM .EQU 100H ;LOCATION WHERE CPM WILL BE PLACED FOR COLD BOOT -STARTDOS .EQU 100H ;LOCATION WHERE MSDOS WILL BE PLACED FOR COLD BOOT -FFILE_SIZE .EQU 9000h/512 ;SIZE OF 5MSDOS20.COM IN 512 BYTE SECTORS -; -; -;IOBYTE = SENSE SWITCHES AT PORT 0EFH -; -; BIT MAP OF PORT 0EFH:------- X X X X X X X X (11111111=NORMAL CONFIG) -; | | | | | | | |..For Z80 Monitor, 0=CONSOLE DATA TO PRINTER ALSO -; | | | | | | |....For 8086 Monitor, 0=Force Consol output to CGA/VGA Board -; | | | | | |......For 8086 Monitor, 0=Do not initilize extra ROMS -; | | | | |........Unused -; | | | |...........For CPM3, 0=Prevents LF's in CPM3 -; | | |.............For Z80 Monitor, 0=Consol I/O via ACIA Serial port -; | |...............For CPM3, 0=Force format of Mdisk ith CPM3 -; |.................For CPM3, 0=R/W protect Mdisk -; For 8086 Monitor, 0=Prevent doing a JMPF to 0000:0500H after 8086 reset -; -; - -;-------------- SD SYSTEMS VIDIO BOARD FOR CONSOLE INPUT & OUTPUT -#IF S100SDSVIDENABLE -CONSOL_STATUS .EQU 0H -CONSOL_IN .EQU 01H -CONSOL_OUT .EQU 01H -#ENDIF - - -;-------------- THIS IS MY PORT TO OUTPUT DATA TO HP 4050T LASAR PRINTER (IMSAI 8PIO Board) -PRINTER_STATUS .EQU 5 ;IN, HP PARELL PORT -PRINTER_OUT .EQU 5 ;OUT -PRINTER_STROBE .EQU 4 ;OUT -;DIAG_LEDS .EQU 5 ;OUT (Will use this port initially for diagnostic LED display) -DIAG_LEDS .EQU 0A8h ;OUT (Will use this port initially for diagnostic LED display) Use hex display - - -;-------------- S100 Computers Serial I/O BOARD PORT ASSIGNMENTS (A0-AC) -#IF S100IOENABLE - -#IF S100IOSCCBENABLE -BCTL .EQU 0A0H ;CHANNEL B CONTROL PORT ASSIGNMENTS OF THE ZILOG SCC CHIP ;<--- Adjust as necessary, -BDTA .EQU 0A2H ;CHANNEL B DATA -#ENDIF -#IF S100IOSCCAENABLE -ACTL .EQU 0A1H ;CHANNEL A CONTROL -ADTA .EQU 0A3H ;CHANNEL A DATA -#ENDIF -#IF S100IO8255ENABLE -PortA_8255 .EQU 0A8H ;A port of 8255 -PortB_8255 .EQU 0A9H ;B port of 8255 -PortC_8255 .EQU 0AAH ;C Port of 8255 -PortCtrl_8255 .EQU 0ABH ;8255 configuration port -AinBout8255cfg .EQU 10011000b ;Set 8255 ports:- A input, B output, -AoutBin8255cfg .EQU 10001010b ;Set 8255 ports:- A output to LED, B Input from Dip Switch -#ENDIF - -#IF S100IOUSBENABLE -;---------------PORT ASSIGNEMENT FOR DLP-USB Controller chip -USB_DATA .EQU 0ACH -USB_STATUS .EQU 0AAH ;Status port for USB port (Port C of 8255, bits 6,7) -USB_RXE .EQU 80H ;If Bit 7 = 0, data available to recieve by S-100 Computer -USB_TXE .EQU 40H ;If Bit 6 = 0 data CAN be written for transmission to PC -#ENDIF - -#ENDIF - -;-------------- S100Computers MSDOS Support Board PORT ASSIGNMENTS -#IF S100MSDENABLE -CMOS_PORT .EQU 70H ;Base Port for CMOS Chip on MSDOS Support Board -MASTER_PIC_PORT .EQU 20h ;Hardware port the 8259A (two ports 20H & 21H) -MasterICW1 .EQU 00010111B ;EDGE triggered, 4 bytes, single Master,ICW4 needed -MasterICW2 .EQU 8H ;Base address for 8259A Int Table (IBM-PC uses 8X4 = 20H) -MasterICW3 .EQU 0H ;No slave -MasterICW4 .EQU 00000011B ;No special mode, non buffer, Auto EOI, 8086. ;<<<<, -#ENDIF - - -;--------------- PORTS FOR FOR Z80/WD2793 ZFDC Board -#IF S100ZFDCENABLE -S100_DATA_A .EQU 10H ;IN, S100 Data port to GET data to from FDC Board -S100_DATA_B .EQU 10H ;OUT, S100 Data port to SEND data to FDC Board -S100_STATUS_A .EQU 11H ;Status port for A -S100_STATUS_B .EQU 11H ;Status port for B -RESET_ZFDC_PORT .EQU 13H ;Port to reset ZFDC Z80 CPU. - -STATUS_DELAY .EQU 5 ;Time-out for waiting for ZFDC Board handshake signal (~0.5 seconds @ 10MHz) -DIRECTION_BIT .EQU 7 ;Bits for the ZFDC flags 0 = IN, 1 = OUT -DATA_IN_RDY .EQU 0 ;Bit for data available from ZFDC board -DATA_OUT_RDY .EQU 1 ;Bit for data can be sent to ZFDC board -STD8IBM .EQU 1 ;IBM 8" SDSS Disk -NO_ERRORS_FLAG .EQU 0 ;No Errors flag for previous cmd, sent back to S-100 BIOS - -;Commands to the ZFDC Board:- -CMD_RESET_ZFDC .EQU 3H ;Reset the WD2793 chip and Board software -CMD_SET_FORMAT .EQU 4H ;This will select a specified drive and assign a disk format table to that drive -CMD_SET_DRIVE .EQU 5H ;This will select a specified drive (0,1,2,3) -CMD_SET_TRACK .EQU 7H ;This will set head r.EQUest to a specified track -CMD_SET_SIDE .EQU 8H ;This will set side r.EQUest to a specified side -CMD_SET_SECTOR .EQU 9H ;This will set sector r.EQUest to a specified sector -CMD_SET_HOME .EQU 0AH ;This will set head r.EQUest to Track 0 of CURRENT drive -CMD_STEP_IN .EQU 0BH ;Step head in one track of CURRENT drive -CMD_SEEK_TRACK .EQU 0EH ;Seek to track to (IY+DRIVE_TRACK) with the track verify bit set on CURRENT drive/format -CMD_READ_SECTOR .EQU 10H ;Read data from the CURRENT sector (on current track,side,drive). -CMD_HANDSHAKE .EQU 21H ;Handshake command only sent during board initilization/testing -CMD_RD_MULTI_SECTOR .EQU 29H ;Read data from multiple sectors starting at the CURRENT sector (on current track,side,drive). -#ENDIF - -;-------------- PORT(S) TO SWITCH MASTER/SLAVE(S) -Z80PORT .EQU 0D0H ;4 PORTS ON Z80 BOARD FOR MEMORY MANAGEMENT (& INT Controller on IA Z80 CPU Board) -Z80MMUL .EQU Z80PORT+2 ; MMU port for lower 16k block -Z80MMUH .EQU Z80PORT+3 ; MMU port for upper 16k block - - -SW86 .EQU 0EDH ;INPUT FROM THIS PORT SWITCHES IN THE 8088,8086, or 80286 board -SW68K .EQU 0ECH ;INPUT FROM THIS PORT SWITCHES IN THE 68000 CPU Board - - -;-------------- VERSAFLOPPY-II FLOPPY DISK CONTROLLER COMMANDS ETC. -#IF S100VFIIENABLE -X .EQU 50H ;BASE PORT FOR 1791 -RSET .EQU X+0 ;CONTROLLER RESET ADDRESS -SELECT .EQU X+3 ;DRIVE SELECT PORT -STATUS .EQU X+4 ;STATUS PORT -TRACK .EQU X+5 ;TRACK PORT -SECTOR .EQU X+6 ;SECTOR PORT -DATA .EQU X+7 ;DATA PORT -CMD .EQU X+4 ;COMMAND PORT -#ENDIF - -CIOBYTE .EQU 03H -CDISK1 .EQU 04H -ZERO_L .EQU 08H ;Some of my CPM Loader's needs these to be zero! -ZERO_H .EQU 09H ;(The Non Banked version of CPM3). Need to later see why -_TADDR .EQU 40H -_UNIT .EQU 42H ;NEW @UNIT BYTE -_SCTR .EQU 43H ;SECTOR (compatible with my old CPM2.2 Versafloppy BIOS) -_TRK .EQU 44H ;TRACK -_NREC .EQU 45H ;# OF SECTORS -_ERMASK .EQU 46H ;ERROR MASK -_ERSTAT .EQU 47H ;ERROR FLAG STORE -_IDSV .EQU 48H ;6 BYTES (USED FOR TRACK ID COMMAND) -_CMDSV .EQU 4EH ;COMMAND SAVE -_SPSV .EQU 4FH ;SP SAVE -TEMP2 .EQU 51H ;2 BYTE TEMP RECORD -_SIDE .EQU 51H ;SIDE STORE FOR MSDOS DISK -_COUNT .EQU 53H ;SECTORS/TRACK for BOOT (Currently unused) -_UNITCK .EQU 55H ;OLD @UNIT BYTE -_RSEEK .EQU 56H ;NBR OF RESEEKS -_RTRY .EQU 57H ;NBR OF RTRYS -ADRIVE .EQU 58H ;STORE OF A: DRIVE DENSITY ETC TYPE -BDRIVE .EQU 59H ;STORE OF B: DRIVE TYPE - -_FDCTYPE .EQU 5BH ;0FFH = ZFDC FDC Board Boot, else Versafloppy II FDC Boot, - -_SEC_SIZE .EQU 5CH ;Byte count of a sector fot loader -_SSTACK .EQU 80H ;SYSTEM STACK - -COLD .EQU 80H ;COLD START ADDRESS FOR CPM FLOPPY (ONLY) BOOT LOADER - -RDACMD .EQU 0C0H ;READ ADDRESS CODE -RDCMD .EQU 088H ;READ SECTOR CODE -WRCMD .EQU 0A8H ;WRITE SECTOR CODE -WRTCMD .EQU 0F4H ;WRITE TRACK CODE -RSCMD .EQU 008H ;RESTORE COMMAND (Note 3 Ms seek) -SKNCMD .EQU 018H ;SEEK NO VERIFY -FSKCMD .EQU 01CH ;FLOPPY SEEK COMAND -RSVCMD .EQU 00CH ;RESTORE WITH VERIFY COMMAND -MSKCMD .EQU 01FH ;MINI FLOPPY SEEK COMMAND - -SRMASK .EQU 0FEH ;SECTOR READ ERROR BITS MASK - -STDSDT .EQU 26 ;STANDARD 8" 26 SECTORS/TRACK -STDDDT .EQU 50 ;STANDARD DD 8" 50 SECTORS/TRACK -NBYTES .EQU 128 ;BYTES/SECTOR -NTRKS .EQU 77 ;TRACKS/DISK - - -;-------------- S100Computers IDE HARD DISK CONTROLLER COMMANDS ETC. -#IF S100DIDEENABLE -IDEAport .EQU 030H ;lower 8 bits of IDE interface -IDEBport .EQU 031H ;upper 8 bits of IDE interface -IDECport .EQU 032H ;control lines for IDE interface -IDECtrl .EQU 033H ;8255 configuration port -IDEDrivePort .EQU 034H ;To select the 1st or 2nd CF card/drive (Not used with this monitor) - -IDE_Reset_Delay .EQU 020H ;Time delay for reset/initilization (~60 uS, with 10MHz Z80, 2 I/O wait states) - -CPM_ADDRESS .EQU 100H ;Will place the CPMLDR.COM Loader here with - ;CPMLDR.COM will ALWAYS be on TRK 0,SEC2, (LBA Mode) -SEC_COUNT .EQU 12 ;CPMLDR.COM r.EQUires (currently) 10, 512 byte sectors - ;Add extra just in case -; -RDcfg8255 .EQU 10010010B ;Set 8255 IDECport out, IDEAport/B input -WRcfg8255 .EQU 10000000B ;Set all three 8255 ports output -; -IDEa0line .EQU 01H ;direct from 8255 to IDE interface -IDEa1line .EQU 02H ;direct from 8255 to IDE interface -IDEa2line .EQU 04H ;direct from 8255 to IDE interface -IDEcs0line .EQU 08H ;inverter between 8255 and IDE interface -IDEcs1line .EQU 10H ;inverter between 8255 and IDE interface -IDEwrline .EQU 20H ;inverter between 8255 and IDE interface -IDErdline .EQU 40H ;inverter between 8255 and IDE interface -IDEreset .EQU 80H ;inverter between 8255 and IDE interface -; -;Symbolic constants for the IDE Drive registers, which makes the -;code more readable than always specifying the address pins -; -REGdata .EQU 08H ;IDEcs0line -REGerr .EQU 09H ;IDEcs0line + IDEa0line -REGcnt .EQU 0AH ;IDEcs0line + IDEa1line -REGsector .EQU 0BH ;IDEcs0line + IDEa1line + IDEa0line -REGcyLSB .EQU 0CH ;IDEcs0line + IDEa2line -REGcyMSB .EQU 0DH ;IDEcs0line + IDEa2line + IDEa0line -REGshd .EQU 0EH ;IDEcs0line + IDEa2line + IDEa1line ;(0EH) -REGCMD .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line ;(0FH) -REGstatus .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line -REGcontrol .EQU 16H ;IDEcs1line + IDEa2line + IDEa1line -REGastatus .EQU 17H ;IDEcs1line + IDEa2line + IDEa1line + IDEa0line - -;IDE CMD Constants. These should never change. -CMDrecal .EQU 10H -CMDread .EQU 20H -CMDwrite .EQU 30H -CMDinit .EQU 91H -CMDid .EQU 0ECH -CMDdownspin .EQU 0E0H -CMDupspin .EQU 0E1H -; -; IDE Status Register: -; bit 7: Busy 1=busy, 0=not busy -; bit 6: Ready 1=ready for CMD, 0=not ready yet -; bit 5: DF 1=fault occured insIDE drive -; bit 4: DSC 1=seek complete -; bit 3: DRQ 1=data r.EQUest ready, 0=not ready to xfer yet -; bit 2: CORR 1=correctable error occured -; bit 1: IDX vendor specific -; bit 0: ERR 1=error occured -; -;---------------------------------------------------------------------------- -; -;CONNECTIONS TO Z80-MONB.Z80 :- -; -#ENDIF - -#IF BIGROM -BASE .EQU 0E000H ;Start or EPROM Location (Assume a 278C64 (8k) ) -#ELSE -BASE .EQU 0F000H ;Start or EPROM Location (Assume a 2732 (4K) or half of a 278C64 (8k) ) -#ENDIF ; endif 8kROM - - .ORG BASE ;<--------<<<<<< LOCATION OF START OF MONITOR (First part) -VERSA .EQU BASE+800H ;<--------<<<<<< LOCATION OF FLOPPY BIOS (For old Software) - ; NOTE MUST INSURE NO OVERFLOW OF THE FIRST - ; PART OR THIS MONITOR INTO THIS BIOS AREA - -;PROGRAM CODE BEGINS HERE -;FIRST A JUMP TABLE FOR ALL JUMPS INTO THE MONITOR. NOTE THESE CANNOT BE -;CHANGED. WHERE POSSIBLE ZAPPLE FORMAT IS USED. - -ZAPPLE: JP BEGIN ;INITILIZATION -ZCI: JP CI ;CONSOL INPUT -ZRI: JP SERIAL_IN ;READER INPUT = Modem Input for Now -ZCO: JP CO ;CONSOL OUTPUT -ZPOO: JP SERIAL_OUT ;PUNCH OUTPUT = Modem Output for Now -ZLO: JP LO ;LIST OUTPUT -ZCSTS: JP CSTS ;CONSOL STATUS -ZMEMCK: JP MEMSIZ ;GET HIGHEST RAM RETURNS IT IN [HL] -ZTRAP: JP TRAP ;ERROR TRAP ADDRESS -ZSTART: JP START ;JUMP TO MONITOR DO NOT RESET HARDWARE -ZTALK: JP SPEAKOUT ;SEND AN ASCII CHARACTER TO TALKER (One at a time) -ZTALKS: JP SPEAKER_CTS ;STATUS FOR SPEECH CTS Line (V-Stamp CTS low when ready) -ZDELAY: JP DELAY ;SOFTWARE DELAY LENGTH IN [A] -ZLSTAT: JP LSTAT ;LIST STATUS -ZONLIST: JP ONLIST ;INITILIZE LIST DEVICE -ZOFFLIST: JP OFLIST ;TURN OFF LIST DEVICE -ZTIME: JP PRINT_TIME ;PUT TIME ON CRT @ CURSOR POSITION -ZDATE: JP PRINT_DATE ;PRINT DATE ON CRT @ CURSOR POSITION -ZSPEAK_: JP SPEAK_ ;SEND ASCII STRING TO TALKER [HL] UP TO '$' -ZSERIAL_OUT: JP SERIAL_OUT ;OUT TO ZILOG SCC SERIAL PORT -ZSERIAL_IN: JP SERIAL_IN ;INPUT FROM ZILOG SCC SERIAL PORT -ZSERIAL_STAT: JP SERIAL_STAT ;STATUS FROM ZILOG SCC SERIAL PORT -ZLOADER: JP LOADER ;LOAD IN CPM IMAGE ON TRACKS 0 & 1 (VIA FLOPPY BOOT LOADER ON DISK SECTOR 1) -ZPMSG0: JP TOM ;DISPLAY STRING ON CONSOL [HL]=START ADD. [B]=LENGTH -ZPMSG_: JP PRINT_STRING ;DISPLAY STRING ON CONSOL [HL]=START ADD. '$'=END -ZHLSP: JP HLSP ;DISPLAY [HL] ON CONSOL THEN ONE SPACE -ZBITS: JP BITS1 ;DISPLAY 8 BITS OF [A] ON CONSOL -ZLBYTE: JP LBYTE ;DISPLAY [A] ON CONSOL -ZHEXSP: JP HEXSP ;PUT 16 BIT PARAMETERS ON STACK FROM CONSOL, [C]=PARAMETER # -ZCRLF: JP CRLF ;SEND CRLF TO CONSOL -ZHILO: JP HILO ;RANGE CHECK (INC [HL], IF HL=DE THEN SET CARRY) -ZCONV: JP CONV ;CONVERT HEX IN [A] TO ASCII IN [A] -ZDOS JP MSDOS ;LOAD MSDOS FROM 5" DRIVE D: -ZPCHK: JP PCHK ;INPUT FROM CONSOL & TEST FOR DELIMITERS RET {Z} IF - ;SPACE OR , RET {C} IF A CR ELSE NON ZERO NON CARRY -VFLOPPY JP VBOOT ;BOOT UP CPM-80 FROM VERSAFLOPPY II FDC -ZHARD: JP HBOOTCPM ;BOOT UP CPM-80 FROM HARD DISK -ZPRDY: JP PRDY ;PUNCH READY CHECK -ZRSTAT: JP RSTAT ;READER STATUS -ZCCHK: JP CCHK ;CHECK FOR ^S & ESC AT KEYBOARD -ZFLOPPY JP ZBOOT ;BOOT UP CPM-80 FROM ZFDC FDC -; -; NOTE TABLE MUST BE WITHIN 0-FFH BOUNDRY -; -;COMMAND BRANCH TABLE - -TBL: - .DW FLUSH ; "@" SEND FF to LaserJet printer - .DW MEMMAP ; "A" DISPLAY A MAP OF MEMORY - .DW SWITCH_68K ; "B" SWITCH CONTROL TO 68000 CPU - .DW ZBOOT ; "C" BOOT IN CP/M FROM 8" DISK WITH WITH ZFDC FDC - .DW DISP ; "D" DISPLAY MEMORY (IN HEX & ASCII) - .DW ECHO ; "E" ECHO CHAR IN TO CHAR OUT - .DW FILL ; "F" FILL MEMORY WITH A CONSTANT - .DW GOTO ; "G" GO TO [ADDRESS] - .DW SHOW_DATE ; "H" SHOW CURRENT DATE - .DW SHOW_TIME ; "I" SHOW CURRENT TIME - .DW RAMTEST ; "J" NON-DESTRUCTIVE MEMORY TEST - .DW KCMD ; "K" DISPLAY THE LIST OF MONITOR COMMANDS - .DW VBOOT ; "L" BOOT IN CP/M FROM 8" DISK WITH VERSAFLOPPY II FDC - .DW MOVE ; "M" MOVE BLOCK OF MEMORY (START,FINISH,DESTINATION) - .DW XMEMMAP ; "N" Display extended memory Segment:Address - .DW UP8086 ; "O" SWITCH CONTROL TO 8088, 8086 or 80286. - .DW HBOOTCPM ; "P" BOOT IN CPM FROM IDE HARD DISK - .DW QUERY ; "Q" QUERY PORT (IN OR OUT) - .DW INPORTS ; "R" Read ALL Input Ports - .DW SUBS ; "S" SUBSTITUTE &/OR EXAMINE MEMORY - .DW TYPE ; "T" TYPE ASCII PRESENT IN MEMORY - .DW BEGIN ; "U" SPARE - .DW VERIFY ; "V" COMPARE MEMORY - .DW SWITCH_8086 ; "W" INPUT Port ED (switched in 8086/80286) - .DW START ; "X" BOOT IN MSDOS FROM HARD DISK (Not done yet) - .DW BOOT_RomWBW ; "Y" Boot RomWBW - .DW SIZE ; "Z" FIND HIGHEST R/W RAM - -; -;--------------------------------------------------------------------------- -; -BEGIN: - -#IF S100I4SCREAM - ld a,1 - ld c,GBUSR - out (c),a - ld a,S100I4MODE1 - ld c,GBUM - out (c),a - ld a,S100I4MODE2 - ld c,GBUM - out (c),a - ld a,S100I4CMD ; dtr,break,reset,rts - ld C,GBUC ; set up command port - out (c),a - ld c,GBUS -i4scrmlp: - in a,(c) - and i4TBMT - jr z,i4scrmlp - ld c,GBUD - ld a,'!' - out (c),a - jr i4scrmlp - -#ENDIF - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -#IF S100IOENABLE - ; We are using the serial port's extra I/O port as a diagnostic port, so we need to - ; set them up here at the start of the code. - ; Port A as output to a pair of Hex Displays. - ; Port B as input from a 8 position dip switch. - LD A,AoutBin8255cfg ;A out to Hex LED, B In Dip , C(bits 0-3) output, (bits 4-7)input - OUT (PortCtrl_8255),A ;Config 8255 chip, Mode 0 -#ENDIF - -#IF S100SDSVIDENABLE - LD A,'#' ;For quick hardware diagnostic test - OUT (CONSOL_OUT),A -#ENDIF - -#IF S100IOENABLE - LD A,0FFH ;Clear Printer strobe, comes up 0 on a reset - OUT (PRINTER_STROBE),A ;also it turn all LED's off as a diagnostic - LD A,00000000B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC (ALL LED' ON) - OUT (DIAG_LEDS),A ;LED's will go off one at a time -#ENDIF - -#IF S100VFIIENABLE - LD A,0FFH - OUT (SELECT),A ;DESELECT ANY FLOPPYS ON VERSAFLOPPY FDC (If Present) -#ENDIF - -#IF S100IOENABLE - LD A,10000000B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC (1 LED off) - OUT (DIAG_LEDS),A -#ENDIF - - LD A,0FFH -#IF S100VFIIENABLE - OUT (RSET),A ;RESET VERSAFLOPPY II FLOPPY DISK CONTROLLER (If Present) -#ENDIF -#IF S100ZFDCENABLE - OUT (RESET_ZFDC_PORT),A ;RESET ZFDC FLOPPY DISK CONTROLLER (If Present) -#ENDIF - - XOR A ;SET INTERUPT TO PAGE 0H -#IF S100ISCPUENABLE - OUT (Z80PORT+1),A ;KILL THE INTERSYSTEMS Z80 CPU BOARD INT CONTROLLER (If present) -#ENDIF - LD I,A - -#IF S100MSDENABLE - ;We need to clear the 8259A otherewise teh 8086 monitor sometimes hangs - LD A,MasterICW1 ;Initilize the 8259A PIC Controller (;EDGE triggered, 4 bytes, single Master,ICW4 needed) - OUT (MASTER_PIC_PORT),A - LD A,MasterICW2 ;Ints starts at 20H in RAM (IBM-PC uses 8X4 = 20H) - OUT (MASTER_PIC_PORT+1),A - LD A,MasterICW4 ;No slaves above, so 8259 does not expect ICW3 - out (MASTER_PIC_PORT+1),A - - LD A,11111111b ;Allow no interrupts to 8259A with Z80. - out (MASTER_PIC_PORT+1),A -#ENDIF - - LD A,0H ;SETUP MEMORY MANAGEMENT TO OVERLAP WITH - OUT (Z80PORT+2),A ;CURRENT RAM in 64K Space - LD A,04H - OUT (Z80PORT+3),A - -#IF S100IOENABLE - LD A,11000000B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC (2 LED's off) - OUT (DIAG_LEDS),A -#ENDIF - -ZAXXLE: LD SP,AHEAD-4 ;SETUP A FAKE STACK - JP MEMSZ1 ;RETURNS WITH TOP OF RAM IN [HL] - .DW AHEAD ;Ret will pick up this address -AHEAD: LD SP,HL ;[HL] CONTAINS TOP OF RAM - WORKAREA - - PUSH HL - POP IX ;Store stack pointer for below in [IX] - -#IF S100IOENABLE - CALL INIT_S100_IO ;Initilize the Zilog 8530 & 8255 on the S100Computers I/O Board -#ENDIF - - -#IF S100I3ENABLE - LD A,0 - CALL i3_config - LD A,1 - CALL i3_config - LD A,2 - CALL i3_config - LD A,3 - CALL i3_config - LD A,4 - CALL i3_config - LD A,5 - CALL i3_config - LD A,6 - CALL i3_config - LD A,7 - CALL i3_config -scream: - LD A,0 - LD C,'*' - CALL i3_output - LD A,1 - LD C,'*' - CALL i3_output - LD A,2 - LD C,'*' - CALL i3_output - LD A,3 - LD C,'*' - CALL i3_output - LD A,4 - LD C,'*' - CALL i3_output - LD A,5 - LD C,'*' - CALL i3_output - LD A,6 - LD C,'*' - CALL i3_output - LD A,7 - LD C,'*' - CALL i3_output - JP scream -#ENDIF - -#IF S100I4ENABLE - LD A,1 - CALL i4_config - LD A,2 - CALL i4_config - LD A,3 - CALL i4_config -scream: - LD A,1 - LD D,'*' - CALL i4_output - LD A,2 - LD D,'*' - CALL i4_output - LD A,3 - LD D,'*' - CALL i4_output - JP scream -#ENDIF - - - LD HL,MSG0 ;Have a Stack, so we can use CALL - CALL PRINT_STRING - -#IF S100IOENABLE - LD A,11100000B ;FLAG PROGRESS (Have a Stack with 3 LED's off) - OUT (DIAG_LEDS),A -#ENDIF - CALL PRINT_TIME ;PRINT TIME ON CRT (IF RTC BOARD PRESENT) - JP C,NO_CLOCK - LD HL,GAP_MSG - CALL PRINT_STRING - CALL PRINT_DATE ;PRINT DATE ON CRT, then CRLF -NO_CLOCK: - CALL CRLF - -#IF S100IOENABLE - LD A,11110000B ;FLAG PROGRESS (I/O board initilized, 4 LED's Off) - OUT (DIAG_LEDS),A -#ENDIF - - LD HL,SP_MSG ;Print Current Stack Location - CALL PRINT_STRING - - - PUSH IX ;SP is stored from above in [IX] - POP HL - CALL HLSP ;Print HL/SP - CALL CRLF ;Then CRLF - CALL CSTS ;CHECK IF GARBAGE AT KEYBOARD - CALL NZ,CI ;If so flush it - -#IF S100IOENABLE - LD A,11111000B ;FLAG PROGRESS (Ready to go, 5 LED's off) - OUT (DIAG_LEDS),A -#ENDIF -#IF S100IOVSENABLE - LD HL,CR_SMSG ;lets V-Stamp chip get baud rate - CALL SPEAK_ -#ENDIF ; S100IOVSENABLE - - -#IF S100DIDEENABLE - CALL INITILIZE_IDE_BOARD ;initilize first IDE drive (if present) -#ENDIF - -#IF S100IOENABLE - LD A,11111100B ;FLAG PROGRESS (Initilization done, 6 LED's off) - OUT (DIAG_LEDS),A -#ENDIF - -;-------THIS IS THE START ON THE MAIN MONITOR LOOP-------------------------------- - -START: LD DE,START - PUSH DE ;EXTRA UNBALANCED POP & [DE] WOULD END UP IN [PC] - CALL CRLF - LD C,BELL ;A BELL HERE WILL SIGNAL WHEN JOBS ARE DONE - CALL CO - LD C,'-' - CALL CO - LD C,'>' - CALL CO - -STARO: CALL TI ;Main loop. Monitor will stay here until cmd. - AND 7FH - JR Z,STARO - SUB '@' ;Commands @ to Z only - RET M - CP 1BH ;A-Z only - RET NC - ADD A,A - LD HL,TBL - ADD A,L - LD L,A - LD A,(HL) - INC HL - LD H,(HL) - LD L,A - LD C,02H - JP (HL) ;JUMP TO COMMAND TABLE -; -;----- GO CARRY OUT COMMAND AND POP BACK TO START---------- -; NOTE STRING IS HERE IN CASE A 2716 IS USED BY MISTAKE (Monitor will at least signon) - -MSG0: -#IF S100SDSVIDENABLE - .DB SCROLL,QUIT,NO_ENHANCEMENT,FAST,BELL,CR,LF,LF -#ENDIF - .TEXT "Configurable Z80 ROM MONITOR V4.7C (RomWBW Version of 9 January 2013) $" -SMSG: .TEXT "Hello The Z80 ROM MONITOR Ver 4.7B Is Now Resident $" - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -#IF S100I3ENABLE -#INCLUDE "s100-i3.asm" -#ENDIF - -#IF S100I4ENABLE -#INCLUDE "s100-i4.asm" -#ENDIF - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;SEND MESSAGE TO CONSOL MESSAGE IN [HL],LENGTH IN [B] - -TOM: - LD C,(HL) - INC HL - CALL CO - DJNZ TOM - RET -; -PRINT_STRING: - LD A,(HL) ;A ROUTINE TO PRINT OUT A STRING @ [HL] - INC HL ;UP TO THE FIRST '$'. - CP '$' - RET Z - LD C,A - CALL CO - JR PRINT_STRING - -;ABORT IF ESC AT CONSOL, PAUSE IF ^S AT CONSOL - -CCHK: CALL CSTS ;FIRST IS THERE ANYTHING THERE - RET Z - CALL CI - CP 'S'-40H - JR NZ,CCHK1 -CCHK2: CALL CSTS ;WAIT HERE UNTIL ANOTHER INPUT IS GIVEN - JR Z,CCHK2 -CCHK1: CP ESC - RET NZ ;RETURN EXECPT IF ESC - -;RESTORE SYSTEM AFTER ERROR - -ERROR: - CALL MEMSIZ ;GET RAM AVAILABLE - WORKSPACE IN [HL] - LD SP,HL ;SET STACK UP IN WORKSPACE AREA - LD C,'*' - CALL CO - JP START - -;PRINT HIGHEST MEMORY FROM BOTTOM - -SIZE: - CALL MEMSIZ ;RETURNS WITH [HL]= RAM AVAILABLE-WORKSPACE - -LFADR: CALL CRLF - -;PRINT [HL] AND A SPACE -HLSP: PUSH HL - PUSH BC - CALL LADR - LD C,SPACE - CALL CO - POP BC - POP HL - RET - -;PRINT A SPACE - -SF488: LD C,SPACE - JP CO - -;CONVERT HEX TO ASCII - -CONV: AND 0FH - ADD A,90H - DAA - ADC A,40H - DAA - LD C,A - RET - -;GET TWO PARAMETERS AND PUT THEM IN [HL] & [DE] THEN CRLF - -EXLF: CALL HEXSP - POP DE - POP HL - -;SEND TO CONSOL CR/LF - -CRLF: PUSH BC - LD C,LF - CALL CO - LD C,CR - CALL CO - POP BC - RET - -;PUT THREE PARAMETERS IN [BC] [DE] [HL] THEN CR/LF - -EXPR3: INC C ;ALREADY HAD [C]=2 FROM START - CALL HEXSP - CALL CRLF - POP BC - POP DE - POP HL - RET - -;GET ONE PARAMETER - -EXPR1: LD C,01H -HEXSP: LD HL,0000 -EX0: CALL TI -EX1: LD B,A - CALL NIBBLE - JR C,EX2X - ADD HL,HL - ADD HL,HL - ADD HL,HL - ADD HL,HL - OR L - LD L,A - JR EX0 -EX2X: EX (SP),HL - PUSH HL - LD A,B - CALL QCHK - JR NC,SF560 - DEC C - RET Z -SF560: JP NZ,ERROR - DEC C - JR NZ,HEXSP - RET -EXF: LD C,01H - LD HL,0000H - JR EX1 - -;RANGE TEST ROUTINE CARRY SET = RANGE EXCEEDED - -HILOX: CALL CCHK - CALL HILO - RET NC - POP DE ;DROP ONE LEVEL BACK TO START - RET -HILO: INC HL ;RANGE CHECK SET CARRY IF [DE]=[HL] - LD A,H - OR L - SCF - RET Z - LD A,E - SUB L - LD A,D - SBC A,H - RET - -;PRINT [HL] ON CONSOL - -LADR: - LD A,H - CALL LBYTE - LD A,L -LBYTE: - PUSH AF - RRCA - RRCA - RRCA - RRCA - CALL SF598 - POP AF -SF598: - CALL CONV - JP CO - -;THIS IS A CALLED ROUTINE USED TO CALCULATE TOP OF RAM IS USED BY -;THE ERROR TO RESET THE STACK. Returns top of RAM in [HL] - -MEMSIZ: - PUSH BC ;SAVE [BC] -MEMSZ1: - LD HL,0FFFFH ;START FROM THE TOP DOWN -MEMSZ2: - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL ;PUT BACK WHAT WAS THERE - LD (HL),A - JP Z,GOTTOP - DEC H ;TRY 100H BYTES LOWER - JR MEMSZ2 ;KEEP LOOKING FOR RAM -GOTTOP: - POP BC ;RESTORE [BC] - RET - -NIBBLE: - SUB 30H - RET C - CP 17H - CCF - RET C - CP LF - CCF - RET NC - SUB 07H - CP LF - RET - -COPCK: - LD C,'-' - CALL CO - -PCHK: CALL TI - -;TEST FOR DELIMITERS - -QCHK: - CP SPACE - RET Z - CP ',' - RET Z - CP CR - SCF - RET Z - CCF - RET - -;KEYBOARD HANDELING ROUTINE (WILL NOT ECHO CR/LF) -;IT CONVERTS LOWER CASE TO UPPER CASE FOR LOOKUP COMMANDS -;ALSO ^C WILL FORCE A JUMP TO BOOT IN CP/M -;ALL OTHERE CHARACTERS ARE ECHOED ON CONSOL - -TI: - CALL CI - CP CR - RET Z - CP 'C'-40H ;^C TO BOOT IN CP/M - JP Z,FBOOT - PUSH BC - LD C,A - CALL CO - LD A,C - POP BC - CP 40H ;LC->UC - RET C - CP 7BH - RET NC -SF754: - AND 5FH - RET - -BITS1: PUSH DE ;DISPLAY 8 BITS OF [A] - PUSH BC - LD E,A - CALL BITS - POP BC - POP DE - RET - -BITS: LD B,08H ;DISPLAY 8 BITS OF [E] - CALL SF488 -SF76E: SLA E - LD A,18H - ADC A,A - LD C,A - CALL CO - DJNZ SF76E - RET -; -;<<<<<<<<<<<<<<<<<<<<<< MAIN CONSOL OUTPUT ROUTINE >>>>>>>>>>>>>>>>>>>>>>>>> -; If console board is NOT installed, their is issues with default status BITS -; returning bad info keeping Serial Board form working. For now we will -; just force serial I/O - -CO: -; IN A,(IOBYTE1) ;NOTE CHARACTER IS IN [C] -; BIT 0,A ;CHECK IF OUTPUT TO PRINTER IS ALSO REQ -; JP Z,LOX - -#IF S100SDSVIDENABLE -SDCONO: - IN A,(CONSOL_STATUS) ;SD SYSTEMS VIDIO BOARD PORT - AND 4H - JR Z,SDCONO - LD A,C - CP 07H ;IS IT A BELL - JR Z,BELL1 - CP 0H ;SD BOARD CANNOT TAKE A NULL! - RET Z - - OUT (CONSOL_OUT),A - IN A,(IOBYTE1) - BIT 5,A ;SEE IF SERIAL PORT OUTPUT IS REQ - JR NZ,SDCON5 ;MAKE SURE TO RETURN CHARACTER SENT IN [A] -#ENDIF - - CALL SERIAL_OUT ;Send data in [C] to Serial Port -SDCON5: LD A,C - RET ;RETURN CHARACTER SENT IN [A] - -;LOX: -; CALL SDCONO ;OUTPUT TO BOTH PRINTER & CONSOLE -; CALL LO -; RET - -#IF S100SDSVIDENABLE -BELL1: - LD A,06H ;SEND A BELL - OUT (CONSOL_OUT),A - LD A,0FH - CALL DELAY - LD A,07H - OUT (CONSOL_OUT),A - JR SDCON5 -#ENDIF - -DELAY: - DEC A ;GENERAL COUNT DOWN TIME DELAY - RET Z ;LENGTH SET IN [A] - PUSH AF - LD A,05H -MORE: DEC A - PUSH AF - XOR A -MORE2: DEC A - JR NZ,MORE2 - POP AF - JR NZ,MORE - POP AF - JR DELAY - -;<<<<<<<<<<<<<<<<<<< MAIN CONSOL STATUS ROUTINE >>>>>>>>>>>>>>>>>>>>>> -; -; If console board is NOT installed, their is issues with default status BITS -; returning bad info keeping Serial Board form working. For now we will -; just force serial I/O and have commented out routines for CONSOLE I/O - -CSTS: - -#IF S100SDSVIDENABLE - IN A,(CONSOL_STATUS) - AND 02H - JP Z,TRYSER ;See if input from Serial Port is req - XOR A - DEC A ;RETURN WITH 0FFH IN [A] IF SOMETHING - RET -#ENDIF - -TRYSER: - -; IN A,(IOBYTE1) -; BIT 5,A ;SEE IF SERIAL PORT INPUT IS REQ -; JP Z,SERIAL_STAT ;Check if anything at Modem IN status routine - JP SERIAL_STAT ;Check if anything at Modem IN status routine -; XOR A ;IF IOBYTE bit 1 then skip modem input -; RET ;RETURN WITH 0 IN A IF NOTHING THERE - - -;<<<<<<<<<<<<<<<<<<<< MAIN CONSOL INPUT ROUTINE >>>>>>>>>>>>>>>>>>>> - -CI: - -#IF S100SDSVIDENABLE - IN A,(CONSOL_STATUS) ;NEED CONSTAT TO CLEAN UP SHIFT KEYS ETC - AND 02H - JR Z,CHKSERIAL - JP CHKSERIAL ; Force it for now - IN A,(CONSOL_IN) - AND 7FH - RET -#ENDIF - -CHKSERIAL: -; IN A,(IOBYTE1) -; BIT 5,A ;SEE IF SERIAL PORT INPUT IS REQ -; JR NZ,CI ;NO, then do normal CI - CALL SERIAL_STAT ;See if anything at Modem input - JP Z,CI ; No - JP SERIAL_IN ; Yes, lets get it - - -;>>>>>>>>>>>>>>>>>>>> MAIN PRINTER OUTPUT ROUTINE <<<<<<<<<<<<<<<<<<<<< - -LO: - LD B,0FFH -LO2: - CALL LSTAT - JR NZ,LO1 - DJNZ LO2 - XOR A - LD A,C - RET ;RET Z if Printer problem (Not switched on) -LO1: - LD A,0FFH ;Setup strobe high to low then high - OUT (PRINTER_STROBE),A - LD A,C - OUT (PRINTER_OUT),A ;Now Data - XOR A ;STROBE FOR CENTRONICS - OUT (PRINTER_STROBE),A - LD A,0FFH ;Raise strobe again - OUT (PRINTER_STROBE),A - OR A - RET ;Ret NZ if OK - -FLUSH: - LD C,FF ;Send a Form Feed to laserJet Printer - CALL LO ;This forces a partial page to be printed - RET - -;>>>>>>>>>>>>>>>>>>>>>> PRINTER STATUS ROUTINE <<<<<<<<<<<<<<<<<<<<<<<< - -LSTAT: - -#IF S100IOENABLE - IN A,(PRINTER_STATUS) - AND 00001111B ;XXXX0110 IS READY (BIT 3=PAPER BIT 2=FAULT - CP 00000110B ;BIT 1=SELECT BIT 0=BUSY - JR Z,LSTAT1 - XOR A - RET -LSTAT1: - XOR A ;PUT 0FFH IN [A] IF READY & NO ZERO FLAG - DEC A -#ENDIF - - RET - - -;-------------- BOOT RomWBW via loader ---------------- - -#IF S100WBWENABLE -BOOT_RomWBW: - - CALL ZCRLF - LD HL,RomWBW_Msg ;Print RomWBW loader sign on - CALL PRINT_STRING - JP ZSTART ; all done for now - -RomWBW_Msg: .TEXT "RomWBW Loader $" -#ENDIF - - - -;-------------- BOOT UP CPM FROM HARD DISK ON S100COMPUTERS IDE BOARD ---------------- - -;BOOT UP THE 8255/IDE Board HARD DISK/Flash Memory Card -;NOTE CODE IS ALL HERE IN CASE A 2716 IS USED - -HBOOTCPM: - POP HL ;CLEAN UP STACK - -#IF S100IOVSENABLE - LD HL,SPEAKCPM_MSG ;Announce on speaker - CALL SPEAK_ -#ENDIF - -#IF S100DIDEENABLE - CALL INITILIZE_IDE_BOARD ;Initilze the 8255 and drive (again just in case) - - LD D,11100000B ;Data for IDE SDH reg (512bytes, LBA mode,single drive) - LD E,REGshd ;00001110,(0EH) CS0,A2,A1, - CALL IDEwr8D ;Write byte to select the MASTER device - - LD B,0FFH ;Delay time to allow a Hard Disk to get up to speed -WaitInit: - LD E,REGstatus ;Get status after initilization - CALL IDErd8D ;Check Status (info in [D]) - BIT 7,D - JR Z,SECREAD ;Zero, so all is OK to write to drive - ;Delay to allow drive to get up to speed - PUSH BC - LD BC,0FFFFH -DXLAY2: - LD D,2 ;May need to adjust delay time to allow cold drive to -DXLAY1: - DEC D ;to speed - JR NZ,DXLAY1 - DEC BC - LD A,C - OR B - JR NZ,DXLAY2 - POP BC - DJNZ WaitInit ;If after 0FFH, 0FEH, 0FDH... 0, then drive initilization problem - - -IDError: - LD HL,DRIVE_NR_ERR ;Drive not ready - JP ABORT_ERR_MSG - -SECREAD: ;Note CPMLDR will ALWAYS be on TRK 0,SEC 1,Head 0 - -#IF S100IOENABLE - LD A,11111111B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC - OUT (DIAG_LEDS),A -#ENDIF - - CALL IDEwaitnotbusy ;Make sure drive is ready - JR C,IDError ;NC if ready - - LD D,1 ;Load track 0,sec 1, head 0 - LD E,REGsector ;Send info to drive - CALL IDEwr8D - - LD D,0 ;Send Low TRK# - LD E,REGcyLSB - CALL IDEwr8D - - LD D,0 ;Send High TRK# - LD E,REGcyMSB - CALL IDEwr8D - - LD D,SEC_COUNT ;Count of CPM sectors we wish to read - LD E,REGcnt - CALL IDEwr8D - - LD D,CMDread ;Send read CMD - LD E,REGCMD - CALL IDEwr8D ;Send sec read CMD to drive. - CALL IDEwdrq ;Wait until it's got the data - - LD HL,CPM_ADDRESS ;DMA address where the CPMLDR resides in RAM - LD B,0 ;256X2 bytes - LD C,SEC_COUNT ;Count of sectors X 512 -MoreRD16: - LD A,REGdata ;REG regsiter address - OUT (IDECport),A - - OR IDErdline ;08H+40H, Pulse RD line - OUT (IDECport),A - - IN A,(IDEAport) ;read the LOWER byte - LD (HL),A - INC HL - IN A,(IDEBport) ;read the UPPER byte - LD (HL),A - INC HL - - LD A,REGdata ;Deassert RD line - OUT (IDECport),A - DJNZ MoreRD16 - DEC C - JR NZ,MoreRD16 - - LD E,REGstatus ;Check the R/W status when done - CALL IDErd8D - BIT 0,D - JR NZ,IDEerr1 ;Z if no errors - LD HL,STARTCPM - LD A,(HL) - CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H - JP Z,STARTCPM ;AS THE FIRST INSTRUCTION. IF OK JP to 100H in RAM - JP ERR_LD1 ;Boot Sector Data incorrect - -IDEerr1: - LD HL,IDE_RW_ERROR ;Drive R/W Error - JP ABORT_ERR_MSG -#ENDIF - -; -------------------- SUPPORT ROUTINES ------------------------ - -INITILIZE_IDE_BOARD: ;Drive Select in [A]. Note leaves selected drive as [A] - -#IF S100DIDEENABLE - LD A,RDcfg8255 ;Config 8255 chip (10010010B), read mode on return - OUT (IDECtrl),A ;Config 8255 chip, READ mode - - ;Hard reset the disk drive - ;For some reason some CF cards need to the RESET line - ;pulsed very carefully. You may need to play around - LD A,IDEreset ;with the pulse length. Symptoms are: incorrect data comming - OUT (IDECport),A ;back from a sector read (often due to the wrong sector being read) - ;I have a (negative)pulse of 60 uSec. (10Mz Z80, two IO wait states). - - LD C,IDE_Reset_Delay ;~60 uS seems to work for the 5 different CF cards I have -ResetDelay: - DEC C - JP NZ,ResetDelay ;Delay (reset pulse width) - XOR A - OUT (IDECport),A ;No IDE control lines asserted (just bit 7 of port C) - - CALL DELAY_15 ;Need to delay a little before checking busy status - -IDEwaitnotbusy: ;Drive READY if 01000000 - LD B,0FFH - LD C,080H ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreWait: - LD E,REGstatus ;Wait for RDY bit to be set - CALL IDErd8D - LD A,D - AND 11000000B - XOR 01000000B - JR Z,DoneNotBusy - DJNZ MoreWait - DEC C - JR NZ,MoreWait -#ENDIF - SCF ;Set carry to indicate an error - RET - -DoneNotBusy: - - OR A ;Clear carry it indicate no error - RET - - - ;Wait for the drive to be ready to transfer data. -IDEwdrq: ;Returns the drive's status in Acc -#IF S100DIDEENABLE - LD B,0FFH - LD C,0FFH ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreDRQ: - LD E,REGstatus ;wait for DRQ bit to be set - CALL IDErd8D - LD A,D - AND 10001000B - CP 00001000B - JR Z,DoneDRQ - DJNZ MoreDRQ - DEC C - JR NZ,MoreDRQ - - SCF ;Set carry to indicate error - RET -DoneDRQ: -#ENDIF - OR A ;Clear carry - RET -; -;------------------------------------------------------------------ -; Low Level 8 bit R/W to the drive controller. These are the routines that talk -; directly to the drive controller registers, via the 8255 chip. -; Note the 16 bit I/O to the drive (which is only for SEC Read here) is done directly -; in the routine MoreRD16 for speed reasons. - -IDErd8D: ;READ 8 bits from IDE register in [E], return info in [D] -#IF S100DIDEENABLE - LD A,E - OUT (IDECport),A ;drive address onto control lines - - OR IDErdline ;RD pulse pin (40H) - OUT (IDECport),A ;assert read pin - - IN A,(IDEAport) - LD D,A ;return with data in [D] - - LD A,E ;<---Ken Robbins suggestion - OUT (IDECport),A ;Deassert RD pin - - XOR A - OUT (IDECport),A ;Zero all port C lines -#ENDIF - RET - - -IDEwr8D: ;WRITE Data in [D] to IDE register in [E] -#IF S100DIDEENABLE - LD A,WRcfg8255 ;Set 8255 to write mode - OUT (IDECtrl),A - - LD A,D ;Get data put it in 8255 A port - OUT (IDEAport),A - - LD A,E ;select IDE register - OUT (IDECport),A - - OR IDEwrline ;lower WR line - OUT (IDECport),A - - LD A,E ;<-- Kens Robbins suggestion, raise WR line - OUT (IDECport),A - - XOR A ;Deselect all lines including WR line - OUT (IDECport),A - - LD A,RDcfg8255 ;Config 8255 chip, read mode on return - OUT (IDECtrl),A -#ENDIF - RET - -;------------------------------------------------------------------------------------- - -;MEMORY MAP PROGRAM CF.DR.DOBBS VOL 31 P40. -;IT WILL SHOW ON CONSOL TOTAL MEMORY SUMMARY OF RAM,PROM, AND NO MEMORY -; -MEMMAP: - CALL ZCRLF - LD HL,0 - LD B,1 -MAP1: - LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A - JR NZ,MAP2 - CP (HL) - JR Z,PRINT -MAP2: - LD E,'P' ; Print P for prom -MAP3: - LD A,0FFH - CP (HL) - JR NZ,PRINT - INC L - XOR A - CP L - JR NZ,MAP3 - LD E,'.' ; Print . for no memory -PRINT: - LD L,0 - DEC B - JR NZ,NLINE - LD B,16 - CALL ZCRLF - CALL HXOT4 -NLINE: - LD A,SPACE - CALL OTA - LD A,E - CALL OTA - INC H - JR NZ,MAP1 - CALL ZCRLF - CALL ZCRLF - JP ZSTART - -;16 HEX OUTPUT ROUTINE - -HXOT4: - LD C,H - CALL HXO2 - LD C,L -HXO2: - LD A,C - RRA - RRA - RRA - RRA - CALL HXO3 - LD A,C -HXO3: - AND 0FH - CP 10 - JR C,HADJ - ADD A,7 -HADJ: - ADD A,30H -OTA: - PUSH BC - LD C,A - CALL ZCO ;SEND TO CONSOL - POP BC - RET - -;-------------DISPLAY MEMORY IN HEX - -DISP: CALL EXLF ;GET PARAMETERS IN [HL],[DE] - LD A,L ;ROUND OFF ADDRESSES TO XX00H - AND 0F0H - LD L,A - LD A,E ;FINAL ADDRESS LOWER HALF - AND 0F0H - ADD A,10H ;FINISH TO END 0F LINE -SF172: - CALL LFADR -SF175: - CALL BLANK - LD A,(HL) - CALL ZLBYTE - CALL HILOX - LD A,L - AND 0FH - JR NZ,SF175 - LD C,TAB ;INSERT A TAB BETWEEN DATA - CALL ZCO - LD B,4H ;ALSO 4 SPACES -TA11: - LD C,SPACE - CALL ZCO - DJNZ TA11 - LD B,16 ;NOW PRINT ASCII (16 CHARACTERS) - PUSH DE ;TEMPORLY SAVE [DE] - LD DE,0010H - SBC HL,DE - POP DE -T11: - LD A,(HL) - AND 7FH - CP ' ' ;FILTER OUT CONTROL CHARACTERS' - JR NC,T33 -T22: - LD A,'.' -T33: - CP 07CH - JR NC,T22 - LD C,A ;SET UP TO SEND - CALL ZCO - INC HL - DJNZ T11 ;REPEAT FOR WHOLE LINE - JR SF172 - -BLANK: - LD C,' ' - JP ZCO - -;-----------------INSPECT AND / OR MODIFY MEMORY - -SUBS: - LD C,1 - CALL ZHEXSP - POP HL -SF2E3: - LD A,(HL) - CALL ZLBYTE - LD C,'-' - CALL ZCO - CALL ZPCHK - RET C - JR Z,SF2FC - CP 5FH - JR Z,SF305 - PUSH HL - CALL EXF - POP DE - POP HL - LD (HL),E - LD A,B - CP CR - RET Z -SF2FC: - INC HL -SF2FD: - LD A,L - AND 07H - CALL Z,LFADR - JR SF2E3 -SF305: - DEC HL - JR SF2FD - -;----------------FILL A BLOCK OF MEMORY WITH A VALUE - -FILL: - CALL EXPR3 -SF1A5: - LD (HL),C - CALL HILOX - JR NC,SF1A5 - POP DE - JP ZSTART - -;---------------GO TO A RAM LOCATION - -GOTO: LD C,1 ;SIMPLE GOTO FIRST GET PARMS. - CALL HEXSP - CALL CRLF - POP HL ;GET PARAMETER PUSHED BY EXF - JP (HL) - -;--------------GET OR OUTPUT TO A PORT - -QUERY: - CALL ZPCHK - CP 'O' ;OUTPUT TO PORT - JR Z,SF77A - CP 'I' ;INPUT FROM PORT - JP Z,QQQ1 - LD C,'*' - JP ZCO ;WILL ABORT IF NOT 'I' OR 'O' -QQQ1: - LD C,1 - CALL ZHEXSP - POP BC - IN A,(C) - JP ZBITS -; -SF77A: - CALL ZHEXSP - POP DE - POP BC - OUT (C),E - RET - - -;--------------MEMORY TEST - -RAMTEST: - CALL EXLF -SF200: - LD A,(HL) - LD B,A - CPL - LD (HL),A - XOR (HL) - JR Z,SF215 - PUSH DE - LD D,B - LD E,A ;TEMP STORE BITS - CALL ZHLSP - CALL BLANK - LD A,E - CALL ZBITS - CALL ZCRLF - LD B,D - POP DE -SF215: - LD (HL),B - CALL HILOX - JR SF200 - -;---------------MOVE A BLOCK OF MEMORY TO ANOTHER LOCATION - -MOVE: - CALL EXPR3 -SF21E: - LD A,(HL) - LD (BC),A - INC BC - CALL HILOX - JR SF21E - -;---------------VERIFY ONE BLOCK OF MEMORY WITH ANOTHER - -VERIFY: - CALL EXPR3 -VERIO: - LD A,(BC) - CP (HL) - JR Z,SF78E - PUSH BC - CALL CERR - POP BC -SF78E: - INC BC - CALL HILOX - JR VERIO - RET -; -CERR: - LD B,A - CALL ZHLSP - LD A,(HL) - CALL ZLBYTE - CALL BLANK - LD A,B - CALL ZLBYTE - JP ZCRLF - -ECHO: - CALL CI ;Routine to check keyboard etc. - CP 'C'-40H ;Loop until ^C - RET Z - CP 'Z'-40H - RET Z - LD C,A - CALL CO - JR ECHO - - -;Display Extended memory map for 1MG RAM using IA-2 Z80 Board window registers - -XMEMMAP: - LD HL,MSG17 ;Get segment (0-F) - CALL PRINT_STRING - LD C,1 - CALL ZHEXSP ;Get 2 or 4 hex digits (count in C). - POP HL - LD A,L ;Get single byte value - AND 0FH - EXX - LD D,A ;Store in D' for 000X:YYYY display below - SLA A - SLA A - SLA A - SLA A - OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space - LD E,A ;store shifted nibble in E' - LD HL,0 ;Will store 0-FFFF for total RAM display (not actual access) - EXX - LD D,0 ;Total display line count (256 characters, 16 lines X 16 characters) - - CALL ZCRLF - LD HL,0 - LD B,1 -XMAP1: - LD A,H - AND 00111111B ;Wrap 16K window - LD H,A - LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A ;Save it back - JR NZ,XMAP2 - CP (HL) - JR Z,XPRINT -XMAP2: - LD E,'p' -XMAP3: - LD A,0FFH - CP (HL) - JR NZ,XPRINT - INC L - XOR A - CP L - JR NZ,XMAP3 - LD E,'.' -XPRINT: - LD L,0 - DEC B - JR NZ,XNLINE - LD B,16 - CALL ZCRLF - CALL SET_WINDOW - LD A,SPACE - JR XN11 -XNLINE: - LD A,SPACE - CALL OTA - LD A,E -XN11: - CALL OTA - INC H - INC D ;Are we done yet - JR NZ,XMAP1 - CALL ZCRLF - XOR A - OUT (Z80PORT+2),A ;Set RAM window back to the way it was - JP ZSTART - -SET_WINDOW: ;Setup the unique IA-II Z80 board window to address > 64k - EXX - LD C,D ;Print seg value - CALL HXO2 - LD C,':' - CALL CO - CALL HXOT4 ;Print HL' (not origional HL) - - LD A,H ;get current H being displayed (Already pointed to first 16K window) -NOTW0: - CP 40H - JR NZ,NOTW1 - LD A,E - ADD A,04H ;Window for 4,5,6,7, set to H from above - JR DOWIN - -NOTW1: - CP 80H - JR NZ,NOTW2 - LD A,E - ADD A,08H ;Window for 8,9,A,B set to H from above - JR DOWIN - -NOTW2: - CP 0C0H - JR NZ,NOTW3 ;Must be values in between - LD A,E - ADD A,0CH ;Window for 4,5,6,7, set to H from above -DOWIN: - OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space -NOTW3: LD A,H - ADD A,10H - LD H,A - EXX ;Get back normal register set - RET - - -;Place an 8086 a Far Jump at F000:FFF0H (FFFF0H) to 500H in RAM for the 8086/80286 -;If there is a ROM there nothing will change and the 8086 reset/boot will jump -;from F000:FFF0 to the start or the ROM monitor at F000:FC00H. If however -;no ROM is present the 8086 will find the RAM code below and jump to 500H in RAM -;Whatever is at that location will then run - usually CPM86. - -UP8086: - LD A,0FCH ;Point to 8086 Reset location - OUT (Z80PORT+2),A ;Re-map to 0000H to FC000H - LD HL,3FF0H - LD (HL),0EAH - INC HL - LD (HL),0H - INC HL - LD (HL),05H - INC HL - LD (HL),0H - INC HL - LD (HL),0H - INC HL - LD (HL),0F4H ;Put an 8086 HLT here just in case - -; LD (HL),0B0H ;Continously put "3" on Consol via port 01 -; INC HL ;Basic test for 8086 on reset -; LD (HL),33H -; INC HL -; LD (HL),0E6H -; INC HL -; LD (HL),01H -; INC HL -; LD (HL),0EBH -; INC HL -; LD (HL),0FAH - - XOR A - OUT (Z80PORT+2),A ;Re-map back to 0H - JP SWITCH_8086 ;Switch over control to the 8086 - -;----------------READ ASCII FROM MEMORY - -TYPE: - CALL EXLF -SF30B: - CALL LFADR - LD B,56 -SF310: - LD A,(HL) - AND 7FH - CP SPACE - JR NC,SF319 -SF317: - LD A,2EH -SF319: - CP 7CH - JR NC,SF317 - LD C,A - CALL ZCO - CALL HILOX - DJNZ SF310 - JR SF30B - - -;-------------Display all active I/O input-ports in the system -; -INPORTS: - CALL ZCRLF - LD B,0 ;Now loop through all ports (0-FF) - LD D,6 ;Display 6 ports across - LD E,0FFH ;Will contain port number -LOOPIO: - LD C,E - LD A,E - ; Special Case here! - CP SW86 ;Inputing here will switch out the Z80 to 8086/80286 - JR Z,SKIP - CP SW68K ;Also this one (68K) - JR Z,SKIP -; - IN A,(C) ;Remember [ZASMB does not work with this opcode,SLR is OK] - CP 0FFH ;No need for 0FF's - JR Z,SKIP - LD H,A ;store port data in H for below - LD A,E ;Need to print port # first - CALL LBYTE ;Print port number - LD C,'-' - CALL ZCO - LD C,'>' - CALL ZCO - LD A,H ;get back port data - CALL LBYTE ;print it - LD C,TAB - CALL ZCO - DEC D ;6 ports per line - JR NZ,SKIP - LD D,6 - CALL ZCRLF -SKIP: - DEC E ;Next Port - DJNZ LOOPIO - CALL ZCRLF - RET - - -; -;--------------S100Computers Serial I/O Board Initilization -;Note both Zilog SCC serial ports (A & B) will be set to 38,400 Baud initially. - -#IF S100IOENABLE - -INIT_S100_IO: - -#IF S100IO8255ENABLE - ;First the 8255 -; LD A,AinBout8255cfg ;A input, B output, C(bits 0-3) output, (bits 4-7)input - LD A,AoutBin8255cfg ;A Out to Hex LED, B In Dip Switch, C(bits 0-3) output, (bits 4-7)input - OUT (PortCtrl_8255),A ;Config 8255 chip, Mode 0 -#ENDIF - -#IF S100IOSCCAENABLE - ;Then the SCC - LD A,ACTL ;Program Channel A - LD C,A - - ; WARNING, 0x0e (14) is not the complete table below - ; it looks like this can be extended to init the int (same below) - LD B,0EH ;Byte count for OTIR below - - LD HL,SCCINIT - OTIR -#ENDIF - -; -#IF S100IOSCCBENABLE - LD A,BCTL ;Program Channel B - LD C,A - LD B,0EH ;Byte count for OTIR below - LD HL,SCCINIT - OTIR -#ENDIF - -#ENDIF ; S100IOENABLE - - RET -; -; ALL SSC's are set for 19,200 BAUD, can be changed below -; - -#IF S100IOSCCAENABLE | S100IOSCCBENABLE -SCCINIT: - .DB 04H ;Point to WR4 - .DB 44H ;X16 clock,1 Stop,NP -; - .DB 03H ;Point to WR3 - .DB 0C1H ;Enable reciever, Auto Enable, Recieve 8 bits -; .DB 0E1H ;Enable reciever, No Auto Enable, Recieve 8 bits (for CTS bit) -; - .DB 05H ;Point to WR5 - .DB 0EAH ;Enable, Transmit 8 bits, Set RTS,DTR, Enable -; - .DB 0BH ;Point to WR11 - .DB 56H ;Recieve/transmit clock = BRG -; - .DB 0CH ;Point to WR12 -; .DB 40H ;Low Byte 2400 Baud -; .DB 1EH ;Low Byte 4800 Baud -; .DB 0EH ;Low Byte 9600 Baud -; .DB 06H ;Low byte 19,200 Baud <<<<<<<<<<< - .DB 02H ;Low byte 38,400 Baud -; .DB 00H ;Low byte 76,800 Baud -; - .DB 0DH ;Point to WR13 - .DB 00H ;High byte for Baud -; - .DB 0EH ;Point to WR14 - .DB 01H ;Use 4.9152 MHz Clock. Note SD Systems uses a 2.4576 MHz clock, enable BRG -; - .DB 0FH ;Point to WR15 - .DB 00H ;Generate Int with CTS going high - - NOP ; ?? why?? - NOP - NOP -#ENDIF - -;---------------------------------------------------------------------------- - .ORG VERSA ;<--------- THIS LOCATION MUST NOT BE CHANGED (F800H) - ;My old CPM V1.4 systems are counting on it being here -; -; VERSAFLOPPY II DOS SYSTEM LINKAGES (USED BY SDOS & 2.2 CP/M) -; These are residule JP's for old CPM BIOS'es. Only LOADER is now functional. - -FBOOT: JP BOOT ;COLD START ENTRY -WBOOT: JP BIOS_JP_ERR ;WARM START ENTRY -CSE: JP ZCSTS ;CONSOLE STATUS -CIE: JP ZCI ;CONSOLE IN -COE: JP ZCO ;CONSOLE OUT -LIST: JP ZLO ;TO MONITOR FOR PRINTER -PUNCH: JP ZPOO ;TO MONITOR FOR PUNCH -READR: JP ZRI ;TO MONITOR FOR READER -HME: JP BIOS_JP_ERR ;HOME , MOVE TO TRACK 0 -SDSKE: JP BIOS_JP_ERR ;SELDSK -S_TRKE: JP BIOS_JP_ERR ;SET_TRK -SSECE: JP BIOS_JP_ERR ;SETSEC -SDMAE: JP BIOS_JP_ERR ;SETDMA -RDE: JP BIOS_JP_ERR ;READF -WRE: JP BIOS_JP_ERR ;WRITEF -LISTS: JP LSTAT ;LIST STATUS -SECTR: JP BIOS_JP_ERR ;SECTRAN FOR 2.2 SECTOR TRANSLATION TABLE - -DTYPE: JP BIOS_JP_ERR ;UNITSL SET UP @UNIT BYTE (DISK DENSITY) -SVE: JP BIOS_JP_ERR ;SAVER SAVE N RECORDS -LDE: JP LOADER ;LOADER LOAD N SECTORS FROM TRACK 0 (& TRACK 1) - -BIOS_JP_ERR: - LD HL,BIOS_ERR ;"BIOS JMP longer implemented in ROM @ F800H." - JP ABORT_ERR_MSG - - - - -;BOOT LOADS A SECTOR TO 80H AND THEN JUMPS TO 80H -;NOTE. Two FDC Boards are supported here:- -; -; VFDC_BOOT Boots CPM from the Versafloppy-II disk controller board -; ZFDC_BOOT Boots CPM from the ZFDC controller board - -VBOOT: - XOR A ;0 = Flag as Boot from Versafloppy II FDC - JR BOOT_COLD - -ZBOOT: - XOR A - DEC A ;0FFH = Flag as Boot from ZFDC FDC - -BOOT_COLD: - LD (_FDCTYPE),A ;0 for VF, 0FFH for ZFDC - -BOOT: - -#IF S100IO8255ENABLE - LD A,11111111B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC - OUT (DIAG_LEDS),A -#ENDIF - -#IF S100IOVSENABLE - LD HL,SPEAKCPM_MSG ;Announce on speaker - CALL SPEAK_ -#ENDIF - - XOR A - LD (CDISK1),A ;MAKE CURRENT DISK A: - LD (CIOBYTE),A ;CLEANUP IOBYTE - LD (_UNIT),A ;8LOAD.Z80 (The first sector loader module) will count on this being 0H - ;for the Versafloppy-II boots - LD (ZERO_L),A ;These need to be zero's here for the CPM Loader/Versafloppy-II of my old - LD (ZERO_H),A ;NON-BANKED CPM3 or CPM2.2 disks. Need to later find out why! - LD HL,128 ;Assume 128 byte sectors for 8" disk - LD (_SEC_SIZE),HL - -BOOTW1: LD SP,_SSTACK - LD A,(_FDCTYPE) ;Are we using a Versafloppy II or ZFDC FDC board - OR A - JP NZ,ZFDC_BOOT ;<<<<<<<<< Go to ZFDC Board BOOT >>>>>>>>>>>>> - -VFDC_BOOT: -#IF S100VFIIENABLE - LD HL,BOOT_MSG0 ;<<<<<<<<< BOOT FROM VERSAFLOPPY-II >>>>>>>>>>>> - CALL PRINT_STRING ;"Loading CPM from VF FDC" - LD HL,VF_MSG - CALL PRINT_STRING - - LD A,0D0H ;FORCE CHIP INTERUPT - OUT (CMD),A - - LD A,STDSDT ;SETUP FOR SD - LD (_COUNT),A ;STORE AS 26 SECTORS/TRACK - LD A,0FEH - OUT (SELECT),A ;Select Drive A: (Always) - - XOR A - LD (_TRK),A - INC A - LD (_SCTR),A - - CALL READY_CHK ;Critical to make sure chip is ready first! - LD A,RSCMD ;RESTORE COMMAND (Note 3 Ms seek) - OUT (CMD),A - CALL READY_CHK ;Critical to make sure chip is ready first! - - LD HL,COLD - LD (_TADDR),HL - - CALL VF_READ_SECTOR ;Read the Boot Sector -BOOT_SEC_READ: - JP NZ,ERR_LD -BOOT_SEC_CHECK: - LD HL,COLD - LD A,(HL) - CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H - JP Z,COLD ;AS THE FIRST INSTRUCTION. IF OK JP 80H - JP ERR_LD1 ;Boot Sector Data incorrect - - -VF_READ_SECTOR: ;READ SECTOR COMMAND - LD B,3 ;Will Try 3 times -READ1: PUSH BC - CALL DRINIT ;Setup sector paramaters - LD A,E - CP 80H ;128 or 512 byte sectors ? - LD B,128 - DI - LD A,RDCMD - OUT (CMD),A ;Note wait states are now switched on - - JR M2 -M2: - JR MM2 -MM2: - JR Z,RD_128 - LD B,0 ;256 X 2 - INIR ;[C]-> [HL++],[B--] -RD_128: - INIR - - EI - CALL WAITF ;Wait states are now off - IN A,(STATUS) - AND SRMASK ;Check sector was read OK - POP BC - RET Z - DEC B - JR NZ,READ1 - XOR A - DEC A - RET ;Return NZ if failure after 3 reads - - -DRINIT: - CALL SEEK ;DRIVE INITIALIZATION - LD HL,(_TADDR) ;SETUP DMA ADDRESS AND BYTE COUNT - LD A,(_SCTR) - OUT (SECTOR),A - - LD DE,(_SEC_SIZE) ;This will be 128 or 512 sectors - LD C,DATA ;8067H in BC - -SWEB: - IN A,(SELECT) ;ENABLE WAIT STATES - AND 7FH - OUT (SELECT),A - RET - - -; SEEK TRACK -SEEK: LD A,(_TRK) - LD C,A - IN A,(TRACK) - CP C - RET Z ;IF SAME TRACK NO NEED TO SEEK - - LD A,(_TRK) - OUT (DATA),A - CALL READY_CHK ;Critical to make sure chip is ready first! - LD A,FSKCMD ;Send Seeek Command to WD1791 - OUT (CMD),A - CALL DELAY_15 ;Delay ~15ms - CALL READY_CHK - IN A,(TRACK) - LD C,A - LD A,(_TRK) - CP C - RET Z - LD HL,SEEK_ERROR_MSG - JP ABORT_ERR_MSG - - -READY_CHK: - LD BC,0 -READY_CHK1: - IN A,(STATUS) - AND 1 - RET Z - DEC BC - LD A,C - OR B - JP NZ,READY_CHK1 ;Wait until 1791/5 is ready - JP WAIT3 - -WAITF: LD E,0 - PUSH BC - LD C,2 -WAIT2: IN A,(STATUS) - AND 1 - JR Z,DWAIT - DJNZ WAIT2 - DEC E - JR NZ,WAIT2 - DEC C - JR NZ,WAIT2 - POP BC -WAIT3: IN A,(SELECT) ;IF BY THIS TIME NOT READY FORCE - OR 80H ;A HARDWARE RESET - OUT (RSET),A - LD HL,VF_HUNG - JP ABORT_ERR_MSG - - -; DISABLE WAIT STATES -DWAIT: POP BC ;TO BALANCE THE ABOVE PUSH IN WAIT -DDWAIT: IN A,(SELECT) - OR 80H - OUT (SELECT),A - RET - -#ENDIF - -DELAY_15: ;DELAY ~15 MS - LD A,40 -DELAY1: LD B,0 -M0: DJNZ M0 - DEC A - JR NZ,DELAY1 - RET - -DELAY_150: ;DELAY ~150 MS - LD C,10 -DELAY320A: - CALL DELAY_15 - DEC C - JP NZ,DELAY320A - RET - - - -LOADER: LD A,(_FDCTYPE) ;Are we using a Versafloppy II or ZFDC FDC board - OR A - JP NZ,ZFDC_LOADER ;Go to ZFDC Board Loader - - - ; LOAD A NUMBER OF SECTORS -VF_LOADER: -#IF S100VFIIENABLE - CALL VF_READ_SECTOR - JP NZ,ERR_LD - LD C,'.' ;Show progress - CALL CO - CALL INCP - JR NZ,VF_LOADER -#ENDIF - RET - -; INC SECTOR AND TRACK -INCP: - LD HL,(_TADDR) - LD DE,(_SEC_SIZE) ;128 or 512 byte sectors -INCP2: - ADD HL,DE - LD (_TADDR),HL - LD HL,_NREC - DEC (HL) - RET Z ;Return when we have done all sectors (~51) - LD HL,_SCTR - INC (HL) - LD A,(_COUNT) ;IS ONE TRACK DONE YET (Sec/track+1) - INC A - CP (HL) - RET NZ ;IF FULL Z, THEN GO TO NEXT TRACK - LD (HL),1 ;SET SECTOR COUNT BACK TO 1 - INC HL ;ASSUMES @TRK=SECTOR+1 IE 44H - INC (HL) - OR A ;MAKE SURE TO RETURN NZ - RET - - -ERR_NR: - LD HL,DRIVE_NR_ERR ;"DRIVE NOT READY - JP ABORT_ERR_MSG -ERR_LD: - LD HL,BOOT_LD_ERR ;"ERROR READING BOOT/LOADER SECTORS" - JP ABORT_ERR_MSG -ERR_LD1: - LD HL,BOOT_LD1_ERR ;"DATA ERROR IN BOOT SECTOR" - -ABORT_ERR_MSG: - CALL PRINT_STRING - JP ZAPPLE ;BACK TO START OF MONITOR. - - -;---------------------- ZFDC FDC BOOT & LOADER ---------------------------------- - -ZFDC_BOOT: ;Cold Boot with ZFDC FDC Board -#IF S100ZFDCENABLE - LD HL,BOOT_MSG0 ;<<<<<<<<< BOOT FROM ZFDC BOARD >>>>>>>>>>>>>> - CALL PRINT_STRING ;"Loading CPM from ZFDC FDC" - LD HL,ZFDC_MSG - CALL PRINT_STRING - - OUT (RESET_ZFDC_PORT),A ;Do a hardware reset. Does not matter what is in [A] - - LD A,STATUS_DELAY ;~0.5 second at 10 MHz - LD BC,0 ;Delay to allow board to setup hardware -WAIT_D: - DEC B - JR NZ,WAIT_D ;Delay for ~0.5 seconds - DEC B ;Reset B to 0FFH - DEC C - JR NZ,WAIT_D - DEC A - JR NZ,WAIT_D - - IN A,(S100_DATA_B) ;Check the board is there - CP CMD_HANDSHAKE ;Make sure we get HANDSHAKE byte back - JP NZ,ERR_NR ;If error, just abort - - LD A,CMD_HANDSHAKE ;Send another byte just to be sure. - OUT (S100_DATA_B),A ;This clears up ints on ZFDC board - CALL WAIT_FOR_ACK ;Wait to make sure all is well. - OR A - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SET_FORMAT ;Send Set Disk Format to 8" SSSD DISK - CALL S100OUT - LD C,0 ;Floppy Drive 0, (ZFDC Board expects a 0H, 1H, 2H or 3H) - CALL S100OUT - LD C,STD8IBM ;ZFDC Board expects a Disk Format Table Number (0,1,2...13H) - CALL S100OUT - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SET_DRIVE ;Send a "Set Drive CMD" to ZFDC board - CALL S100OUT - LD C,0 ;Floppy Drive #, (ZFDC Board expects a 0H, 1H, 2H or 3H) - CALL S100OUT - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - ;Drive selected and ready to read sectors. Note this code - ;is written to eb compatible with the boot loader for the - ;Versafloppy-II disk controller as well. - - LD A,STDSDT ;SETUP FOR SD - LD (_COUNT),A ;STORE AS 26 SECTORS/TRACK - - XOR A ;Setup Boot Sector read track - LD (_TRK),A - INC A - LD (_SCTR),A - LD (_NREC),A ;read only 1 sector initially - - LD HL,COLD - LD (_TADDR),HL - - CALL ZFDC_MULTI_READ_SECTOR ;Actully we will only read one sector here - JP BOOT_SEC_READ ;JMP to same section as for Versafloppy boot - - -ZFDC_MULTI_READ_SECTOR: - LD C,CMD_SET_TRACK ;Set Track - CALL S100OUT - LD A,(_TRK) - LD C,A - CALL S100OUT ;Send Selected track HEX number - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SET_SECTOR ;Set Sector # to side A (or for DS disks also side B) - CALL S100OUT - LD A,(_SCTR) - LD C,A - CALL S100OUT ;Send Selected sector HEX number - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SEEK_TRACK ;Later can let board do this - CALL S100OUT - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_RD_MULTI_SECTOR ;Routine assumes r.EQUired Drive Table,Drive,Side,Track, and sector are already sent to board - CALL S100OUT ;(Note [HL]-> Sector DMA address) - LD A,(_NREC) ;How many sectors - LD C,A - CALL S100OUT - CALL WAIT_FOR_ACK ;Wait for NO_ERRORS_FLAG to come back - JP NZ,ERR_NR ;If error, just abort - - LD HL,(_TADDR) ;Set DMA address - -MULTI_RD_SEC: - LD DE,(_SEC_SIZE) ;For CPM this will be 128 Byte sector(s) -RD_SEC: - CALL S100IN ;Note potential to lockup here & below (but unlightly) - LD (HL),A - INC HL - DEC DE - LD A,E - OR D - JR NZ,RD_SEC - - LD A,(_NREC) ;How many sectors of data worth - DEC A - LD (_NREC),A - JR NZ,MULTI_RD_SEC ;Are there more - - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - RET - - -S100OUT: - IN A,(S100_STATUS_B) ;Send data to ZFDC output (arrive with character to be sent in C) - BIT DIRECTION_BIT,A ;Is ZFDC in output mode, if not wait - JR NZ,S100OUT - BIT DATA_OUT_RDY,A ;Has previous (if any) character been read. - JR Z,S100OUT ;Z if not yet ready - LD A,C - OUT (S100_DATA_B),A - RET - -S100STAT: - IN A,(S100_STATUS_B) ;Check if ZFDC has any data for S-100 system - BIT DATA_IN_RDY,A ;Anything there ? - RET Z ;Return 0 if nothing - XOR A - DEC A ;Return NZ, & 0FFH in A if something there - RET - -S100IN: - IN A,(S100_STATUS_B) ;Check if ZFDC has any data for S-100 system - BIT DIRECTION_BIT,A ;Is ZFDC in input mode, if not wait - JR Z,S100IN ;If low then ZFDC board is still in input mode, wait - BIT DATA_IN_RDY,A - JR Z,S100IN - IN A,(S100_DATA_A) ;return with character in A - RET - -WAIT_FOR_ACK: ;Delay to wait for ZFDC to return data. There is a timeout of about 2 sec. - PUSH BC ;This can be increased if you are displaying debugging info on the ZFDC - PUSH DE ;HEX LED display. - LD BC,0 - LD E,STATUS_DELAY ;Timeout, (about 2 seconds) -WAIT_1: - IN A,(S100_STATUS_B) ;Check if ZFDC has any data for S-100 system - BIT DIRECTION_BIT,A ;Is ZFDC in input mode - JR Z,WAIT_2 ;if low then ZFDC is still in input mode - CALL S100STAT ;Wait until ZFDC Board sends something - JR Z,WAIT_2 - CALL S100IN ;Get returned Error # (Note this releases the SEND_DATA routine on the ZFDC board) - CP NO_ERRORS_FLAG ;Was SEND_OK/NO_ERRORS_FLAG sent back from ZFDC Board - POP DE ;Balance up stack - POP BC - RET ;Return NZ if problem, Z if no problem -WAIT_2: DEC B - JR NZ,WAIT_1 ;Try for ~2 seconds - DEC B ;Reset B to 0FFH - DEC C - JR NZ,WAIT_1 - DEC B ;Reset B to 0FFH - DEC C - DEC E - JR NZ,WAIT_1 - XOR A - DEC A - POP DE ;Balance up stack - POP BC - RET ;Return NZ flag set if timeout AND 0FFH in [A] - -#ENDIF - -; LOAD A NUMBER OF SECTORS ;Note this loader utilizes the fast multi-sec read in V2.8 of later - -ZFDC_LOADER: ;CPM Loader with ZFDC FDC Board -#IF S100ZFDCENABLE - CALL ZFDC_MULTI_READ_SECTOR ;Note the Boot sector has by now setup the sector count etc. in low RAM -#ENDIF - RET - - -;---------------------------------------------------------------------------- -; Module to boot MSDOS from 5" DDDS disk (Note this module has not been updated yet) -; -MSDOS: - -#IF S100IOVSENABLE - LD HL,SPEAKDOS_MSG ;Announce on speaker - CALL SPEAK_ -#ENDIF - - CALL CRLF - - JP ERR_NR ;Not done Yet - -; LD A,4 ;MSDOS.SYS STARTS AT SECTOR 4 SIDE B -; LD (_SCTR),A -; LD A,0 -; LD (_TRK),A ;START ON TRACK 0 -; LD A,1 -; LD (_SIDE),A ;START ON SIDE B -; LD A,FFILE_SIZE ;SIZE OF DOS IN 512 BYTE SECTORS -; LD (_NREC),A -; -; LD A,01110100B ;0,DD,5",SIDE 1, 0100=D: -; CALL MDSEL -; JP NZ,ERR_NR ;ROUTINE TO SAY DRIVE NOT READY -; LD A,RSVCMD ;SEND RESTORE COMMAND -; CALL DCMDI -; JR Z,DGETID -;DOS1: -; LD HL,RESTORE_ERR ;RESTORE FAILED -; JP ABORT_ERR_MSG -; -;DGETID: -; CALL DIDRD -; JR NZ,DOS1 -; -;GETSEC: -; LD HL,STARTDOS -;DGET1: -; LD C,'.' ;to indicate on CRT sectors read -; CALL CO -; LD A,(_SCTR) -; OUT (SECTOR),A -; LD B,0 ;256 BYTES -; LD C,DATA ;DATA PORT -; DI ;just in case -; CALL SWEB ;SET WAIT ENABLE BIT -; LD A,RDCMD -; OUT (CMD),A -; INIR -; INIR ;512 BYTES TOTAL -; LD B,0 -;DWAITF: -; IN A,(STATUS) -; AND 1 -; DJNZ DWAITF -; -; CALL DDWAIT -; -; IN A,(STATUS) ;CHECK STATUS -; AND 0FEH -; JP NZ,ERR_LD ;ROUTINE TO SAY SECTOR READ ERROR -; -; LD A,(_NREC) -; DEC A -; LD (_NREC),A -; JP Z,STARTDOS -; -; LD A,(_SCTR) -; INC A -; LD (_SCTR),A -; CP 0AH ;end of track yet? -; JR NZ,DGET1 -; -; LD A,(_SIDE) -; CP 1 ;if on track 1 go to side 1 else side 0 -; JR Z,TRK1A -; LD A,1 ;FLAG CURRENT SIDE IS NOW B -; LD (_SIDE),A -; LD A,01110100B ;SWITCH TO SIDE B -; JR TRK1B -;TRK1A: -; LD A,(_TRK) -; INC A -; LD (_TRK),A -; LD A,0 -; LD (_SIDE),A ;FLAG CURRENT SIDE IS NOW A -; LD A,01100100B ;SWITCH TO SIDE A -;TRK1B: -; CALL MDSEL -; JP NZ,ERR_NR ;ROUTINE TO SAY DRIVE NOT READY -; -;DSEC: -; LD A,1 -; LD (_SCTR),A -; -; LD A,(_TRK) -; OUT (DATA),A -; LD A,MSKCMD ;SEEK TO TRACK WITH VERIFY -; CALL DCMDI -; JP Z,DDRS3 -;DSEC1: -; LD HL,MSGH4 ;SEEK ERROR MESSAGE -; JP ABORT_ERR_MSG -; -;xxxz: HALT - -;DDRS3: -; PUSH HL -; CALL DIDRD -; POP HL -; JR NZ,DSEC1 -; JP DGET1 -; -;DIDRD: -; LD HL,_IDSV -; LD BC,600H+DATA -; CALL SWEB -; LD A,RDACMD ;SEND READ ID COMMAND -; OUT (CMD),A -; INIR -;DWAITS: -; IN A,(STATUS) -; AND 1 -; JR NZ,DWAITS -; CALL DDWAIT ;DISABEL WAIT STATE GENERATOR -; LD A,(_IDSV) ;++++++++++++++ -; LD B,A -; LD A,(_TRK) -; CP B ;RETURN WITH Z IF AT RIGHT TRACK -; RET - -;MDSEL: -; CPL -; OUT (SELECT),A -;DRDYCK: -; IN A,(STATUS) -; AND 80H -; JP NZ,DRDYCK -; RET -; -;SEND TYPE 1 COMMANDS (RESTORE,SEEK,STEP) -; -;DCMDI: -; LD (_CMDSV),A ;TEMPORLY STORE COMMAND -; LD A,80H -; LD (_ERMASK),A -;DCMDI1: -; IN A,(STATUS) ;IS 1793 READY -; AND 01H -; JP NZ,DCMDI1 -; LD A,(_CMDSV) -; OUT (CMD),A -; CALL DELAY_15 ;DELAY R.EQUIRED FOR A VALID STATUS -;DEEND: -; IN A,(STATUS) ;END OF DISK COMMANDS ROUTINE -; AND 01H -; JP NZ,DEEND ;IS 1793 STILL BUSY -; IN A,(STATUS) -; LD D,A -; LD A,(_ERMASK) -; AND D ;CHECK FOR ERRORS -; RET - -;------THIS IS THE MAIN ROUTINE TO GET THE TIME DATA FROM THE CMOS-RTC Chip on the MSDOS Support Board - -SHOW_TIME: -#IF S100MSDENABLE - LD HL,TIME_MSG - CALL PRINT_STRING ;Print message up to '$' - CALL PRINT_TIME -#ENDIF - RET - - -SHOW_DATE: -#IF S100MSDENABLE - LD HL,DATE_MSG - CALL PRINT_STRING ;Print message up to '$' - CALL PRINT_DATE -#ENDIF - RET - -PRINT_TIME: -#IF S100MSDENABLE - CALL UPD_IN_PR ;CHECK FOR UPDATE IN PROCESS - JP NC,RTC_2A ;GO AROUND IF OK - JP RTC_ERROR ;IF ERROR - -RTC_2A: LD E,-2 ;-2 goes to 0 for PORT_INC_2 - CALL PORT_INC_2 ;SET ADDRESS OF SECONDS - IN A,(CMOS_PORT+1) ;Get BCD value returned - LD D,A ;SAVE IN D - CALL PORT_INC_2 ;SET ADDRESS OF MINUTES - IN A,(CMOS_PORT+1) ;Get BCD value returned - LD C,A ;SAVE IN C - CALL PORT_INC_2 ;SET ADDRESS OF HOURS - IN A,(CMOS_PORT+1) ;Get BCD value returned - LD B,A ;SAVE - LD E,0 ;SET E TO ZERO - CALL DisplayTime - XOR A ;Clear Carry - RET ;BACK TO MONITOR - -RTC_ERROR: ;Indicate RTC Board is not present or Error - SCF ;SET CARRY FOR ERROR -#ENDIF - RET - -;Display time -; Arrive with B = HOURS IN BCD -; C = Minutes in BCD -; D = Seconds in BCD -DisplayTime: -#IF S100MSDENABLE - PUSH DE - PUSH BC - LD A,B - CALL PRINT_BCD ;Hours. Convert BCD to ASCII - LD C,':' - CALL ZCO - POP BC - LD A,C - CALL PRINT_BCD ;Minutes. Convert BCD to ASCII - LD C,':' - CALL ZCO - POP DE - LD A,D - CALL PRINT_BCD ;Seconds. Convert BCD to ASCII -#ENDIF - RET - -PRINT_DATE: -#IF S100MSDENABLE - CALL UPD_IN_PR - JP NC,RTC_4A - JP RTC_ERROR ;IF ERROR - -RTC_4A: - LD E,6 - CALL PORT_INC ;POINT TO DAY - IN A,(CMOS_PORT+1) - LD B,A ;SAVE IN A - CALL PORT_INC ;POINT TO MONTH - IN A,(CMOS_PORT+1) - LD D,A ;SAVE IN D - CALL PORT_INC ;POINT TO YEAR - IN A,(CMOS_PORT+1) - LD C,A ;SAVE IN C - LD E,31H ;POINT TO CENTURY BYTE SAVE AREA - CALL PORT_INC ; - IN A,(CMOS_PORT+1) ;GET VALUE - LD E,B ;GET DAY BACK - LD B,A - CALL DisplayDate - XOR A ;Clear Carry -#ENDIF - RET ;FINISHED - - -;Display date -; Return B = CENTURY IN BCD -; C = Year in BCD -; D = Month in BCD -; E = Day in BCD -DisplayDate: -#IF S100MSDENABLE - PUSH DE - PUSH DE - PUSH BC - PUSH BC - - POP BC - LD A,B - CALL PRINT_BCD ;Century (19/20). Convert BCD to ASCII - POP BC - LD A,C - CALL PRINT_BCD ;Year. Convert BCD to ASCII - LD C,'/' - CALL ZCO - POP DE - LD A,D - CALL PRINT_BCD ;Month. Convert BCD to ASCII - LD C,'/' - CALL ZCO - POP DE - LD A,E - CALL PRINT_BCD ;Day. Convert BCD to ASCII -#ENDIF - RET - - -UPD_IN_PR: ;Check we are ready to read clock -#IF S100MSDENABLE - PUSH BC - LD BC,600 ;SET LOOP COUNT -UPDATE: - LD A,0AH ;ADDRESS OF [A] REGISTER - OUT (CMOS_PORT),A - NOP - NOP - NOP - IN A,(CMOS_PORT+1) ;READ IN REGISTER [A] - AND 80H ;IF 8XH--> UIP BIT IS ON (CANNOT READ TIME) - JP Z,UPD_IN_PREND ;Are we ready/done - DEC BC - LD A,C - OR B - JP NZ,UPDATE ;Try again - XOR A ; - SCF ;SET CARRY FOR ERROR - POP BC - RET -UPD_IN_PREND: - XOR A ;Clear Carry - POP BC -#ENDIF - RET ;RETURN - -PORT_INC: -#IF S100MSDENABLE - LD A,E - INC A ;INCREMENT ADDRESS - LD E,A - OUT (CMOS_PORT),A -#ENDIF - RET - - -PORT_INC_2: -#IF S100MSDENABLE - LD A,E - ADD A,2 ;INCREMENT ADDRESS - LD E,A - OUT (CMOS_PORT),A -#ENDIF - RET - -PRINT_BCD: ;Print BCD in [A] - PUSH AF - PUSH AF - RRA - RRA - RRA - RRA - AND 0FH - ADD A,30H - LD C,A ;Write high byte mins to CRT - CALL ZCO - POP AF - AND 0FH - ADD A,30H - LD C,A - CALL ZCO - POP AF - RET - -;>>>>>>>>>>>>>>>>>>>>>>>>> SPEECH OUTPUT ROUTINES <<<<<<<<<<<<<<<<<< -; -;SPEAK OUTPUT (WILL BE USED TO COMMUNICATE WITH TALKER) -; Note the S100Computers I/O board V-Stamp speech chip will use the initial baud rate -; of of the SCC to communicate with it. This is determines after each reset/slave clear. -SPEAKER_CTS: ;Cannot get this to work. SCC does not change bit 5 of RR1 - ;when E1 sent to WR3 (No Auto ENABLE. See SCCINIT: -#IF S100IOVSENABLE - - IN A,(BCTL) ;A0H - BIT 5,A - LD A,0FFH - RET NZ ;Ret NZ if CTS is High - XOR A -#ENDIF - RET ;Ret Z if CTS is Low - -SPEAKOUT: -#IF S100IOVSENABLE - XOR A ;Will try 256 times, then timeout -SPXXX: - PUSH AF - IN A,(BCTL) ;(A0), Is SCC TX Buffer empty - AND 04H - JR NZ,SENDS ;NZ if ready to recieve character - POP AF - DEC A - JR NZ,SPXXX - RET -SENDS: - POP AF - LD A,C - OUT (BDTA),A ;(A2), Send it -#ENDIF - RET -; -;SPEAKTOMM THIS IS A ROUTINE TO SEND A STRING TO TALKER [HL] AT STRING -SPEAK_: - LD A,(HL) - CP '$' - JR Z,SPEAK1 - LD C,A - CALL SPEAKOUT - INC HL - JR SPEAK_ -SPEAK1: - LD C,0DH ;MUST END WITH A CR - JP SPEAKOUT -;;;;;;#ENDIF - - -;>>>>>>>>>>>>>>>>>> MODEM/SERIAL I/O <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -; Note the S100Computers I/O board will have the SSC set initially to 19,200 Baud -; THIS USES CHANNELL 'A' -SERIAL_OUT: -#IF S100IOSCCAENABLE - XOR A ;Will try 256 times, then timeout -MODXXX: PUSH AF - IN A,(ACTL) ;MODEM/SERIAL OUT - AND 04H ;Are we ready for a character - JR NZ,SENDM ;NZ if ready to recieve character - POP AF - DEC A - JR NZ,MODXXX - RET -SENDM: - POP AF - LD A,C - OUT (ADTA),A ;Send it -#ENDIF - RET - -SERIAL_IN: -#IF S100IOSCCAENABLE - XOR A ;Will try 256 times, then timeout -SERIAL_INX: - PUSH AF - CALL SERIAL_STAT ;MODEM/SERIAL IN - JR NZ,GETMOD - POP AF - DEC A - JR NZ,SERIAL_INX - RET -GETMOD: - POP AF - IN A,(ADTA) -#ELSE - LD A,'?' -#ENDIF - RET - -SERIAL_STAT: -#IF S100IOSCCAENABLE - IN A,(ACTL) - AND 01H - RET Z ;Ret Z if nothing -#ELSE - LD A,0FFH -; XOR A ; <--- This is not correct, returns a Z condtion, need a NZ -#ENDIF - RET ;Ret FF/NZ if something - - - -;PRINT MAIN MONITOR MENU ON CRT - -KCMD: - LD HL,MSG0 ;Signon Msg again (K Command) - CALL PRINT_STRING - -#IF S100IOVSENABLE - LD HL,SMSG ;SPEECH MESSAGE - CALL SPEAK_ -#ENDIF - - LD HL,MENUMSG ;Then Menu Message - JP PRINT_STRING - -; -;THIS ROUTINE JUMPS OVER TO THE 8088, 8086 or 80286. Port SW86 raises S-100 PIN #55 -;THIS WILL CAUSE THE 8086/80286 BOARD TO BECOME ACTIVE AND TAKE OVER THE BUS. THE -;Z80 WILL BE IN A PERMANANT HOLD STATE UNTIL PIN #55 IS AGAIN LOWERED. - -SWITCH_8086: - LD HL,MSG14 - CALL PRINT_STRING - IN A,(SW86) ;THIS SWITCHES CPU'S with no block Move - NOP ;Z80 WILL BE HELD HERE - NOP - NOP - NOP - JP BEGIN ;WILL DROP BACK TO REBOOT MONITOR - - -;THIS ROUTINE JUMPS OVER TO THE 68000 CPU Board. Port SW68K raises S-100 PIN #56 -;THIS WILL CAUSE THE 68000 CPU BOARD TO BECOME ACTIVE AND TAKE OVER THE BUS. THE -;Z80 WILL BE IN A PERMANANT HOLD STATE UNTIL PIN #56 IS AGAIN LOWERED. - -SWITCH_68K: - LD HL,MSG68K - CALL PRINT_STRING - IN A,(SW68K) ;THIS SWITCHES CPU'S - NOP ;Z80 WILL BE HELD HERE - NOP - NOP - NOP - JP BEGIN ;WILL DROP BACK TO REBOOT MONITOR - -; -; -; -;THESE ARE ROUTINES NOT YET IMPLEMENTED -; -RI: ;READER -POO: ;PUNCH -PRDY: ;PUNCH STATUS (Sent to Serial port right now) -RSTAT: ;READER STATUS (Input from Serial port right now) -ONLIST: ;ON LIST -OFLIST: RET ;OFF LIST -TRAP: HALT -; -; -DRIVE_NR_ERR: .DB BELL,CR,LF - .TEXT "Drive not Ready." - .DB CR,LF,LF - .TEXT "$" -RESTORE_ERR: .DB BELL,CR,LF - .TEXT "Restore Failed." - .DB CR,LF,LF - .TEXT "$" -BOOT_LD_ERR: .DB BELL,CR,LF - .TEXT "Read Error." - .DB CR,LF,LF - .TEXT "$" -SEEK_ERROR_MSG: .DB BELL,CR,LF - .TEXT "Seek Error." - .DB CR,LF,LF - .TEXT "$" - -BOOT_LD1_ERR: .DB BELL,CR,LF - .TEXT "BOOT error." - .DB CR,LF,LF - .TEXT "$" -VF_HUNG: .TEXT "VF Controller Hung" - .DB CR,LF,LF - .TEXT "$" -BIOS_ERR: .TEXT "BIOS JMP not in ROM" - .DB CR,LF,LF - .TEXT "$" -BOOT_MSG0: .DB CR,LF - .TEXT "Loading CPM from $" - -#IF S100VFIIENABLE -VF_MSG: .TEXT "VF FDC." - .DB CR,LF - .TEXT "$" -#ENDIF - -#IF S100ZFDCENABLE -ZFDC_MSG: .TEXT "ZFDC FDC." - .DB CR,LF - .TEXT "$" -#ENDIF - -MENUMSG: .DB CR,LF - .TEXT "A=Memmap B=68000 C=CP/M(Z) D=Disp E=Echo F=Fill G=Goto" - .DB CR,LF - .TEXT "H=Date I=Time J=Test K=Menu L=CPM(V) M=Move N=SeqMap" - .DB CR,LF - .TEXT "O=8086 P=CPM(IDE) Q=Port R=Ports S=Subs T=Type" - .DB CR,LF - .TEXT "V=Verify W=Port EDH X=DOS(H) Y=RomWBW Z=Top @=Flush Printer" - .DB CR,LF,LF - .TEXT "$" -; -MSG14: .DB BELL,CR,LF - .TEXT "8086/80286 Active" - .DB CR,LF,LF - .TEXT "$" - -MSG68K: .DB BELL,CR,LF - .TEXT "68K Active" - .DB CR,LF,LF - .TEXT "$" - -MSG17: .DB CR,LF - .TEXT "Segment (0-F):$" - -#IF S100MSDENABLE -TIME_MSG: .DB CR,LF - .TEXT "Time:- $" -DATE_MSG: .DB CR,LF - .TEXT "Date:- $" -#ENDIF - -GAP_MSG: .TEXT " $" - -#IF S100DIDEENABLE -IDE_RW_ERROR: .DB CR,LF - .TEXT "IDE Drive R/W Error" - .DB CR,LF - .TEXT "$" -#ENDIF - -SP_MSG .DB CR,LF - .TEXT "SP=$" - - -SPEAKCPM_MSG: .TEXT "LOADING CPM $" - -#IF S1008086ENABLE -SPEAKDOS_MSG: .TEXT "LOADING DOS $" -#ENDIF - -CR_SMSG: .DB CR,CR,CR,CR - .TEXT "$" -; - NOP - HALT - - - .END -;END diff --git a/branches/s100/Source/master-dwg.asm b/branches/s100/Source/master-dwg.asm deleted file mode 100755 index 248b31c3..00000000 --- a/branches/s100/Source/master-dwg.asm +++ /dev/null @@ -1,2777 +0,0 @@ - -; MASTER.Z80 This is the main monitor program for my system. -; It resided in 1 2732 PROM at F000H (or top half of 28C64) -; Assemble and SLR's Z80ASM Assembler (Can also use Cromemco's Assembler) -; Use:- Z80ASM MASTER FH -; -; Note the monitor is is two sections. The F000H-F7FFH is for typical display -; move memory type functions. The second portion starts at F800H and contains -; a series of CPM BIOS compatable jumps. For compatability with some of my old -; CPM V1.4 software these locations should not be changed. You can easily build -; around them. The second section (after the above BIOS jumps section) contains -; CPM boot loader code and other more specilized stuff. -; -; To assemble under windows... -; Load Altair.EXE -; do cpm3 -; I: -; Submit master -; -; Master.HEX is written back to the same windows folder as altair.exe is in. - -; Programming an EEPROM for the Z80 Board with the VP-280 Programmer -; Using a MK28C28A EEPROM or uP28C64:- -; For monitor at F000H-FFFFH -; Load Buffer Address – 1000 -; From File address F000H -; This will put the code (4K) in the top “half” of the 8K EEPROM. It can be seen/edited at 1000H - -; Recent History... - -; 26/2/09 Added ability to switch CO/CI to ACIA serial from PC. -; 5/3/09 Adjust RTS/CTS levels for Modem -; V3.5 6/3/09 Set talker messages for new V-Stamp chip. -; 12/09/09 Add SD Systems IO-8 board Serial ports. -; V3.52 16/9/09 Add SD Systems IO-8 Board clock display on signon -; v3.6 21/9/09 Add display command for greater than 64K RAM, removed -; V4.0 10/26/09 Switched in 8255 driven IDE HD Controller (Removed XComp) -; some old commands to make more room. -; V4.1 11/7/09 Added input ports scan/diagnostic -; V4.2 11/14/09 Remove Date (keep time) from Clock (Chip is messed up by CPM3 routine) -; also modified to switch from the SD System assembler to the SLR one. -; V4.21 11/17/09 Removed 8086 jump far setting code -; V4.3 11/18/09 Implement movement of 8086 Monitor code (EPROM) to correct location in RAM space -; V4.31 11/19/09 Check 8086 Monitor ROM->ROM went OK. Added W command. -; V4.32 12/7/09 Turn off any SD Systems 8024 video screen enhancements (flashing, underline etc). -; V4.33 12/25/09 Correct High/Low byte Sector read for IDE board -; V4.34 2/23/10 "O" command, 8086 Far jump to 500H (IF RAM @ FFFF0H), W command boots 8086 from reset at FFFF0H. -; V4.35 3/25/10 "O" command just puts 8086 Far JMP to 500H (IF RAM @ FFFF0H). Done also at each reset. -; V4.4 7/29/10 Removed all SD Systems IO-8. Added S-100Computers I/O board drivers. -; V4.41 7/29/10 Initilization of V-Stamp chip done. Cleaned up Serial port names etc -; V4.42 7/31/10 Switched RTC over to S-100Computers board (Ports A4,A5) -; V4.50 2/7/11 Added Floppy Boot loader for ZFDC board. Still have the Versafloppy loader but no BIOS functions -; V4.51 2/13/11 Check IDE if Boot sector is valid -; V4.52 2/15/11 Pulse CF/IDE cards twice to reset (some) cards properly -; V4.53 2/16/11 Initilize IDE board with IDE RD/WR lines inactive on power-up. -; V4.54 2/28/11 Incoporated new fast multi-sector boot for CPM floppy loading with ZFDC board -; V4.55 2/28/11 "O" command now jumps to SWITCH_8086 (activates 8086) when done -; V4.55a 3/1/11 "O" cmd will just put 33 on Consol (temporary 8086 board test) -; V4.56 3/15/11 Re-did IDE drive hardware reset pulse to one (delayed) pulse, then wait for drive ready status. -; V4.57 6/3/11 Set up an equate for IDE drive reset pulse, Fixed Z command (Last version using MM58167 RTC chip) -; V4.6 11/27/11 Switched to Dallas Semiconductor/IBM-PC CMOS-RTC chip & MSDOS Support board for time & dates -; V4.7 3/26/12 Cleaned up IOBYTE options. Added 68000 CPU Slave activate option (B menu command) - -; V4.7A 16Oct12 TRL - Fixed console serial port, forced I/O to serial port -; V4.7B 18Oct12 TRL - Added boot code framwork for RomWBW testing -; V4.7C 19Oct12 TRL - Converted to TASM syntax - - -#INCLUDE "std.asm" ; Add standard .asm files - -;FALSE .EQU 0 -;TRUE .EQU NOT FALSE - -BIGROM .EQU FALSE ; will put Monitor at 0E000h -;SERIAL .EQU TRUE ; Will use S100 Serial Board -;VERSA .EQU FALSE ; Will load Versi Floppy code -;SPEAK .EQU FALSE ; Will allow speach talker board -;RTC .EQU FALSE ; Will load RTC code - - -SCROLL .EQU 01H ;Set scrool direction UP. -BELL .EQU 07H -SPACE .EQU 20H -TAB .EQU 09H ;TAB ACROSS (8 SPACES FOR SD-BOARD) -CR .EQU 0DH -LF .EQU 0AH -FF .EQU 0CH -QUIT .EQU 11H ;Turns off any screen enhancements (flashing, underline etc). -NO_ENHANCEMENT .EQU 17H ;Turns off whatever is on -FAST .EQU 10H ;High speed scrool -ESC .EQU 1BH -DELETE .EQU 7FH -BACKS .EQU 08H -CLEAR .EQU 1AH ;TO CLEAR SCREEN -RST7 .EQU 38H ;RST 7 (LOCATION FOR TRAP) -IOBYTE1 .EQU 0EFH ;IOBYTE (SEE BELOW) -NN .EQU 0H ;[I] INITIAL VALUE -; - -STARTCPM .EQU 100H ;LOCATION WHERE CPM WILL BE PLACED FOR COLD BOOT -STARTDOS .EQU 100H ;LOCATION WHERE MSDOS WILL BE PLACED FOR COLD BOOT -FFILE_SIZE .EQU 9000h/512 ;SIZE OF 5MSDOS20.COM IN 512 BYTE SECTORS -; -; -;IOBYTE = SENSE SWITCHES AT PORT 0EFH -; -; BIT MAP OF PORT 0EFH:------- X X X X X X X X (11111111=NORMAL CONFIG) -; | | | | | | | |..For Z80 Monitor, 0=CONSOLE DATA TO PRINTER ALSO -; | | | | | | |....For 8086 Monitor, 0=Force Consol output to CGA/VGA Board -; | | | | | |......For 8086 Monitor, 0=Do not initilize extra ROMS -; | | | | |........Unused -; | | | |...........For CPM3, 0=Prevents LF's in CPM3 -; | | |.............For Z80 Monitor, 0=Consol I/O via ACIA Serial port -; | |...............For CPM3, 0=Force format of Mdisk ith CPM3 -; |.................For CPM3, 0=R/W protect Mdisk -; For 8086 Monitor, 0=Prevent doing a JMPF to 0000:0500H after 8086 reset -; -; -;-------------- SD SYSTEMS VIDIO BOARD FOR CONSOLE INPUT & OUTPUT -CONSOL_STATUS .EQU 0H -CONSOL_IN .EQU 01H -CONSOL_OUT .EQU 01H - - - -;-------------- THIS IS MY PORT TO OUTPUT DATA TO HP 4050T LASAR PRINTER (IMSAI 8PIO Board) -PRINTER_STATUS .EQU 5 ;IN, HP PARELL PORT -PRINTER_OUT .EQU 5 ;OUT -PRINTER_STROBE .EQU 4 ;OUT -;DIAG_LEDS .EQU 5 ;OUT (Will use this port initially for diagnostic LED display) -DIAG_LEDS .EQU 0A8h ;OUT (Will use this port initially for diagnostic LED display) Use hex display - - -;-------------- S100 Computers Serial I/O BOARD PORT ASSIGNMENTS (A0-AC) -BCTL .EQU 0A0H ;CHANNEL B CONTROL PORT ASSIGNMENTS OF THE ZILOG SCC CHIP ;<--- Adjust as necessary, -ACTL .EQU 0A1H ;CHANNEL A CONTROL -BDTA .EQU 0A2H ;CHANNEL B DATA -ADTA .EQU 0A3H ;CHANNEL A DATA - -PortA_8255 .EQU 0A8H ;A port of 8255 -PortB_8255 .EQU 0A9H ;B port of 8255 -PortC_8255 .EQU 0AAH ;C Port of 8255 -PortCtrl_8255 .EQU 0ABH ;8255 configuration port -AinBout8255cfg .EQU 10011000b ;Set 8255 ports:- A input, B output, -AoutBin8255cfg .EQU 10001010b ;Set 8255 ports:- A output to LED, B Input from Dip Switch - -;---------------PORT ASSIGNEMENT FOR DLP-USB Controller chip -USB_DATA .EQU 0ACH -USB_STATUS .EQU 0AAH ;Status port for USB port (Port C of 8255, bits 6,7) -USB_RXE .EQU 80H ;If Bit 7 = 0, data available to recieve by S-100 Computer -USB_TXE .EQU 40H ;If Bit 6 = 0 data CAN be written for transmission to PC - - -;-------------- S100Computers MSDOS Support Board PORT ASSIGNMENTS -CMOS_PORT .EQU 70H ;Base Port for CMOS Chip on MSDOS Support Board -MASTER_PIC_PORT .EQU 20h ;Hardware port the 8259A (two ports 20H & 21H) - -MasterICW1 .EQU 00010111B ;EDGE triggered, 4 bytes, single Master,ICW4 needed -MasterICW2 .EQU 8H ;Base address for 8259A Int Table (IBM-PC uses 8X4 = 20H) -MasterICW3 .EQU 0H ;No slave -MasterICW4 .EQU 00000011B ;No special mode, non buffer, Auto EOI, 8086. ;<<<<, - - -;--------------- PORTS FOR FOR Z80/WD2793 ZFDC Board -S100_DATA_A .EQU 10H ;IN, S100 Data port to GET data to from FDC Board -S100_DATA_B .EQU 10H ;OUT, S100 Data port to SEND data to FDC Board -S100_STATUS_A .EQU 11H ;Status port for A -S100_STATUS_B .EQU 11H ;Status port for B -RESET_ZFDC_PORT .EQU 13H ;Port to reset ZFDC Z80 CPU. - -STATUS_DELAY .EQU 5 ;Time-out for waiting for ZFDC Board handshake signal (~0.5 seconds @ 10MHz) -DIRECTION_BIT .EQU 7 ;Bits for the ZFDC flags 0 = IN, 1 = OUT -DATA_IN_RDY .EQU 0 ;Bit for data available from ZFDC board -DATA_OUT_RDY .EQU 1 ;Bit for data can be sent to ZFDC board -STD8IBM .EQU 1 ;IBM 8" SDSS Disk -NO_ERRORS_FLAG .EQU 0 ;No Errors flag for previous cmd, sent back to S-100 BIOS - - -;Commands to the ZFDC Board:- - -CMD_RESET_ZFDC .EQU 3H ;Reset the WD2793 chip and Board software -CMD_SET_FORMAT .EQU 4H ;This will select a specified drive and assign a disk format table to that drive -CMD_SET_DRIVE .EQU 5H ;This will select a specified drive (0,1,2,3) -CMD_SET_TRACK .EQU 7H ;This will set head r.EQUest to a specified track -CMD_SET_SIDE .EQU 8H ;This will set side r.EQUest to a specified side -CMD_SET_SECTOR .EQU 9H ;This will set sector r.EQUest to a specified sector -CMD_SET_HOME .EQU 0AH ;This will set head r.EQUest to Track 0 of CURRENT drive -CMD_STEP_IN .EQU 0BH ;Step head in one track of CURRENT drive -CMD_SEEK_TRACK .EQU 0EH ;Seek to track to (IY+DRIVE_TRACK) with the track verify bit set on CURRENT drive/format -CMD_READ_SECTOR .EQU 10H ;Read data from the CURRENT sector (on current track,side,drive). -CMD_HANDSHAKE .EQU 21H ;Handshake command only sent during board initilization/testing -CMD_RD_MULTI_SECTOR .EQU 29H ;Read data from multiple sectors starting at the CURRENT sector (on current track,side,drive). - - -;-------------- PORT(S) TO SWITCH MASTER/SLAVE(S) -Z80PORT .EQU 0D0H ;4 PORTS ON Z80 BOARD FOR MEMORY MANAGEMENT (& INT Controller on IA Z80 CPU Board) -Z80MMUL .EQU Z80PORT+2 ; MMU port for lower 16k block -Z80MMUH .EQU Z80PORT+3 ; MMU port for upper 16k block -SW86 .EQU 0EDH ;INPUT FROM THIS PORT SWITCHES IN THE 8088,8086, or 80286 board -SW68K .EQU 0ECH ;INPUT FROM THIS PORT SWITCHES IN THE 68000 CPU Board - - -;-------------- VERSAFLOPPY-II FLOPPY DISK CONTROLLER COMMANDS ETC. -X .EQU 50H ;BASE PORT FOR 1791 -RSET .EQU X+0 ;CONTROLLER RESET ADDRESS -SELECT .EQU X+3 ;DRIVE SELECT PORT -STATUS .EQU X+4 ;STATUS PORT -TRACK .EQU X+5 ;TRACK PORT -SECTOR .EQU X+6 ;SECTOR PORT -DATA .EQU X+7 ;DATA PORT -CMD .EQU X+4 ;COMMAND PORT - -CIOBYTE .EQU 03H -CDISK1 .EQU 04H -ZERO_L .EQU 08H ;Some of my CPM Loader's needs these to be zero! -ZERO_H .EQU 09H ;(The Non Banked version of CPM3). Need to later see why -_TADDR .EQU 40H -_UNIT .EQU 42H ;NEW @UNIT BYTE -_SCTR .EQU 43H ;SECTOR (compatible with my old CPM2.2 Versafloppy BIOS) -_TRK .EQU 44H ;TRACK -_NREC .EQU 45H ;# OF SECTORS -_ERMASK .EQU 46H ;ERROR MASK -_ERSTAT .EQU 47H ;ERROR FLAG STORE -_IDSV .EQU 48H ;6 BYTES (USED FOR TRACK ID COMMAND) -_CMDSV .EQU 4EH ;COMMAND SAVE -_SPSV .EQU 4FH ;SP SAVE -TEMP2 .EQU 51H ;2 BYTE TEMP RECORD -_SIDE .EQU 51H ;SIDE STORE FOR MSDOS DISK -_COUNT .EQU 53H ;SECTORS/TRACK for BOOT (Currently unused) -_UNITCK .EQU 55H ;OLD @UNIT BYTE -_RSEEK .EQU 56H ;NBR OF RESEEKS -_RTRY .EQU 57H ;NBR OF RTRYS -ADRIVE .EQU 58H ;STORE OF A: DRIVE DENSITY ETC TYPE -BDRIVE .EQU 59H ;STORE OF B: DRIVE TYPE -_FDCTYPE .EQU 5BH ;0FFH = ZFDC FDC Board Boot, else Versafloppy II FDC Boot, -_SEC_SIZE .EQU 5CH ;Byte count of a sector fot loader -_SSTACK .EQU 80H ;SYSTEM STACK - -COLD .EQU 80H ;COLD START ADDRESS FOR CPM FLOPPY (ONLY) BOOT LOADER - -RDACMD .EQU 0C0H ;READ ADDRESS CODE -RDCMD .EQU 088H ;READ SECTOR CODE -WRCMD .EQU 0A8H ;WRITE SECTOR CODE -WRTCMD .EQU 0F4H ;WRITE TRACK CODE -RSCMD .EQU 008H ;RESTORE COMMAND (Note 3 Ms seek) -SKNCMD .EQU 018H ;SEEK NO VERIFY -FSKCMD .EQU 01CH ;FLOPPY SEEK COMAND -RSVCMD .EQU 00CH ;RESTORE WITH VERIFY COMMAND -MSKCMD .EQU 01FH ;MINI FLOPPY SEEK COMMAND - -SRMASK .EQU 0FEH ;SECTOR READ ERROR BITS MASK - -STDSDT .EQU 26 ;STANDARD 8" 26 SECTORS/TRACK -STDDDT .EQU 50 ;STANDARD DD 8" 50 SECTORS/TRACK -NBYTES .EQU 128 ;BYTES/SECTOR -NTRKS .EQU 77 ;TRACKS/DISK - -;-------------- S100Computers IDE HARD DISK CONTROLLER COMMANDS ETC. -IDEAport .EQU 030H ;lower 8 bits of IDE interface -IDEBport .EQU 031H ;upper 8 bits of IDE interface -IDECport .EQU 032H ;control lines for IDE interface -IDECtrl .EQU 033H ;8255 configuration port -IDEDrivePort .EQU 034H ;To select the 1st or 2nd CF card/drive (Not used with this monitor) - -IDE_Reset_Delay .EQU 020H ;Time delay for reset/initilization (~60 uS, with 10MHz Z80, 2 I/O wait states) - -CPM_ADDRESS .EQU 100H ;Will place the CPMLDR.COM Loader here with - ;CPMLDR.COM will ALWAYS be on TRK 0,SEC2, (LBA Mode) -SEC_COUNT .EQU 12 ;CPMLDR.COM r.EQUires (currently) 10, 512 byte sectors - ;Add extra just in case -; -RDcfg8255 .EQU 10010010B ;Set 8255 IDECport out, IDEAport/B input -WRcfg8255 .EQU 10000000B ;Set all three 8255 ports output -; -IDEa0line .EQU 01H ;direct from 8255 to IDE interface -IDEa1line .EQU 02H ;direct from 8255 to IDE interface -IDEa2line .EQU 04H ;direct from 8255 to IDE interface -IDEcs0line .EQU 08H ;inverter between 8255 and IDE interface -IDEcs1line .EQU 10H ;inverter between 8255 and IDE interface -IDEwrline .EQU 20H ;inverter between 8255 and IDE interface -IDErdline .EQU 40H ;inverter between 8255 and IDE interface -IDEreset .EQU 80H ;inverter between 8255 and IDE interface -; -;Symbolic constants for the IDE Drive registers, which makes the -;code more readable than always specifying the address pins -; -REGdata .EQU 08H ;IDEcs0line -REGerr .EQU 09H ;IDEcs0line + IDEa0line -REGcnt .EQU 0AH ;IDEcs0line + IDEa1line -REGsector .EQU 0BH ;IDEcs0line + IDEa1line + IDEa0line -REGcyLSB .EQU 0CH ;IDEcs0line + IDEa2line -REGcyMSB .EQU 0DH ;IDEcs0line + IDEa2line + IDEa0line -REGshd .EQU 0EH ;IDEcs0line + IDEa2line + IDEa1line ;(0EH) -REGCMD .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line ;(0FH) -REGstatus .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line -REGcontrol .EQU 16H ;IDEcs1line + IDEa2line + IDEa1line -REGastatus .EQU 17H ;IDEcs1line + IDEa2line + IDEa1line + IDEa0line - -;IDE CMD Constants. These should never change. -CMDrecal .EQU 10H -CMDread .EQU 20H -CMDwrite .EQU 30H -CMDinit .EQU 91H -CMDid .EQU 0ECH -CMDdownspin .EQU 0E0H -CMDupspin .EQU 0E1H -; -; IDE Status Register: -; bit 7: Busy 1=busy, 0=not busy -; bit 6: Ready 1=ready for CMD, 0=not ready yet -; bit 5: DF 1=fault occured insIDE drive -; bit 4: DSC 1=seek complete -; bit 3: DRQ 1=data r.EQUest ready, 0=not ready to xfer yet -; bit 2: CORR 1=correctable error occured -; bit 1: IDX vendor specific -; bit 0: ERR 1=error occured -; -;---------------------------------------------------------------------------- -; -;CONNECTIONS TO Z80-MONB.Z80 :- -; - - -#IF BIGROM -BASE .EQU 0E000H ;Start or EPROM Location (Assume a 278C64 (8k) ) -#ELSE -BASE .EQU 0F000H ;Start or EPROM Location (Assume a 2732 (4K) or half of a 278C64 (8k) ) -#ENDIF ; endif 8kROM - - .ORG BASE ;<--------<<<<<< LOCATION OF START OF MONITOR (First part) -VERSA .EQU BASE+800H ;<--------<<<<<< LOCATION OF FLOPPY BIOS (For old Software) - ; NOTE MUST INSURE NO OVERFLOW OF THE FIRST - ; PART OR THIS MONITOR INTO THIS BIOS AREA - -;PROGRAM CODE BEGINS HERE -;FIRST A JUMP TABLE FOR ALL JUMPS INTO THE MONITOR. NOTE THESE CANNOT BE -;CHANGED. WHERE POSSIBLE ZAPPLE FORMAT IS USED. - -ZAPPLE: JP BEGIN ;INITILIZATION -ZCI: JP CI ;CONSOL INPUT -ZRI: JP SERIAL_IN ;READER INPUT = Modem Input for Now -ZCO: JP CO ;CONSOL OUTPUT -ZPOO: JP SERIAL_OUT ;PUNCH OUTPUT = Modem Output for Now -ZLO: JP LO ;LIST OUTPUT -ZCSTS: JP CSTS ;CONSOL STATUS -ZMEMCK: JP MEMSIZ ;GET HIGHEST RAM RETURNS IT IN [HL] -ZTRAP: JP TRAP ;ERROR TRAP ADDRESS -ZSTART: JP START ;JUMP TO MONITOR DO NOT RESET HARDWARE -ZTALK: JP SPEAKOUT ;SEND AN ASCII CHARACTER TO TALKER (One at a time) -ZTALKS: JP SPEAKER_CTS ;STATUS FOR SPEECH CTS Line (V-Stamp CTS low when ready) -ZDELAY: JP DELAY ;SOFTWARE DELAY LENGTH IN [A] -ZLSTAT: JP LSTAT ;LIST STATUS -ZONLIST: JP ONLIST ;INITILIZE LIST DEVICE -ZOFFLIST: JP OFLIST ;TURN OFF LIST DEVICE -ZTIME: JP PRINT_TIME ;PUT TIME ON CRT @ CURSOR POSITION -ZDATE: JP PRINT_DATE ;PRINT DATE ON CRT @ CURSOR POSITION -ZSPEAK_: JP SPEAK_ ;SEND ASCII STRING TO TALKER [HL] UP TO '$' -ZSERIAL_OUT: JP SERIAL_OUT ;OUT TO ZILOG SCC SERIAL PORT -ZSERIAL_IN: JP SERIAL_IN ;INPUT FROM ZILOG SCC SERIAL PORT -ZSERIAL_STAT: JP SERIAL_STAT ;STATUS FROM ZILOG SCC SERIAL PORT -ZLOADER: JP LOADER ;LOAD IN CPM IMAGE ON TRACKS 0 & 1 (VIA FLOPPY BOOT LOADER ON DISK SECTOR 1) -ZPMSG0: JP TOM ;DISPLAY STRING ON CONSOL [HL]=START ADD. [B]=LENGTH -ZPMSG_: JP PRINT_STRING ;DISPLAY STRING ON CONSOL [HL]=START ADD. '$'=END -ZHLSP: JP HLSP ;DISPLAY [HL] ON CONSOL THEN ONE SPACE -ZBITS: JP BITS1 ;DISPLAY 8 BITS OF [A] ON CONSOL -ZLBYTE: JP LBYTE ;DISPLAY [A] ON CONSOL -ZHEXSP: JP HEXSP ;PUT 16 BIT PARAMETERS ON STACK FROM CONSOL, [C]=PARAMETER # -ZCRLF: JP CRLF ;SEND CRLF TO CONSOL -ZHILO: JP HILO ;RANGE CHECK (INC [HL], IF HL=DE THEN SET CARRY) -ZCONV: JP CONV ;CONVERT HEX IN [A] TO ASCII IN [A] -ZDOS JP MSDOS ;LOAD MSDOS FROM 5" DRIVE D: -ZPCHK: JP PCHK ;INPUT FROM CONSOL & TEST FOR DELIMITERS RET {Z} IF - ;SPACE OR , RET {C} IF A CR ELSE NON ZERO NON CARRY -VFLOPPY JP VBOOT ;BOOT UP CPM-80 FROM VERSAFLOPPY II FDC -ZHARD: JP HBOOTCPM ;BOOT UP CPM-80 FROM HARD DISK -ZPRDY: JP PRDY ;PUNCH READY CHECK -ZRSTAT: JP RSTAT ;READER STATUS -ZCCHK: JP CCHK ;CHECK FOR ^S & ESC AT KEYBOARD -ZFLOPPY JP ZBOOT ;BOOT UP CPM-80 FROM ZFDC FDC -; -; NOTE TABLE MUST BE WITHIN 0-FFH BOUNDRY -; -;COMMAND BRANCH TABLE - -TBL: - .DW FLUSH ; "@" SEND FF to LaserJet printer - .DW MEMMAP ; "A" DISPLAY A MAP OF MEMORY - .DW SWITCH_68K ; "B" SWITCH CONTROL TO 68000 CPU - .DW ZBOOT ; "C" BOOT IN CP/M FROM 8" DISK WITH WITH ZFDC FDC - .DW DISP ; "D" DISPLAY MEMORY (IN HEX & ASCII) - .DW ECHO ; "E" ECHO CHAR IN TO CHAR OUT - .DW FILL ; "F" FILL MEMORY WITH A CONSTANT - .DW GOTO ; "G" GO TO [ADDRESS] - .DW SHOW_DATE ; "H" SHOW CURRENT DATE - .DW SHOW_TIME ; "I" SHOW CURRENT TIME - .DW RAMTEST ; "J" NON-DESTRUCTIVE MEMORY TEST - .DW KCMD ; "K" DISPLAY THE LIST OF MONITOR COMMANDS - .DW VBOOT ; "L" BOOT IN CP/M FROM 8" DISK WITH VERSAFLOPPY II FDC - .DW MOVE ; "M" MOVE BLOCK OF MEMORY (START,FINISH,DESTINATION) - .DW XMEMMAP ; "N" Display extended memory Segment:Address - .DW UP8086 ; "O" SWITCH CONTROL TO 8088, 8086 or 80286. - .DW HBOOTCPM ; "P" BOOT IN CPM FROM IDE HARD DISK - .DW QUERY ; "Q" QUERY PORT (IN OR OUT) - .DW INPORTS ; "R" Read ALL Input Ports - .DW SUBS ; "S" SUBSTITUTE &/OR EXAMINE MEMORY - .DW TYPE ; "T" TYPE ASCII PRESENT IN MEMORY - .DW BEGIN ; "U" SPARE - .DW VERIFY ; "V" COMPARE MEMORY - .DW SWITCH_8086 ; "W" INPUT Port ED (switched in 8086/80286) - .DW START ; "X" BOOT IN MSDOS FROM HARD DISK (Not done yet) - .DW BOOT_RomWBW ; "Y" Boot RomWBW - .DW SIZE ; "Z" FIND HIGHEST R/W RAM - -; -;--------------------------------------------------------------------------- -; -BEGIN: - ; We are using the serial port's extra I/O port as a diagnostic port, so we need to - ; set them up here at the start of the code. - ; Port A as output to a pair of Hex Displays. - ; Port B as input from a 8 position dip switch. - LD A,AoutBin8255cfg ;A out to Hex LED, B In Dip , C(bits 0-3) output, (bits 4-7)input - OUT (PortCtrl_8255),A ;Config 8255 chip, Mode 0 - - - LD A,'#' ;For quick hardware diagnostic test - OUT (CONSOL_OUT),A - LD A,0FFH ;Clear Printer strobe, comes up 0 on a reset - OUT (PRINTER_STROBE),A ;also it turn all LED's off as a diagnostic - LD A,00000000B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC (ALL LED' ON) - OUT (DIAG_LEDS),A ;LED's will go off one at a time - - LD A,0FFH - OUT (SELECT),A ;DESELECT ANY FLOPPYS ON VERSAFLOPPY FDC (If Present) - - LD A,10000000B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC (1 LED off) - OUT (DIAG_LEDS),A - - LD A,0FFH - OUT (RSET),A ;RESET VERSAFLOPPY II FLOPPY DISK CONTROLLER (If Present) - OUT (RESET_ZFDC_PORT),A ;RESET ZFDC FLOPPY DISK CONTROLLER (If Present) - - XOR A ;SET INTERUPT TO PAGE 0H - OUT (Z80PORT+1),A ;KILL THE INTERSYSTEMS Z80 CPU BOARD INT CONTROLLER (If present) - LD I,A - ;We need to clear the 8259A otherewise teh 8086 monitor sometimes hangs - LD A,MasterICW1 ;Initilize the 8259A PIC Controller (;EDGE triggered, 4 bytes, single Master,ICW4 needed) - OUT (MASTER_PIC_PORT),A - LD A,MasterICW2 ;Ints starts at 20H in RAM (IBM-PC uses 8X4 = 20H) - OUT (MASTER_PIC_PORT+1),A - LD A,MasterICW4 ;No slaves above, so 8259 does not expect ICW3 - out (MASTER_PIC_PORT+1),A - - LD A,11111111b ;Allow no interrupts to 8259A with Z80. - out (MASTER_PIC_PORT+1),A - - LD A,0H ;SETUP MEMORY MANAGEMENT TO OVERLAP WITH - OUT (Z80PORT+2),A ;CURRENT RAM in 64K Space - LD A,04H - OUT (Z80PORT+3),A - - LD A,11000000B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC (2 LED's off) - OUT (DIAG_LEDS),A - -ZAXXLE: LD SP,AHEAD-4 ;SETUP A FAKE STACK - JP MEMSZ1 ;RETURNS WITH TOP OF RAM IN [HL] - .DW AHEAD ;Ret will pick up this address -AHEAD: LD SP,HL ;[HL] CONTAINS TOP OF RAM - WORKAREA - - PUSH HL - POP IX ;Store stack pointer for below in [IX] - - CALL INIT_S100_IO ;Initilize the Zilog 8530 & 8255 on the S100Computers I/O Board - - LD HL,MSG0 ;Have a Stack, so we can use CALL - CALL PRINT_STRING - - LD A,11100000B ;FLAG PROGRESS (Have a Stack with 3 LED's off) - OUT (DIAG_LEDS),A - - CALL PRINT_TIME ;PRINT TIME ON CRT (IF RTC BOARD PRESENT) - JP C,NO_CLOCK - LD HL,GAP_MSG - CALL PRINT_STRING - CALL PRINT_DATE ;PRINT DATE ON CRT, then CRLF -NO_CLOCK: - CALL CRLF - - LD A,11110000B ;FLAG PROGRESS (I/O board initilized, 4 LED's Off) - OUT (DIAG_LEDS),A - - LD HL,SP_MSG ;Print Current Stack Location - CALL PRINT_STRING - - - PUSH IX ;SP is stored from above in [IX] - POP HL - CALL HLSP ;Print HL/SP - CALL CRLF ;Then CRLF - CALL CSTS ;CHECK IF GARBAGE AT KEYBOARD - CALL NZ,CI ;If so flush it - - LD A,11111000B ;FLAG PROGRESS (Ready to go, 5 LED's off) - OUT (DIAG_LEDS),A - - LD HL,CR_SMSG ;lets V-Stamp chip get baud rate - CALL SPEAK_ - - CALL INITILIZE_IDE_BOARD ;initilize first IDE drive (if present) - - LD A,11111100B ;FLAG PROGRESS (Initilization done, 6 LED's off) - OUT (DIAG_LEDS),A - - -;-------THIS IS THE START ON THE MAIN MONITOR LOOP-------------------------------- - -START: LD DE,START - PUSH DE ;EXTRA UNBALANCED POP & [DE] WOULD END UP IN [PC] - CALL CRLF - LD C,BELL ;A BELL HERE WILL SIGNAL WHEN JOBS ARE DONE - CALL CO - LD C,'-' - CALL CO - LD C,'>' - CALL CO - -STARO: CALL TI ;Main loop. Monitor will stay here until cmd. - AND 7FH - JR Z,STARO - SUB '@' ;Commands @ to Z only - RET M - CP 1BH ;A-Z only - RET NC - ADD A,A - LD HL,TBL - ADD A,L - LD L,A - LD A,(HL) - INC HL - LD H,(HL) - LD L,A - LD C,02H - JP (HL) ;JUMP TO COMMAND TABLE -; -;----- GO CARRY OUT COMMAND AND POP BACK TO START---------- -; NOTE STRING IS HERE IN CASE A 2716 IS USED BY MISTAKE (Monitor will at least signon) - -MSG0: .DB SCROLL,QUIT,NO_ENHANCEMENT,FAST,BELL,CR,LF,LF - .TEXT "Z80 ROM MONITOR V4.7C (RomWBW Version 1 Nov 2012) $" -SMSG: .TEXT "Hello The Z80 ROM MONITOR Ver 4.7B Is Now Resident $" - -;SEND MESSAGE TO CONSOL MESSAGE IN [HL],LENGTH IN [B] - -TOM: - LD C,(HL) - INC HL - CALL CO - DJNZ TOM - RET -; -PRINT_STRING: - LD A,(HL) ;A ROUTINE TO PRINT OUT A STRING @ [HL] - INC HL ;UP TO THE FIRST '$'. - CP '$' - RET Z - LD C,A - CALL CO - JR PRINT_STRING - -;ABORT IF ESC AT CONSOL, PAUSE IF ^S AT CONSOL - -CCHK: CALL CSTS ;FIRST IS THERE ANYTHING THERE - RET Z - CALL CI - CP 'S'-40H - JR NZ,CCHK1 -CCHK2: CALL CSTS ;WAIT HERE UNTIL ANOTHER INPUT IS GIVEN - JR Z,CCHK2 -CCHK1: CP ESC - RET NZ ;RETURN EXECPT IF ESC - -;RESTORE SYSTEM AFTER ERROR - -ERROR: - CALL MEMSIZ ;GET RAM AVAILABLE - WORKSPACE IN [HL] - LD SP,HL ;SET STACK UP IN WORKSPACE AREA - LD C,'*' - CALL CO - JP START - -;PRINT HIGHEST MEMORY FROM BOTTOM - -SIZE: - CALL MEMSIZ ;RETURNS WITH [HL]= RAM AVAILABLE-WORKSPACE - -LFADR: CALL CRLF - -;PRINT [HL] AND A SPACE -HLSP: PUSH HL - PUSH BC - CALL LADR - LD C,SPACE - CALL CO - POP BC - POP HL - RET - -;PRINT A SPACE - -SF488: LD C,SPACE - JP CO - -;CONVERT HEX TO ASCII - -CONV: AND 0FH - ADD A,90H - DAA - ADC A,40H - DAA - LD C,A - RET - -;GET TWO PARAMETERS AND PUT THEM IN [HL] & [DE] THEN CRLF - -EXLF: CALL HEXSP - POP DE - POP HL - -;SEND TO CONSOL CR/LF - -CRLF: PUSH BC - LD C,LF - CALL CO - LD C,CR - CALL CO - POP BC - RET - -;PUT THREE PARAMETERS IN [BC] [DE] [HL] THEN CR/LF - -EXPR3: INC C ;ALREADY HAD [C]=2 FROM START - CALL HEXSP - CALL CRLF - POP BC - POP DE - POP HL - RET - -;GET ONE PARAMETER - -EXPR1: LD C,01H -HEXSP: LD HL,0000 -EX0: CALL TI -EX1: LD B,A - CALL NIBBLE - JR C,EX2X - ADD HL,HL - ADD HL,HL - ADD HL,HL - ADD HL,HL - OR L - LD L,A - JR EX0 -EX2X: EX (SP),HL - PUSH HL - LD A,B - CALL QCHK - JR NC,SF560 - DEC C - RET Z -SF560: JP NZ,ERROR - DEC C - JR NZ,HEXSP - RET -EXF: LD C,01H - LD HL,0000H - JR EX1 - -;RANGE TEST ROUTINE CARRY SET = RANGE EXCEEDED - -HILOX: CALL CCHK - CALL HILO - RET NC - POP DE ;DROP ONE LEVEL BACK TO START - RET -HILO: INC HL ;RANGE CHECK SET CARRY IF [DE]=[HL] - LD A,H - OR L - SCF - RET Z - LD A,E - SUB L - LD A,D - SBC A,H - RET - -;PRINT [HL] ON CONSOL - -LADR: - LD A,H - CALL LBYTE - LD A,L -LBYTE: - PUSH AF - RRCA - RRCA - RRCA - RRCA - CALL SF598 - POP AF -SF598: - CALL CONV - JP CO - -;THIS IS A CALLED ROUTINE USED TO CALCULATE TOP OF RAM IS USED BY -;THE ERROR TO RESET THE STACK. Returns top of RAM in [HL] - -MEMSIZ: - PUSH BC ;SAVE [BC] -MEMSZ1: - LD HL,0FFFFH ;START FROM THE TOP DOWN -MEMSZ2: - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL ;PUT BACK WHAT WAS THERE - LD (HL),A - JP Z,GOTTOP - DEC H ;TRY 100H BYTES LOWER - JR MEMSZ2 ;KEEP LOOKING FOR RAM -GOTTOP: - POP BC ;RESTORE [BC] - RET - -NIBBLE: - SUB 30H - RET C - CP 17H - CCF - RET C - CP LF - CCF - RET NC - SUB 07H - CP LF - RET - -COPCK: - LD C,'-' - CALL CO - -PCHK: CALL TI - -;TEST FOR DELIMITERS - -QCHK: - CP SPACE - RET Z - CP ',' - RET Z - CP CR - SCF - RET Z - CCF - RET - -;KEYBOARD HANDELING ROUTINE (WILL NOT ECHO CR/LF) -;IT CONVERTS LOWER CASE TO UPPER CASE FOR LOOKUP COMMANDS -;ALSO ^C WILL FORCE A JUMP TO BOOT IN CP/M -;ALL OTHERE CHARACTERS ARE ECHOED ON CONSOL - -TI: - CALL CI - CP CR - RET Z - CP 'C'-40H ;^C TO BOOT IN CP/M - JP Z,FBOOT - PUSH BC - LD C,A - CALL CO - LD A,C - POP BC - CP 40H ;LC->UC - RET C - CP 7BH - RET NC -SF754: - AND 5FH - RET - -BITS1: PUSH DE ;DISPLAY 8 BITS OF [A] - PUSH BC - LD E,A - CALL BITS - POP BC - POP DE - RET - -BITS: LD B,08H ;DISPLAY 8 BITS OF [E] - CALL SF488 -SF76E: SLA E - LD A,18H - ADC A,A - LD C,A - CALL CO - DJNZ SF76E - RET -; -;<<<<<<<<<<<<<<<<<<<<<< MAIN CONSOL OUTPUT ROUTINE >>>>>>>>>>>>>>>>>>>>>>>>> -; If console board is NOT installed, their is issues with default status BITS -; returning bad info keeping Serial Board form working. For now we will -; just force serial I/O - -CO: -; IN A,(IOBYTE1) ;NOTE CHARACTER IS IN [C] -; BIT 0,A ;CHECK IF OUTPUT TO PRINTER IS ALSO REQ -; JP Z,LOX -SDCONO: -; IN A,(CONSOL_STATUS) ;SD SYSTEMS VIDIO BOARD PORT -; AND 4H -; JR Z,SDCONO -; LD A,C -; CP 07H ;IS IT A BELL -; JR Z,BELL1 -; CP 0H ;SD BOARD CANNOT TAKE A NULL! -; RET Z - -; OUT (CONSOL_OUT),A -; IN A,(IOBYTE1) -; BIT 5,A ;SEE IF SERIAL PORT OUTPUT IS REQ -; JR NZ,SDCON5 ;MAKE SURE TO RETURN CHARACTER SENT IN [A] - CALL SERIAL_OUT ;Send data in [C] to Serial Port -SDCON5: LD A,C - RET ;RETURN CHARACTER SENT IN [A] - -LOX: - CALL SDCONO ;OUTPUT TO BOTH PRINTER & CONSOLE -; CALL LO - RET - -BELL1: -; LD A,06H ;SEND A BELL -; OUT (CONSOL_OUT),A -; LD A,0FH -; CALL DELAY -; LD A,07H -; OUT (CONSOL_OUT),A -; JR SDCON5 - - -DELAY: - DEC A ;GENERAL COUNT DOWN TIME DELAY - RET Z ;LENGTH SET IN [A] - PUSH AF - LD A,05H -MORE: DEC A - PUSH AF - XOR A -MORE2: DEC A - JR NZ,MORE2 - POP AF - JR NZ,MORE - POP AF - JR DELAY - - -;<<<<<<<<<<<<<<<<<<< MAIN CONSOL STATUS ROUTINE >>>>>>>>>>>>>>>>>>>>>> -; -; If console board is NOT installed, their is issues with default status BITS -; returning bad info keeping Serial Board form working. For now we will -; just force serial I/O and have commented out routines for CONSOLE I/O - -CSTS: -; IN A,(CONSOL_STATUS) -; AND 02H -; JP Z,TRYSER ;See if input from Serial Port is req - -; XOR A -; DEC A ;RETURN WITH 0FFH IN [A] IF SOMETHING -; RET -TRYSER: -; IN A,(IOBYTE1) -; BIT 5,A ;SEE IF SERIAL PORT INPUT IS REQ -; JP Z,SERIAL_STAT ;Check if anything at Modem IN status routine - JP SERIAL_STAT ;Check if anything at Modem IN status routine -; XOR A ;IF IOBYTE bit 1 then skip modem input -; RET ;RETURN WITH 0 IN A IF NOTHING THERE - - -;<<<<<<<<<<<<<<<<<<<< MAIN CONSOL INPUT ROUTINE >>>>>>>>>>>>>>>>>>>> - -CI: -; IN A,(CONSOL_STATUS) ;NEED CONSTAT TO CLEAN UP SHIFT KEYS ETC -; AND 02H -; JR Z,CHKSERIAL - JP CHKSERIAL ; Force it for now -; IN A,(CONSOL_IN) -; AND 7FH -; RET -CHKSERIAL: -; IN A,(IOBYTE1) -; BIT 5,A ;SEE IF SERIAL PORT INPUT IS REQ -; JR NZ,CI ;NO, then do normal CI - CALL SERIAL_STAT ;See if anything at Modem input - JP Z,CI ; No - JP SERIAL_IN ; Yes, lets get it - - -;>>>>>>>>>>>>>>>>>>>> MAIN PRINTER OUTPUT ROUTINE <<<<<<<<<<<<<<<<<<<<< - -LO: - LD B,0FFH -LO2: - CALL LSTAT - JR NZ,LO1 - DJNZ LO2 - XOR A - LD A,C - RET ;RET Z if Printer problem (Not switched on) -LO1: - LD A,0FFH ;Setup strobe high to low then high - OUT (PRINTER_STROBE),A - LD A,C - OUT (PRINTER_OUT),A ;Now Data - XOR A ;STROBE FOR CENTRONICS - OUT (PRINTER_STROBE),A - LD A,0FFH ;Raise strobe again - OUT (PRINTER_STROBE),A - OR A - RET ;Ret NZ if OK - -FLUSH: - LD C,FF ;Send a Form Feed to laserJet Printer - CALL LO ;This forces a partial page to be printed - RET - -;>>>>>>>>>>>>>>>>>>>>>> PRINTER STATUS ROUTINE <<<<<<<<<<<<<<<<<<<<<<<< - -LSTAT: - IN A,(PRINTER_STATUS) - AND 00001111B ;XXXX0110 IS READY (BIT 3=PAPER BIT 2=FAULT - CP 00000110B ;BIT 1=SELECT BIT 0=BUSY - JR Z,LSTAT1 - XOR A - RET -LSTAT1: - XOR A ;PUT 0FFH IN [A] IF READY & NO ZERO FLAG - DEC A - RET - - -;-------------- BOOT RomWBW via loader ---------------- - -BOOT_RomWBW: - - CALL ZCRLF - LD HL,RomWBW_Msg ;Print RomWBW loader sign on - CALL PRINT_STRING - JP ZSTART ; all done for now - -RomWBW_Msg: .TEXT "RomWBW Loader $" - - - - -;-------------- BOOT UP CPM FROM HARD DISK ON S100COMPUTERS IDE BOARD ---------------- - -;BOOT UP THE 8255/IDE Board HARD DISK/Flash Memory Card -;NOTE CODE IS ALL HERE IN CASE A 2716 IS USED - -HBOOTCPM: - POP HL ;CLEAN UP STACK - LD HL,SPEAKCPM_MSG ;Announce on speaker - CALL SPEAK_ - - CALL INITILIZE_IDE_BOARD ;Initilze the 8255 and drive (again just in case) - - LD D,11100000B ;Data for IDE SDH reg (512bytes, LBA mode,single drive) - LD E,REGshd ;00001110,(0EH) CS0,A2,A1, - CALL IDEwr8D ;Write byte to select the MASTER device - - LD B,0FFH ;Delay time to allow a Hard Disk to get up to speed -WaitInit: - LD E,REGstatus ;Get status after initilization - CALL IDErd8D ;Check Status (info in [D]) - BIT 7,D - JR Z,SECREAD ;Zero, so all is OK to write to drive - ;Delay to allow drive to get up to speed - PUSH BC - LD BC,0FFFFH -DXLAY2: - LD D,2 ;May need to adjust delay time to allow cold drive to -DXLAY1: - DEC D ;to speed - JR NZ,DXLAY1 - DEC BC - LD A,C - OR B - JR NZ,DXLAY2 - POP BC - DJNZ WaitInit ;If after 0FFH, 0FEH, 0FDH... 0, then drive initilization problem -IDError: - LD HL,DRIVE_NR_ERR ;Drive not ready - JP ABORT_ERR_MSG - -SECREAD: ;Note CPMLDR will ALWAYS be on TRK 0,SEC 1,Head 0 - LD A,11111111B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC - OUT (DIAG_LEDS),A - - CALL IDEwaitnotbusy ;Make sure drive is ready - JR C,IDError ;NC if ready - - LD D,1 ;Load track 0,sec 1, head 0 - LD E,REGsector ;Send info to drive - CALL IDEwr8D - - LD D,0 ;Send Low TRK# - LD E,REGcyLSB - CALL IDEwr8D - - LD D,0 ;Send High TRK# - LD E,REGcyMSB - CALL IDEwr8D - - LD D,SEC_COUNT ;Count of CPM sectors we wish to read - LD E,REGcnt - CALL IDEwr8D - - LD D,CMDread ;Send read CMD - LD E,REGCMD - CALL IDEwr8D ;Send sec read CMD to drive. - CALL IDEwdrq ;Wait until it's got the data - - LD HL,CPM_ADDRESS ;DMA address where the CPMLDR resides in RAM - LD B,0 ;256X2 bytes - LD C,SEC_COUNT ;Count of sectors X 512 -MoreRD16: - LD A,REGdata ;REG regsiter address - OUT (IDECport),A - - OR IDErdline ;08H+40H, Pulse RD line - OUT (IDECport),A - - IN A,(IDEAport) ;read the LOWER byte - LD (HL),A - INC HL - IN A,(IDEBport) ;read the UPPER byte - LD (HL),A - INC HL - - LD A,REGdata ;Deassert RD line - OUT (IDECport),A - DJNZ MoreRD16 - DEC C - JR NZ,MoreRD16 - - LD E,REGstatus ;Check the R/W status when done - CALL IDErd8D - BIT 0,D - JR NZ,IDEerr1 ;Z if no errors - LD HL,STARTCPM - LD A,(HL) - CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H - JP Z,STARTCPM ;AS THE FIRST INSTRUCTION. IF OK JP to 100H in RAM - JP ERR_LD1 ;Boot Sector Data incorrect - -IDEerr1: - LD HL,IDE_RW_ERROR ;Drive R/W Error - JP ABORT_ERR_MSG - - -; -------------------- SUPPORT ROUTINES ------------------------ - -INITILIZE_IDE_BOARD: ;Drive Select in [A]. Note leaves selected drive as [A] - LD A,RDcfg8255 ;Config 8255 chip (10010010B), read mode on return - OUT (IDECtrl),A ;Config 8255 chip, READ mode - - ;Hard reset the disk drive - ;For some reason some CF cards need to the RESET line - ;pulsed very carefully. You may need to play around - LD A,IDEreset ;with the pulse length. Symptoms are: incorrect data comming - OUT (IDECport),A ;back from a sector read (often due to the wrong sector being read) - ;I have a (negative)pulse of 60 uSec. (10Mz Z80, two IO wait states). - - LD C,IDE_Reset_Delay ;~60 uS seems to work for the 5 different CF cards I have -ResetDelay: - DEC C - JP NZ,ResetDelay ;Delay (reset pulse width) - XOR A - OUT (IDECport),A ;No IDE control lines asserted (just bit 7 of port C) - - CALL DELAY_15 ;Need to delay a little before checking busy status - -IDEwaitnotbusy: ;Drive READY if 01000000 - LD B,0FFH - LD C,080H ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreWait: - LD E,REGstatus ;Wait for RDY bit to be set - CALL IDErd8D - LD A,D - AND 11000000B - XOR 01000000B - JR Z,DoneNotBusy - DJNZ MoreWait - DEC C - JR NZ,MoreWait - SCF ;Set carry to indicate an error - RET - -DoneNotBusy: - - OR A ;Clear carry it indicate no error - RET - - - ;Wait for the drive to be ready to transfer data. -IDEwdrq: ;Returns the drive's status in Acc - LD B,0FFH - LD C,0FFH ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreDRQ: - LD E,REGstatus ;wait for DRQ bit to be set - CALL IDErd8D - LD A,D - AND 10001000B - CP 00001000B - JR Z,DoneDRQ - DJNZ MoreDRQ - DEC C - JR NZ,MoreDRQ - SCF ;Set carry to indicate error - RET -DoneDRQ: - OR A ;Clear carry - RET -; -;------------------------------------------------------------------ -; Low Level 8 bit R/W to the drive controller. These are the routines that talk -; directly to the drive controller registers, via the 8255 chip. -; Note the 16 bit I/O to the drive (which is only for SEC Read here) is done directly -; in the routine MoreRD16 for speed reasons. - -IDErd8D: ;READ 8 bits from IDE register in [E], return info in [D] - LD A,E - OUT (IDECport),A ;drive address onto control lines - - OR IDErdline ;RD pulse pin (40H) - OUT (IDECport),A ;assert read pin - - IN A,(IDEAport) - LD D,A ;return with data in [D] - - LD A,E ;<---Ken Robbins suggestion - OUT (IDECport),A ;Deassert RD pin - - XOR A - OUT (IDECport),A ;Zero all port C lines - RET - - -IDEwr8D: ;WRITE Data in [D] to IDE register in [E] - LD A,WRcfg8255 ;Set 8255 to write mode - OUT (IDECtrl),A - - LD A,D ;Get data put it in 8255 A port - OUT (IDEAport),A - - LD A,E ;select IDE register - OUT (IDECport),A - - OR IDEwrline ;lower WR line - OUT (IDECport),A - - LD A,E ;<-- Kens Robbins suggestion, raise WR line - OUT (IDECport),A - - XOR A ;Deselect all lines including WR line - OUT (IDECport),A - - LD A,RDcfg8255 ;Config 8255 chip, read mode on return - OUT (IDECtrl),A - RET - -;------------------------------------------------------------------------------------- - -;MEMORY MAP PROGRAM CF.DR.DOBBS VOL 31 P40. -;IT WILL SHOW ON CONSOL TOTAL MEMORY SUMMARY OF RAM,PROM, AND NO MEMORY -; -MEMMAP: - CALL ZCRLF - LD HL,0 - LD B,1 -MAP1: - LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A - JR NZ,MAP2 - CP (HL) - JR Z,PRINT -MAP2: - LD E,'P' ; Print P for prom -MAP3: - LD A,0FFH - CP (HL) - JR NZ,PRINT - INC L - XOR A - CP L - JR NZ,MAP3 - LD E,'.' ; Print . for no memory -PRINT: - LD L,0 - DEC B - JR NZ,NLINE - LD B,16 - CALL ZCRLF - CALL HXOT4 -NLINE: - LD A,SPACE - CALL OTA - LD A,E - CALL OTA - INC H - JR NZ,MAP1 - CALL ZCRLF - CALL ZCRLF - JP ZSTART - -;16 HEX OUTPUT ROUTINE - -HXOT4: - LD C,H - CALL HXO2 - LD C,L -HXO2: - LD A,C - RRA - RRA - RRA - RRA - CALL HXO3 - LD A,C -HXO3: - AND 0FH - CP 10 - JR C,HADJ - ADD A,7 -HADJ: - ADD A,30H -OTA: - PUSH BC - LD C,A - CALL ZCO ;SEND TO CONSOL - POP BC - RET - -;-------------DISPLAY MEMORY IN HEX - -DISP: CALL EXLF ;GET PARAMETERS IN [HL],[DE] - LD A,L ;ROUND OFF ADDRESSES TO XX00H - AND 0F0H - LD L,A - LD A,E ;FINAL ADDRESS LOWER HALF - AND 0F0H - ADD A,10H ;FINISH TO END 0F LINE -SF172: - CALL LFADR -SF175: - CALL BLANK - LD A,(HL) - CALL ZLBYTE - CALL HILOX - LD A,L - AND 0FH - JR NZ,SF175 - LD C,TAB ;INSERT A TAB BETWEEN DATA - CALL ZCO - LD B,4H ;ALSO 4 SPACES -TA11: - LD C,SPACE - CALL ZCO - DJNZ TA11 - LD B,16 ;NOW PRINT ASCII (16 CHARACTERS) - PUSH DE ;TEMPORLY SAVE [DE] - LD DE,0010H - SBC HL,DE - POP DE -T11: - LD A,(HL) - AND 7FH - CP ' ' ;FILTER OUT CONTROL CHARACTERS' - JR NC,T33 -T22: - LD A,'.' -T33: - CP 07CH - JR NC,T22 - LD C,A ;SET UP TO SEND - CALL ZCO - INC HL - DJNZ T11 ;REPEAT FOR WHOLE LINE - JR SF172 - -BLANK: - LD C,' ' - JP ZCO - -;-----------------INSPECT AND / OR MODIFY MEMORY - -SUBS: - LD C,1 - CALL ZHEXSP - POP HL -SF2E3: - LD A,(HL) - CALL ZLBYTE - LD C,'-' - CALL ZCO - CALL ZPCHK - RET C - JR Z,SF2FC - CP 5FH - JR Z,SF305 - PUSH HL - CALL EXF - POP DE - POP HL - LD (HL),E - LD A,B - CP CR - RET Z -SF2FC: - INC HL -SF2FD: - LD A,L - AND 07H - CALL Z,LFADR - JR SF2E3 -SF305: - DEC HL - JR SF2FD - -;----------------FILL A BLOCK OF MEMORY WITH A VALUE - -FILL: - CALL EXPR3 -SF1A5: - LD (HL),C - CALL HILOX - JR NC,SF1A5 - POP DE - JP ZSTART - -;---------------GO TO A RAM LOCATION - -GOTO: LD C,1 ;SIMPLE GOTO FIRST GET PARMS. - CALL HEXSP - CALL CRLF - POP HL ;GET PARAMETER PUSHED BY EXF - JP (HL) - -;--------------GET OR OUTPUT TO A PORT - -QUERY: - CALL ZPCHK - CP 'O' ;OUTPUT TO PORT - JR Z,SF77A - CP 'I' ;INPUT FROM PORT - JP Z,QQQ1 - LD C,'*' - JP ZCO ;WILL ABORT IF NOT 'I' OR 'O' -QQQ1: - LD C,1 - CALL ZHEXSP - POP BC - IN A,(C) - JP ZBITS -; -SF77A: - CALL ZHEXSP - POP DE - POP BC - OUT (C),E - RET - - -;--------------MEMORY TEST - -RAMTEST: - CALL EXLF -SF200: - LD A,(HL) - LD B,A - CPL - LD (HL),A - XOR (HL) - JR Z,SF215 - PUSH DE - LD D,B - LD E,A ;TEMP STORE BITS - CALL ZHLSP - CALL BLANK - LD A,E - CALL ZBITS - CALL ZCRLF - LD B,D - POP DE -SF215: - LD (HL),B - CALL HILOX - JR SF200 - -;---------------MOVE A BLOCK OF MEMORY TO ANOTHER LOCATION - -MOVE: - CALL EXPR3 -SF21E: - LD A,(HL) - LD (BC),A - INC BC - CALL HILOX - JR SF21E - -;---------------VERIFY ONE BLOCK OF MEMORY WITH ANOTHER - -VERIFY: - CALL EXPR3 -VERIO: - LD A,(BC) - CP (HL) - JR Z,SF78E - PUSH BC - CALL CERR - POP BC -SF78E: - INC BC - CALL HILOX - JR VERIO - RET -; -CERR: - LD B,A - CALL ZHLSP - LD A,(HL) - CALL ZLBYTE - CALL BLANK - LD A,B - CALL ZLBYTE - JP ZCRLF - -ECHO: - CALL CI ;Routine to check keyboard etc. - CP 'C'-40H ;Loop until ^C - RET Z - CP 'Z'-40H - RET Z - LD C,A - CALL CO - JR ECHO - - -;Display Extended memory map for 1MG RAM using IA-2 Z80 Board window registers - -XMEMMAP: - LD HL,MSG17 ;Get segment (0-F) - CALL PRINT_STRING - LD C,1 - CALL ZHEXSP ;Get 2 or 4 hex digits (count in C). - POP HL - LD A,L ;Get single byte value - AND 0FH - EXX - LD D,A ;Store in D' for 000X:YYYY display below - SLA A - SLA A - SLA A - SLA A - OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space - LD E,A ;store shifted nibble in E' - LD HL,0 ;Will store 0-FFFF for total RAM display (not actual access) - EXX - LD D,0 ;Total display line count (256 characters, 16 lines X 16 characters) - - CALL ZCRLF - LD HL,0 - LD B,1 -XMAP1: - LD A,H - AND 00111111B ;Wrap 16K window - LD H,A - LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A ;Save it back - JR NZ,XMAP2 - CP (HL) - JR Z,XPRINT -XMAP2: - LD E,'p' -XMAP3: - LD A,0FFH - CP (HL) - JR NZ,XPRINT - INC L - XOR A - CP L - JR NZ,XMAP3 - LD E,'.' -XPRINT: - LD L,0 - DEC B - JR NZ,XNLINE - LD B,16 - CALL ZCRLF - CALL SET_WINDOW - LD A,SPACE - JR XN11 -XNLINE: - LD A,SPACE - CALL OTA - LD A,E -XN11: - CALL OTA - INC H - INC D ;Are we done yet - JR NZ,XMAP1 - CALL ZCRLF - XOR A - OUT (Z80PORT+2),A ;Set RAM window back to the way it was - JP ZSTART - -SET_WINDOW: ;Setup the unique IA-II Z80 board window to address > 64k - EXX - LD C,D ;Print seg value - CALL HXO2 - LD C,':' - CALL CO - CALL HXOT4 ;Print HL' (not origional HL) - - LD A,H ;get current H being displayed (Already pointed to first 16K window) -NOTW0: - CP 40H - JR NZ,NOTW1 - LD A,E - ADD A,04H ;Window for 4,5,6,7, set to H from above - JR DOWIN - -NOTW1: - CP 80H - JR NZ,NOTW2 - LD A,E - ADD A,08H ;Window for 8,9,A,B set to H from above - JR DOWIN - -NOTW2: - CP 0C0H - JR NZ,NOTW3 ;Must be values in between - LD A,E - ADD A,0CH ;Window for 4,5,6,7, set to H from above -DOWIN: - OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space -NOTW3: LD A,H - ADD A,10H - LD H,A - EXX ;Get back normal register set - RET - - -;Place an 8086 a Far Jump at F000:FFF0H (FFFF0H) to 500H in RAM for the 8086/80286 -;If there is a ROM there nothing will change and the 8086 reset/boot will jump -;from F000:FFF0 to the start or the ROM monitor at F000:FC00H. If however -;no ROM is present the 8086 will find the RAM code below and jump to 500H in RAM -;Whatever is at that location will then run - usually CPM86. - -UP8086: - LD A,0FCH ;Point to 8086 Reset location - OUT (Z80PORT+2),A ;Re-map to 0000H to FC000H - LD HL,3FF0H - LD (HL),0EAH - INC HL - LD (HL),0H - INC HL - LD (HL),05H - INC HL - LD (HL),0H - INC HL - LD (HL),0H - INC HL - LD (HL),0F4H ;Put an 8086 HLT here just in case - -; LD (HL),0B0H ;Continously put "3" on Consol via port 01 -; INC HL ;Basic test for 8086 on reset -; LD (HL),33H -; INC HL -; LD (HL),0E6H -; INC HL -; LD (HL),01H -; INC HL -; LD (HL),0EBH -; INC HL -; LD (HL),0FAH - - XOR A - OUT (Z80PORT+2),A ;Re-map back to 0H - JP SWITCH_8086 ;Switch over control to the 8086 - - -;----------------READ ASCII FROM MEMORY - -TYPE: - CALL EXLF -SF30B: - CALL LFADR - LD B,56 -SF310: - LD A,(HL) - AND 7FH - CP SPACE - JR NC,SF319 -SF317: - LD A,2EH -SF319: - CP 7CH - JR NC,SF317 - LD C,A - CALL ZCO - CALL HILOX - DJNZ SF310 - JR SF30B - - -;-------------Display all active I/O input-ports in the system -; -INPORTS: - CALL ZCRLF - LD B,0 ;Now loop through all ports (0-FF) - LD D,6 ;Display 6 ports across - LD E,0FFH ;Will contain port number -LOOPIO: - LD C,E - LD A,E - ; Special Case here! - CP SW86 ;Inputing here will switch out the Z80 to 8086/80286 - JR Z,SKIP - CP SW68K ;Also this one (68K) - JR Z,SKIP -; - IN A,(C) ;Remember [ZASMB does not work with this opcode,SLR is OK] - CP 0FFH ;No need for 0FF's - JR Z,SKIP - LD H,A ;store port data in H for below - LD A,E ;Need to print port # first - CALL LBYTE ;Print port number - LD C,'-' - CALL ZCO - LD C,'>' - CALL ZCO - LD A,H ;get back port data - CALL LBYTE ;print it - LD C,TAB - CALL ZCO - DEC D ;6 ports per line - JR NZ,SKIP - LD D,6 - CALL ZCRLF -SKIP: - DEC E ;Next Port - DJNZ LOOPIO - CALL ZCRLF - RET - - -; -;--------------S100Computers Serial I/O Board Initilization -;Note both Zilog SCC serial ports (A & B) will be set to 38,400 Baud initially. - -INIT_S100_IO: - ;First the 8255 -; LD A,AinBout8255cfg ;A input, B output, C(bits 0-3) output, (bits 4-7)input - LD A,AoutBin8255cfg ;A Out to Hex LED, B In Dip Switch, C(bits 0-3) output, (bits 4-7)input - OUT (PortCtrl_8255),A ;Config 8255 chip, Mode 0 - - ;Then the SCC - LD A,ACTL ;Program Channel A - LD C,A - LD B,0EH ;Byte count for OTIR below - LD HL,SCCINIT - OTIR -; - LD A,BCTL ;Program Channel B - LD C,A - LD B,0EH ;Byte count for OTIR below - LD HL,SCCINIT - OTIR - RET -; -; ALL SSC's are set for 19,200 BAUD, can be changed below -; -SCCINIT: - .DB 04H ;Point to WR4 -; .DB 44H ;X16 clock,1 Stop,NP - .DB 47H ; x16 1stop even parity -; - .DB 03H ;Point to WR3 - .DB 0C1H ;Enable reciever, Auto Enable, Recieve 8 bits -; .DB 0E1H ;Enable reciever, No Auto Enable, Recieve 8 bits (for CTS bit) -; - .DB 05H ;Point to WR5 -; .DB 0EAH ;Enable, Transmit 8 bits, Set RTS,DTR, Enable - .DB 0AAH ; enable transmit 7 bits rts/dtr enable -; - .DB 0BH ;Point to WR11 - .DB 56H ;Recieve/transmit clock = BRG -; - .DB 0CH ;Point to WR12 -; .DB 40H ;Low Byte 2400 Baud -; .DB 1EH ;Low Byte 4800 Baud -; .DB 0EH ;Low Byte 9600 Baud - .DB 06H ;Low byte 19,200 Baud <<<<<<<<<<< -; .DB 02H ;Low byte 38,400 Baud -; .DB 00H ;Low byte 76,800 Baud -; - .DB 0DH ;Point to WR13 - .DB 00H ;High byte for Baud -; - .DB 0EH ;Point to WR14 - .DB 01H ;Use 4.9152 MHz Clock. Note SD Systems uses a 2.4576 MHz clock, enable BRG -; - .DB 0FH ;Point to WR15 - .DB 00H ;Generate Int with CTS going high - - - NOP ; ?? why?? - NOP - NOP - -;---------------------------------------------------------------------------- - .ORG VERSA ;<--------- THIS LOCATION MUST NOT BE CHANGED (F800H) - ;My old CPM V1.4 systems are counting on it being here -; -; VERSAFLOPPY II DOS SYSTEM LINKAGES (USED BY SDOS & 2.2 CP/M) -; These are residule JP's for old CPM BIOS'es. Only LOADER is now functional. - -FBOOT: JP BOOT ;COLD START ENTRY -WBOOT: JP BIOS_JP_ERR ;WARM START ENTRY -CSE: JP ZCSTS ;CONSOLE STATUS -CIE: JP ZCI ;CONSOLE IN -COE: JP ZCO ;CONSOLE OUT -LIST: JP ZLO ;TO MONITOR FOR PRINTER -PUNCH: JP ZPOO ;TO MONITOR FOR PUNCH -READR: JP ZRI ;TO MONITOR FOR READER -HME: JP BIOS_JP_ERR ;HOME , MOVE TO TRACK 0 -SDSKE: JP BIOS_JP_ERR ;SELDSK -S_TRKE: JP BIOS_JP_ERR ;SET_TRK -SSECE: JP BIOS_JP_ERR ;SETSEC -SDMAE: JP BIOS_JP_ERR ;SETDMA -RDE: JP BIOS_JP_ERR ;READF -WRE: JP BIOS_JP_ERR ;WRITEF -LISTS: JP LSTAT ;LIST STATUS -SECTR: JP BIOS_JP_ERR ;SECTRAN FOR 2.2 SECTOR TRANSLATION TABLE - -DTYPE: JP BIOS_JP_ERR ;UNITSL SET UP @UNIT BYTE (DISK DENSITY) -SVE: JP BIOS_JP_ERR ;SAVER SAVE N RECORDS -LDE: JP LOADER ;LOADER LOAD N SECTORS FROM TRACK 0 (& TRACK 1) - -BIOS_JP_ERR: - LD HL,BIOS_ERR ;"BIOS JMP longer implemented in ROM @ F800H." - JP ABORT_ERR_MSG - - - - -;BOOT LOADS A SECTOR TO 80H AND THEN JUMPS TO 80H -;NOTE. Two FDC Boards are supported here:- -; -; VFDC_BOOT Boots CPM from the Versafloppy-II disk controller board -; ZFDC_BOOT Boots CPM from the ZFDC controller board - - -VBOOT: - XOR A ;0 = Flag as Boot from Versafloppy II FDC - JR BOOT_COLD -ZBOOT: - XOR A - DEC A ;0FFH = Flag as Boot from ZFDC FDC -BOOT_COLD: - LD (_FDCTYPE),A ;0 for VF, 0FFH for ZFDC - -BOOT: - LD A,11111111B ;FLAG PROGRESS VISUALLY FOR DIAGNOSTIC - OUT (DIAG_LEDS),A - - LD HL,SPEAKCPM_MSG ;Announce on speaker - CALL SPEAK_ - XOR A - LD (CDISK1),A ;MAKE CURRENT DISK A: - LD (CIOBYTE),A ;CLEANUP IOBYTE - LD (_UNIT),A ;8LOAD.Z80 (The first sector loader module) will count on this being 0H - ;for the Versafloppy-II boots - LD (ZERO_L),A ;These need to be zero's here for the CPM Loader/Versafloppy-II of my old - LD (ZERO_H),A ;NON-BANKED CPM3 or CPM2.2 disks. Need to later find out why! - LD HL,128 ;Assume 128 byte sectors for 8" disk - LD (_SEC_SIZE),HL - -BOOTW1: LD SP,_SSTACK - LD A,(_FDCTYPE) ;Are we using a Versafloppy II or ZFDC FDC board - OR A - JP NZ,ZFDC_BOOT ;<<<<<<<<< Go to ZFDC Board BOOT >>>>>>>>>>>>> - -VFDC_BOOT: - LD HL,BOOT_MSG0 ;<<<<<<<<< BOOT FROM VERSAFLOPPY-II >>>>>>>>>>>> - CALL PRINT_STRING ;"Loading CPM from VF FDC" - LD HL,VF_MSG - CALL PRINT_STRING - - LD A,0D0H ;FORCE CHIP INTERUPT - OUT (CMD),A - - LD A,STDSDT ;SETUP FOR SD - LD (_COUNT),A ;STORE AS 26 SECTORS/TRACK - LD A,0FEH - OUT (SELECT),A ;Select Drive A: (Always) - - XOR A - LD (_TRK),A - INC A - LD (_SCTR),A - - CALL READY_CHK ;Critical to make sure chip is ready first! - LD A,RSCMD ;RESTORE COMMAND (Note 3 Ms seek) - OUT (CMD),A - CALL READY_CHK ;Critical to make sure chip is ready first! - - LD HL,COLD - LD (_TADDR),HL - - CALL VF_READ_SECTOR ;Read the Boot Sector -BOOT_SEC_READ: - JP NZ,ERR_LD -BOOT_SEC_CHECK: - LD HL,COLD - LD A,(HL) - CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H - JP Z,COLD ;AS THE FIRST INSTRUCTION. IF OK JP 80H - JP ERR_LD1 ;Boot Sector Data incorrect - - -VF_READ_SECTOR: ;READ SECTOR COMMAND - LD B,3 ;Will Try 3 times -READ1: PUSH BC - CALL DRINIT ;Setup sector paramaters - LD A,E - CP 80H ;128 or 512 byte sectors ? - LD B,128 - DI - LD A,RDCMD - OUT (CMD),A ;Note wait states are now switched on - - JR M2 -M2: - JR MM2 -MM2: - JR Z,RD_128 - LD B,0 ;256 X 2 - INIR ;[C]-> [HL++],[B--] -RD_128: - INIR - - EI - CALL WAITF ;Wait states are now off - IN A,(STATUS) - AND SRMASK ;Check sector was read OK - POP BC - RET Z - DEC B - JR NZ,READ1 - XOR A - DEC A - RET ;Return NZ if failure after 3 reads - - -DRINIT: - CALL SEEK ;DRIVE INITIALIZATION - LD HL,(_TADDR) ;SETUP DMA ADDRESS AND BYTE COUNT - LD A,(_SCTR) - OUT (SECTOR),A - - LD DE,(_SEC_SIZE) ;This will be 128 or 512 sectors - LD C,DATA ;8067H in BC - -SWEB: - IN A,(SELECT) ;ENABLE WAIT STATES - AND 7FH - OUT (SELECT),A - RET - - -; SEEK TRACK -SEEK: LD A,(_TRK) - LD C,A - IN A,(TRACK) - CP C - RET Z ;IF SAME TRACK NO NEED TO SEEK - - LD A,(_TRK) - OUT (DATA),A - CALL READY_CHK ;Critical to make sure chip is ready first! - LD A,FSKCMD ;Send Seeek Command to WD1791 - OUT (CMD),A - CALL DELAY_15 ;Delay ~15ms - CALL READY_CHK - IN A,(TRACK) - LD C,A - LD A,(_TRK) - CP C - RET Z - LD HL,SEEK_ERROR_MSG - JP ABORT_ERR_MSG - - -READY_CHK: - LD BC,0 -READY_CHK1: - IN A,(STATUS) - AND 1 - RET Z - DEC BC - LD A,C - OR B - JP NZ,READY_CHK1 ;Wait until 1791/5 is ready - JP WAIT3 - -WAITF: LD E,0 - PUSH BC - LD C,2 -WAIT2: IN A,(STATUS) - AND 1 - JR Z,DWAIT - DJNZ WAIT2 - DEC E - JR NZ,WAIT2 - DEC C - JR NZ,WAIT2 - POP BC -WAIT3: IN A,(SELECT) ;IF BY THIS TIME NOT READY FORCE - OR 80H ;A HARDWARE RESET - OUT (RSET),A - LD HL,VF_HUNG - JP ABORT_ERR_MSG - - -; DISABLE WAIT STATES -DWAIT: POP BC ;TO BALANCE THE ABOVE PUSH IN WAIT -DDWAIT: IN A,(SELECT) - OR 80H - OUT (SELECT),A - RET - -DELAY_15: ;DELAY ~15 MS - LD A,40 -DELAY1: LD B,0 -M0: DJNZ M0 - DEC A - JR NZ,DELAY1 - RET - -DELAY_150: ;DELAY ~150 MS - LD C,10 -DELAY320A: - CALL DELAY_15 - DEC C - JP NZ,DELAY320A - RET - -LOADER: LD A,(_FDCTYPE) ;Are we using a Versafloppy II or ZFDC FDC board - OR A - JP NZ,ZFDC_LOADER ;Go to ZFDC Board Loader - - - ; LOAD A NUMBER OF SECTORS -VF_LOADER: - CALL VF_READ_SECTOR - JP NZ,ERR_LD - LD C,'.' ;Show progress - CALL CO - CALL INCP - JR NZ,VF_LOADER - RET - -; INC SECTOR AND TRACK -INCP: - LD HL,(_TADDR) - LD DE,(_SEC_SIZE) ;128 or 512 byte sectors -INCP2: - ADD HL,DE - LD (_TADDR),HL - LD HL,_NREC - DEC (HL) - RET Z ;Return when we have done all sectors (~51) - LD HL,_SCTR - INC (HL) - LD A,(_COUNT) ;IS ONE TRACK DONE YET (Sec/track+1) - INC A - CP (HL) - RET NZ ;IF FULL Z, THEN GO TO NEXT TRACK - LD (HL),1 ;SET SECTOR COUNT BACK TO 1 - INC HL ;ASSUMES @TRK=SECTOR+1 IE 44H - INC (HL) - OR A ;MAKE SURE TO RETURN NZ - RET - - -ERR_NR: - LD HL,DRIVE_NR_ERR ;"DRIVE NOT READY - JP ABORT_ERR_MSG -ERR_LD: - LD HL,BOOT_LD_ERR ;"ERROR READING BOOT/LOADER SECTORS" - JP ABORT_ERR_MSG -ERR_LD1: - LD HL,BOOT_LD1_ERR ;"DATA ERROR IN BOOT SECTOR" - -ABORT_ERR_MSG: - CALL PRINT_STRING - JP ZAPPLE ;BACK TO START OF MONITOR. - - -;---------------------- ZFDC FDC BOOT & LOADER ----------------------------------- - -ZFDC_BOOT: ;Cold Boot with ZFDC FDC Board - LD HL,BOOT_MSG0 ;<<<<<<<<< BOOT FROM ZFDC BOARD >>>>>>>>>>>>>> - CALL PRINT_STRING ;"Loading CPM from ZFDC FDC" - LD HL,ZFDC_MSG - CALL PRINT_STRING - - OUT (RESET_ZFDC_PORT),A ;Do a hardware reset. Does not matter what is in [A] - - LD A,STATUS_DELAY ;~0.5 second at 10 MHz - LD BC,0 ;Delay to allow board to setup hardware -WAIT_D: - DEC B - JR NZ,WAIT_D ;Delay for ~0.5 seconds - DEC B ;Reset B to 0FFH - DEC C - JR NZ,WAIT_D - DEC A - JR NZ,WAIT_D - - IN A,(S100_DATA_B) ;Check the board is there - CP CMD_HANDSHAKE ;Make sure we get HANDSHAKE byte back - JP NZ,ERR_NR ;If error, just abort - - LD A,CMD_HANDSHAKE ;Send another byte just to be sure. - OUT (S100_DATA_B),A ;This clears up ints on ZFDC board - CALL WAIT_FOR_ACK ;Wait to make sure all is well. - OR A - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SET_FORMAT ;Send Set Disk Format to 8" SSSD DISK - CALL S100OUT - LD C,0 ;Floppy Drive 0, (ZFDC Board expects a 0H, 1H, 2H or 3H) - CALL S100OUT - LD C,STD8IBM ;ZFDC Board expects a Disk Format Table Number (0,1,2...13H) - CALL S100OUT - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SET_DRIVE ;Send a "Set Drive CMD" to ZFDC board - CALL S100OUT - LD C,0 ;Floppy Drive #, (ZFDC Board expects a 0H, 1H, 2H or 3H) - CALL S100OUT - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - ;Drive selected and ready to read sectors. Note this code - ;is written to eb compatible with the boot loader for the - ;Versafloppy-II disk controller as well. - - LD A,STDSDT ;SETUP FOR SD - LD (_COUNT),A ;STORE AS 26 SECTORS/TRACK - - XOR A ;Setup Boot Sector read track - LD (_TRK),A - INC A - LD (_SCTR),A - LD (_NREC),A ;read only 1 sector initially - - LD HL,COLD - LD (_TADDR),HL - - CALL ZFDC_MULTI_READ_SECTOR ;Actully we will only read one sector here - JP BOOT_SEC_READ ;JMP to same section as for Versafloppy boot - - -ZFDC_MULTI_READ_SECTOR: - LD C,CMD_SET_TRACK ;Set Track - CALL S100OUT - LD A,(_TRK) - LD C,A - CALL S100OUT ;Send Selected track HEX number - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SET_SECTOR ;Set Sector # to side A (or for DS disks also side B) - CALL S100OUT - LD A,(_SCTR) - LD C,A - CALL S100OUT ;Send Selected sector HEX number - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_SEEK_TRACK ;Later can let board do this - CALL S100OUT - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - JP NZ,ERR_NR ;If error, just abort - - LD C,CMD_RD_MULTI_SECTOR ;Routine assumes r.EQUired Drive Table,Drive,Side,Track, and sector are already sent to board - CALL S100OUT ;(Note [HL]-> Sector DMA address) - LD A,(_NREC) ;How many sectors - LD C,A - CALL S100OUT - CALL WAIT_FOR_ACK ;Wait for NO_ERRORS_FLAG to come back - JP NZ,ERR_NR ;If error, just abort - - LD HL,(_TADDR) ;Set DMA address - -MULTI_RD_SEC: - LD DE,(_SEC_SIZE) ;For CPM this will be 128 Byte sector(s) -RD_SEC: - CALL S100IN ;Note potential to lockup here & below (but unlightly) - LD (HL),A - INC HL - DEC DE - LD A,E - OR D - JR NZ,RD_SEC - - LD A,(_NREC) ;How many sectors of data worth - DEC A - LD (_NREC),A - JR NZ,MULTI_RD_SEC ;Are there more - - CALL WAIT_FOR_ACK ;Return Z (and NO_ERRORS_FLAG in [A]), or NZ with error # in [A] - RET - - -S100OUT: - IN A,(S100_STATUS_B) ;Send data to ZFDC output (arrive with character to be sent in C) - BIT DIRECTION_BIT,A ;Is ZFDC in output mode, if not wait - JR NZ,S100OUT - BIT DATA_OUT_RDY,A ;Has previous (if any) character been read. - JR Z,S100OUT ;Z if not yet ready - LD A,C - OUT (S100_DATA_B),A - RET - -S100STAT: - IN A,(S100_STATUS_B) ;Check if ZFDC has any data for S-100 system - BIT DATA_IN_RDY,A ;Anything there ? - RET Z ;Return 0 if nothing - XOR A - DEC A ;Return NZ, & 0FFH in A if something there - RET - -S100IN: - IN A,(S100_STATUS_B) ;Check if ZFDC has any data for S-100 system - BIT DIRECTION_BIT,A ;Is ZFDC in input mode, if not wait - JR Z,S100IN ;If low then ZFDC board is still in input mode, wait - BIT DATA_IN_RDY,A - JR Z,S100IN - IN A,(S100_DATA_A) ;return with character in A - RET - -WAIT_FOR_ACK: ;Delay to wait for ZFDC to return data. There is a timeout of about 2 sec. - PUSH BC ;This can be increased if you are displaying debugging info on the ZFDC - PUSH DE ;HEX LED display. - LD BC,0 - LD E,STATUS_DELAY ;Timeout, (about 2 seconds) -WAIT_1: - IN A,(S100_STATUS_B) ;Check if ZFDC has any data for S-100 system - BIT DIRECTION_BIT,A ;Is ZFDC in input mode - JR Z,WAIT_2 ;if low then ZFDC is still in input mode - CALL S100STAT ;Wait until ZFDC Board sends something - JR Z,WAIT_2 - CALL S100IN ;Get returned Error # (Note this releases the SEND_DATA routine on the ZFDC board) - CP NO_ERRORS_FLAG ;Was SEND_OK/NO_ERRORS_FLAG sent back from ZFDC Board - POP DE ;Balance up stack - POP BC - RET ;Return NZ if problem, Z if no problem -WAIT_2: DEC B - JR NZ,WAIT_1 ;Try for ~2 seconds - DEC B ;Reset B to 0FFH - DEC C - JR NZ,WAIT_1 - DEC B ;Reset B to 0FFH - DEC C - DEC E - JR NZ,WAIT_1 - XOR A - DEC A - POP DE ;Balance up stack - POP BC - RET ;Return NZ flag set if timeout AND 0FFH in [A] - - -; LOAD A NUMBER OF SECTORS ;Note this loader utilizes the fast multi-sec read in V2.8 of later - -ZFDC_LOADER: ;CPM Loader with ZFDC FDC Board - CALL ZFDC_MULTI_READ_SECTOR ;Note the Boot sector has by now setup the sector count etc. in low RAM - RET - - -;---------------------------------------------------------------------------- -; Module to boot MSDOS from 5" DDDS disk (Note this module has not been updated yet) -; -MSDOS: - LD HL,SPEAKDOS_MSG ;Announce on speaker - CALL SPEAK_ - CALL CRLF - - JP ERR_NR ;Not done Yet - -; LD A,4 ;MSDOS.SYS STARTS AT SECTOR 4 SIDE B -; LD (_SCTR),A -; LD A,0 -; LD (_TRK),A ;START ON TRACK 0 -; LD A,1 -; LD (_SIDE),A ;START ON SIDE B -; LD A,FFILE_SIZE ;SIZE OF DOS IN 512 BYTE SECTORS -; LD (_NREC),A -; -; LD A,01110100B ;0,DD,5",SIDE 1, 0100=D: -; CALL MDSEL -; JP NZ,ERR_NR ;ROUTINE TO SAY DRIVE NOT READY -; LD A,RSVCMD ;SEND RESTORE COMMAND -; CALL DCMDI -; JR Z,DGETID -;DOS1: -; LD HL,RESTORE_ERR ;RESTORE FAILED -; JP ABORT_ERR_MSG -; -;DGETID: -; CALL DIDRD -; JR NZ,DOS1 -; -;GETSEC: -; LD HL,STARTDOS -;DGET1: -; LD C,'.' ;to indicate on CRT sectors read -; CALL CO -; LD A,(_SCTR) -; OUT (SECTOR),A -; LD B,0 ;256 BYTES -; LD C,DATA ;DATA PORT -; DI ;just in case -; CALL SWEB ;SET WAIT ENABLE BIT -; LD A,RDCMD -; OUT (CMD),A -; INIR -; INIR ;512 BYTES TOTAL -; LD B,0 -;DWAITF: -; IN A,(STATUS) -; AND 1 -; DJNZ DWAITF -; -; CALL DDWAIT -; -; IN A,(STATUS) ;CHECK STATUS -; AND 0FEH -; JP NZ,ERR_LD ;ROUTINE TO SAY SECTOR READ ERROR -; -; LD A,(_NREC) -; DEC A -; LD (_NREC),A -; JP Z,STARTDOS -; -; LD A,(_SCTR) -; INC A -; LD (_SCTR),A -; CP 0AH ;end of track yet? -; JR NZ,DGET1 -; -; LD A,(_SIDE) -; CP 1 ;if on track 1 go to side 1 else side 0 -; JR Z,TRK1A -; LD A,1 ;FLAG CURRENT SIDE IS NOW B -; LD (_SIDE),A -; LD A,01110100B ;SWITCH TO SIDE B -; JR TRK1B -;TRK1A: -; LD A,(_TRK) -; INC A -; LD (_TRK),A -; LD A,0 -; LD (_SIDE),A ;FLAG CURRENT SIDE IS NOW A -; LD A,01100100B ;SWITCH TO SIDE A -;TRK1B: -; CALL MDSEL -; JP NZ,ERR_NR ;ROUTINE TO SAY DRIVE NOT READY -; -;DSEC: -; LD A,1 -; LD (_SCTR),A -; -; LD A,(_TRK) -; OUT (DATA),A -; LD A,MSKCMD ;SEEK TO TRACK WITH VERIFY -; CALL DCMDI -; JP Z,DDRS3 -;DSEC1: -; LD HL,MSGH4 ;SEEK ERROR MESSAGE -; JP ABORT_ERR_MSG -; -;xxxz: HALT - -;DDRS3: -; PUSH HL -; CALL DIDRD -; POP HL -; JR NZ,DSEC1 -; JP DGET1 -; -;DIDRD: -; LD HL,_IDSV -; LD BC,600H+DATA -; CALL SWEB -; LD A,RDACMD ;SEND READ ID COMMAND -; OUT (CMD),A -; INIR -;DWAITS: -; IN A,(STATUS) -; AND 1 -; JR NZ,DWAITS -; CALL DDWAIT ;DISABEL WAIT STATE GENERATOR -; LD A,(_IDSV) ;++++++++++++++ -; LD B,A -; LD A,(_TRK) -; CP B ;RETURN WITH Z IF AT RIGHT TRACK -; RET - -;MDSEL: -; CPL -; OUT (SELECT),A -;DRDYCK: -; IN A,(STATUS) -; AND 80H -; JP NZ,DRDYCK -; RET -; -;SEND TYPE 1 COMMANDS (RESTORE,SEEK,STEP) -; -;DCMDI: -; LD (_CMDSV),A ;TEMPORLY STORE COMMAND -; LD A,80H -; LD (_ERMASK),A -;DCMDI1: -; IN A,(STATUS) ;IS 1793 READY -; AND 01H -; JP NZ,DCMDI1 -; LD A,(_CMDSV) -; OUT (CMD),A -; CALL DELAY_15 ;DELAY R.EQUIRED FOR A VALID STATUS -;DEEND: -; IN A,(STATUS) ;END OF DISK COMMANDS ROUTINE -; AND 01H -; JP NZ,DEEND ;IS 1793 STILL BUSY -; IN A,(STATUS) -; LD D,A -; LD A,(_ERMASK) -; AND D ;CHECK FOR ERRORS -; RET - -;------THIS IS THE MAIN ROUTINE TO GET THE TIME DATA FROM THE CMOS-RTC Chip on the MSDOS Support Board - -SHOW_TIME: - LD HL,TIME_MSG - CALL PRINT_STRING ;Print message up to '$' - CALL PRINT_TIME - RET - -SHOW_DATE: - LD HL,DATE_MSG - CALL PRINT_STRING ;Print message up to '$' - CALL PRINT_DATE - RET - - -PRINT_TIME: - CALL UPD_IN_PR ;CHECK FOR UPDATE IN PROCESS - JP NC,RTC_2A ;GO AROUND IF OK - JP RTC_ERROR ;IF ERROR - -RTC_2A: LD E,-2 ;-2 goes to 0 for PORT_INC_2 - CALL PORT_INC_2 ;SET ADDRESS OF SECONDS - IN A,(CMOS_PORT+1) ;Get BCD value returned - LD D,A ;SAVE IN D - CALL PORT_INC_2 ;SET ADDRESS OF MINUTES - IN A,(CMOS_PORT+1) ;Get BCD value returned - LD C,A ;SAVE IN C - CALL PORT_INC_2 ;SET ADDRESS OF HOURS - IN A,(CMOS_PORT+1) ;Get BCD value returned - LD B,A ;SAVE - LD E,0 ;SET E TO ZERO - CALL DisplayTime - XOR A ;Clear Carry - RET ;BACK TO MONITOR - -RTC_ERROR: ;Indicate RTC Board is not present or Error - SCF ;SET CARRY FOR ERROR - RET - -;Display time -; Arrive with B = HOURS IN BCD -; C = Minutes in BCD -; D = Seconds in BCD -DisplayTime: - PUSH DE - PUSH BC - LD A,B - CALL PRINT_BCD ;Hours. Convert BCD to ASCII - LD C,':' - CALL ZCO - POP BC - LD A,C - CALL PRINT_BCD ;Minutes. Convert BCD to ASCII - LD C,':' - CALL ZCO - POP DE - LD A,D - CALL PRINT_BCD ;Seconds. Convert BCD to ASCII - RET - -PRINT_DATE: - CALL UPD_IN_PR - JP NC,RTC_4A - JP RTC_ERROR ;IF ERROR - -RTC_4A: - LD E,6 - CALL PORT_INC ;POINT TO DAY - IN A,(CMOS_PORT+1) - LD B,A ;SAVE IN A - CALL PORT_INC ;POINT TO MONTH - IN A,(CMOS_PORT+1) - LD D,A ;SAVE IN D - CALL PORT_INC ;POINT TO YEAR - IN A,(CMOS_PORT+1) - LD C,A ;SAVE IN C - LD E,31H ;POINT TO CENTURY BYTE SAVE AREA - CALL PORT_INC ; - IN A,(CMOS_PORT+1) ;GET VALUE - LD E,B ;GET DAY BACK - LD B,A - CALL DisplayDate - XOR A ;Clear Carry - RET ;FINISHED - - -;Display date -; Return B = CENTURY IN BCD -; C = Year in BCD -; D = Month in BCD -; E = Day in BCD -DisplayDate: - PUSH DE - PUSH DE - PUSH BC - PUSH BC - - POP BC - LD A,B - CALL PRINT_BCD ;Century (19/20). Convert BCD to ASCII - POP BC - LD A,C - CALL PRINT_BCD ;Year. Convert BCD to ASCII - LD C,'/' - CALL ZCO - POP DE - LD A,D - CALL PRINT_BCD ;Month. Convert BCD to ASCII - LD C,'/' - CALL ZCO - POP DE - LD A,E - CALL PRINT_BCD ;Day. Convert BCD to ASCII - RET - - -UPD_IN_PR: ;Check we are ready to read clock - PUSH BC - LD BC,600 ;SET LOOP COUNT -UPDATE: - LD A,0AH ;ADDRESS OF [A] REGISTER - OUT (CMOS_PORT),A - NOP - NOP - NOP - IN A,(CMOS_PORT+1) ;READ IN REGISTER [A] - AND 80H ;IF 8XH--> UIP BIT IS ON (CANNOT READ TIME) - JP Z,UPD_IN_PREND ;Are we ready/done - DEC BC - LD A,C - OR B - JP NZ,UPDATE ;Try again - XOR A ; - SCF ;SET CARRY FOR ERROR - POP BC - RET -UPD_IN_PREND: - XOR A ;Clear Carry - POP BC - RET ;RETURN - -PORT_INC: - LD A,E - INC A ;INCREMENT ADDRESS - LD E,A - OUT (CMOS_PORT),A - RET - - -PORT_INC_2: - LD A,E - ADD A,2 ;INCREMENT ADDRESS - LD E,A - OUT (CMOS_PORT),A - RET - - -PRINT_BCD: ;Print BCD in [A] - PUSH AF - PUSH AF - RRA - RRA - RRA - RRA - AND 0FH - ADD A,30H - LD C,A ;Write high byte mins to CRT - CALL ZCO - POP AF - AND 0FH - ADD A,30H - LD C,A - CALL ZCO - POP AF - RET - -;>>>>>>>>>>>>>>>>>>>>>>>>> SPEECH OUTPUT ROUTINES <<<<<<<<<<<<<<<<<< -; -;SPEAK OUTPUT (WILL BE USED TO COMMUNICATE WITH TALKER) -; Note the S100Computers I/O board V-Stamp speech chip will use the initial baud rate -; of of the SCC to communicate with it. This is determines after each reset/slave clear. - -SPEAKER_CTS: ;Cannot get this to work. SCC does not change bit 5 of RR1 - ;when E1 sent to WR3 (No Auto Enable). See SCCINIT: - IN A,(BCTL) ;A0H - BIT 5,A - LD A,0FFH - RET NZ ;Ret NZ if CTS is High - XOR A - RET ;Ret Z if CTS is Low - -SPEAKOUT: - XOR A ;Will try 256 times, then timeout -SPXXX: - PUSH AF - IN A,(BCTL) ;(A0), Is SCC TX Buffer empty - AND 04H - JR NZ,SENDS ;NZ if ready to recieve character - POP AF - DEC A - JR NZ,SPXXX - RET -SENDS: - POP AF - LD A,C - OUT (BDTA),A ;(A2), Send it - RET -; -;SPEAKTOMM THIS IS A ROUTINE TO SEND A STRING TO TALKER [HL] AT STRING -SPEAK_: - LD A,(HL) - CP '$' - JR Z,SPEAK1 - LD C,A - CALL SPEAKOUT - INC HL - JR SPEAK_ -SPEAK1: - LD C,0DH ;MUST END WITH A CR - JP SPEAKOUT - - -;>>>>>>>>>>>>>>>>>> MODEM/SERIAL I/O <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -; Note the S100Computers I/O board will have the SSC set initially to 19,200 Baud -; -SERIAL_OUT: XOR A ;Will try 256 times, then timeout -MODXXX: PUSH AF - IN A,(ACTL) ;MODEM/SERIAL OUT - AND 04H ;Are we ready for a character - JR NZ,SENDM ;NZ if ready to recieve character - POP AF - DEC A - JR NZ,MODXXX - RET -SENDM: - POP AF - LD A,C - OUT (ADTA),A ;Send it - RET - -SERIAL_IN: - XOR A ;Will try 256 times, then timeout -SERIAL_INX: - PUSH AF - CALL SERIAL_STAT ;MODEM/SERIAL IN - JR NZ,GETMOD - POP AF - DEC A - JR NZ,SERIAL_INX - RET -GETMOD: - POP AF - IN A,(ADTA) - RET - -SERIAL_STAT:IN A,(ACTL) - AND 01H - RET Z ;Ret Z if nothing - LD A,0FFH -; XOR A ; <--- This is not correct, returns a Z condtion, need a NZ - RET ;Ret FF/NZ if something - - - -;PRINT MAIN MONITOR MENU ON CRT - -KCMD: - LD HL,MSG0 ;Signon Msg again (K Command) - CALL PRINT_STRING - LD HL,SMSG ;SPEECH MESSAGE - CALL SPEAK_ - LD HL,MENUMSG ;Then Menu Message - JP PRINT_STRING - -; -;THIS ROUTINE JUMPS OVER TO THE 8088, 8086 or 80286. Port SW86 raises S-100 PIN #55 -;THIS WILL CAUSE THE 8086/80286 BOARD TO BECOME ACTIVE AND TAKE OVER THE BUS. THE -;Z80 WILL BE IN A PERMANANT HOLD STATE UNTIL PIN #55 IS AGAIN LOWERED. - -SWITCH_8086: - LD HL,MSG14 - CALL PRINT_STRING - IN A,(SW86) ;THIS SWITCHES CPU'S with no block Move - NOP ;Z80 WILL BE HELD HERE - NOP - NOP - NOP - JP BEGIN ;WILL DROP BACK TO REBOOT MONITOR - - - -;THIS ROUTINE JUMPS OVER TO THE 68000 CPU Board. Port SW68K raises S-100 PIN #56 -;THIS WILL CAUSE THE 68000 CPU BOARD TO BECOME ACTIVE AND TAKE OVER THE BUS. THE -;Z80 WILL BE IN A PERMANANT HOLD STATE UNTIL PIN #56 IS AGAIN LOWERED. -SWITCH_68K: - LD HL,MSG68K - CALL PRINT_STRING - IN A,(SW68K) ;THIS SWITCHES CPU'S - NOP ;Z80 WILL BE HELD HERE - NOP - NOP - NOP - JP BEGIN ;WILL DROP BACK TO REBOOT MONITOR - -; -; -; -;THESE ARE ROUTINES NOT YET IMPLEMENTED -; -RI: ;READER -POO: ;PUNCH -PRDY: ;PUNCH STATUS (Sent to Serial port right now) -RSTAT: ;READER STATUS (Input from Serial port right now) -ONLIST: ;ON LIST -OFLIST: RET ;OFF LIST -TRAP: HALT -; -; -DRIVE_NR_ERR: .DB BELL,CR,LF - .TEXT "Drive not Ready." - .DB CR,LF,LF - .TEXT "$" -RESTORE_ERR: .DB BELL,CR,LF - .TEXT "Restore Failed." - .DB CR,LF,LF - .TEXT "$" -BOOT_LD_ERR: .DB BELL,CR,LF - .TEXT "Read Error." - .DB CR,LF,LF - .TEXT "$" -SEEK_ERROR_MSG: .DB BELL,CR,LF - .TEXT "Seek Error." - .DB CR,LF,LF - .TEXT "$" - -BOOT_LD1_ERR: .DB BELL,CR,LF - .TEXT "BOOT error." - .DB CR,LF,LF - .TEXT "$" -VF_HUNG: .TEXT "VF Controller Hung" - .DB CR,LF,LF - .TEXT "$" -BIOS_ERR: .TEXT "BIOS JMP not in ROM" - .DB CR,LF,LF - .TEXT "$" -BOOT_MSG0: .DB CR,LF - .TEXT "Loading CPM from $" -VF_MSG: .TEXT "VF FDC." - .DB CR,LF - .TEXT "$" -ZFDC_MSG: .TEXT "ZFDC FDC." - .DB CR,LF - .TEXT "$" - -MENUMSG: .DB CR,LF - .TEXT "A=Memmap B=68000 C=CP/M(Z) D=Disp E=Echo F=Fill G=Goto" - .DB CR,LF - .TEXT "H=Date I=Time J=Test K=Menu L=CPM(V) M=Move N=SeqMap" - .DB CR,LF - .TEXT "O=8086 P=CPM(IDE) Q=Port R=Ports S=Subs T=Type" - .DB CR,LF - .TEXT "V=Verify W=Port EDH X=DOS(H) Y=RomWBW Z=Top @=Flush Printer" - .DB CR,LF,LF - .TEXT "$" -; -MSG14: .DB BELL,CR,LF - .TEXT "8086/80286 Active" - .DB CR,LF,LF - .TEXT "$" -MSG68K: .DB BELL,CR,LF - .TEXT "68K Active" - .DB CR,LF,LF - .TEXT "$" -MSG17: .DB CR,LF - .TEXT "Segment (0-F):$" -TIME_MSG: .DB CR,LF - .TEXT "Time:- $" -DATE_MSG: .DB CR,LF - .TEXT "Date:- $" -GAP_MSG: .TEXT " $" - -IDE_RW_ERROR: .DB CR,LF - .TEXT "IDE Drive R/W Error" - .DB CR,LF - .TEXT "$" -SP_MSG .DB CR,LF - .TEXT "SP=$" -SPEAKCPM_MSG: .TEXT "LOADING CPM $" -SPEAKDOS_MSG: .TEXT "LOADING DOS $" -CR_SMSG: .DB CR,CR,CR,CR - .TEXT "$" -; - NOP - HALT - - - .END -;END diff --git a/branches/s100/Source/master-luke.asm b/branches/s100/Source/master-luke.asm deleted file mode 100644 index acc7ae76..00000000 --- a/branches/s100/Source/master-luke.asm +++ /dev/null @@ -1,1039 +0,0 @@ -; master-luke.asm 2/17/2013 dwg - doug's version derived from david's version -; Now includes BTROMWBW.INC (code to boot RomWBW style) Cmd "R" -; -; master-yoda.asm 2/17/2013 dwg - david's version unchanged -; -; monitor.asm This is main monitor program for my system -; -; - - -BELL .EQU 07H -SPACE .EQU 20H -TAB .EQU 09H -CR .EQU 0DH -LF .EQU 0AH -FF .EQU 0CH -ESC .EQU 1BH -DELETE .EQU 7FH - - -STARTCPM .EQU 100H ;LOCATION WHERE CPM WILL BE PLACED FOR COLD BOOT - -;---------PORT(S) TO SWITCH MASTER/SLAVE(S) - -Z80PORT .EQU 0D0H ;4 PORTS ON Z80 BOARD FOR MEMORY MANAGEMENT. - - -BCTL .EQU 0A0H ;CHANNEL B CONTROL PORT FOR SCC -ACTL .EQU 0A1H ;CHANNEL A CONTROL -BDTA .EQU 0A2H ;CHANNEL B DATA -ADTA .EQU 0A3H ;CHANNEL A DATA - -;-------------- S100Computers IDE HARD DISK CONTROLLER COMMANDS ETC. -IDEAport .EQU 030H ;lower 8 bits of IDE interface -IDEBport .EQU 031H ;upper 8 bits of IDE interface -IDECport .EQU 032H ;control lines for IDE interface -IDECtrl .EQU 033H ;8255 configuration port -IDEDrivePort .EQU 034H ;To select the 1st or 2nd CF card/drive (Not used with this monitor) - -IDE_Reset_Delay .EQU 020H ;Time delay for reset/initilization (~60 uS, with 10MHz Z80, 2 I/O wait states) - -CPM_ADDRESS .EQU 100H ;Will place the CPMLDR.COM Loader here with - ;CPMLDR.COM will ALWAYS be on TRK 0,SEC2, (LBA Mode) -SEC_COUNT .EQU 12 ;CPMLDR.COM requires (currently) 10, 512 byte sectors - ;Add extra just in case -RDcfg8255 .EQU 10010010B ;Set 8255 IDECport out, IDEAport/B input -WRcfg8255 .EQU 10000000B ;Set all three 8255 ports output -; -IDEa0line .EQU 01H ;direct from 8255 to IDE interface -IDEa1line .EQU 02H ;direct from 8255 to IDE interface -IDEa2line .EQU 04H ;direct from 8255 to IDE interface -IDEcs0line .EQU 08H ;inverter between 8255 and IDE interface -IDEcs1line .EQU 10H ;inverter between 8255 and IDE interface -IDEwrline .EQU 20H ;inverter between 8255 and IDE interface -IDErdline .EQU 40H ;inverter between 8255 and IDE interface -IDEreset .EQU 80H ;inverter between 8255 and IDE interface -; -;Symbolic constants for the IDE Drive registers, which makes the -;code more readable than always specifying the address pins -; -REGdata .EQU 08H ;IDEcs0line -REGerr .EQU 09H ;IDEcs0line + IDEa0line -REGcnt .EQU 0AH ;IDEcs0line + IDEa1line -REGsector .EQU 0BH ;IDEcs0line + IDEa1line + IDEa0line -REGcyLSB .EQU 0CH ;IDEcs0line + IDEa2line -REGcyMSB .EQU 0DH ;IDEcs0line + IDEa2line + IDEa0line -REGshd .EQU 0EH ;IDEcs0line + IDEa2line + IDEa1line ;(0EH) -REGCMD .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line ;(0FH) -REGstatus .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line -REGcontrol .EQU 16H ;IDEcs1line + IDEa2line + IDEa1line -REGastatus .EQU 17H ;IDEcs1line + IDEa2line + IDEa1line + IDEa0line - -;IDE CMD Constants. These should never change. -CMDrecal .EQU 10H -CMDread .EQU 20H -CMDwrite .EQU 30H -CMDinit .EQU 91H -CMDid .EQU 0ECH -CMDdownspin .EQU 0E0H -CMDupspin .EQU 0E1H -; -; IDE Status Register: -; bit 7: Busy 1=busy, 0=not busy -; bit 6: Ready 1=ready for CMD, 0=not ready yet -; bit 5: DF 1=fault occured insIDE drive -; bit 4: DSC 1=seek complete -; bit 3: DRQ 1=data request ready, 0=not ready to xfer yet -; bit 2: CORR 1=correctable error occured -; bit 1: IDX vendor specific -; bit 0: ERR 1=error occured -; - .ORG 0F000H - JP BEGIN - -TBL: - .DW NOTIMPL ; "@" - .DW MEMMAP ; "A" DISPLAY A MAP OF MEMORY - .DW NOTIMPL ; "B" - .DW NOTIMPL ; "C" - .DW DISP ; "D" DISPLAY MEMORY (IN HEX & ASCII) - .DW NOTIMPL ; "E" ECHO CHAR IN TO CHAR OUT - .DW FILL ; "F" FILL MEMORY WITH A CONSTANT - .DW GOTO ; "G" GO TO [ADDRESS] - .DW NOTIMPL ; "H" - .DW NOTIMPL ; "I" - .DW NOTIMPL ; "J" NON-DESTRUCTIVE MEMORY TEST - .DW NOTIMPL ; "K" - .DW NOTIMPL ; "L" - .DW NOTIMPL ; "M" - .DW XMEMMAP ; "N" DISPLAY EXTENDED MEMORY SEGEMENT:ADDRESS - .DW NOTIMPL ; "O" - .DW HBOOTCPM ; "P" BOOT IN CPM FROM IDE HARD DISK" - .DW QUERY ; "Q" QUERY PORT (IN OR OUT) - .DW HBOOTWBW ; "R" BOOT IN CPM FROM RomWBW HARD DISK - .DW SUBS ; "S" SUBSTITUTE &/OR EXAMINE MEMORY - .DW NOTIMPL ; "T" - .DW NOTIMPL ; "U" - .DW NOTIMPL ; "V" COMPARE MEMORY - .DW NOTIMPL ; "X" - .DW NOTIMPL ; "Y" - .DW NOTIMPL ; "Z" - - -SCCINIT: - .DB 04H ;Point to WR4 - .DB 44H ;X16 clock,1 Stop,NP -; - .DB 03H ;Point to WR3 - .DB 0C1H ;Enable reciever, Auto Enable, Recieve 8 bits -; .DB 0E1H ;Enable reciever, No Auto Enable, Recieve 8 bits (for CTS bit) -; - .DB 05H ;Point to WR5 - .DB 0EAH ;Enable, Transmit 8 bits -; ;Set RTS,DTR, Enable -; - .DB 0BH ;Point to WR11 - .DB 56H ;Recieve/transmit clock = BRG -; - .DB 0CH ;Point to WR12 -; .DB 40H ;Low Byte 2400 Baud -; .DB 1EH ;Low Byte 4800 Baud -; .DB 0EH ;Low Byte 9600 Baud - .DB 06H ;Low byte 19,200 Baud -; .DB 02H ;Low byte 38,400 Baud <<<<<<<<<<< -; .DB 00H ;Low byte 76,800 Baud -; - .DB 0DH ;Point to WR13 - .DB 00H ;High byte for Baud - - .DB 0EH ;Point to WR14 - .DB 01H ;Use 4.9152 MHz Clock. Note SD Systems uses a 2.4576 MHz clock, enable BRG -; - .DB 0FH ;Point to WR15 - .DB 00H ;Generate Int with CTS going high - .DB 00H - .DB 00H - .DB 00H - .DB 00H - .DB 00H - -; -; BEGIN OF CODE ----------------------------------------------------------------------- - -BEGIN: - LD A,0FFH - XOR A - OUT (Z80PORT+1),A - - LD A,0H - OUT (Z80PORT+2),A - LD A,04H - OUT (Z80PORT+3),A - - LD A,ACTL - LD C,A - LD B,$0E - LD HL,SCCINIT - OTIR - - LD A,BCTL - LD C,A - LD B,$0E - LD HL,SCCINIT - OTIR - -ZAXXLE: - LD SP,AHEAD-4 ;SETUP FAKE STACK FRAME - JP MEMSZ1 ;RETURNS WITH TOP OF RAM IN [HL] - .DW AHEAD ;RETURN WILL PICK UP THIS ADDRESS -AHEAD: - LD SP,HL ;[HL] CONTAINS TOP OF RAM - PUSH HL - POP IX ;SAVE STACK POINTER IN IX FOR FUTURE USE - - LD HL,MSG0 - CALL ZPMSG - - LD HL,SP_MSG ;PRINT CURRENT STACK LOCATION - CALL ZPMSG - - PUSH IX ;SP IS STORED HERE FROM ABOVE - POP HL - CALL HLSP ;PRINT HL/SP - CALL CRLF ;THEN CRLF - -START: - LD DE,START - PUSH DE ;EXTRA UNBALANCED POP & [DE] WOULD END UP IN [PC] - CALL CRLF - LD C,BELL ;A BELL HERE WILL SIGNAL WHEN JOBS ARE DONE - CALL CO - LD C,'-' - CALL CO - LD C,'>' - CALL CO - -STAR0: ;MAIN LOOP. MONITOR WILL STAY HERE UNTIL CMD. - CALL TI - AND 7FH - JR Z,STAR0 - SUB '@' ;COMMANDS @ TO Z ONLY - RET M - CP 1BH ;A-Z ONLY - RET NC - ADD A,A - LD HL,TBL - ADD A,L - LD L,A - LD A,(HL) - INC HL - LD H,(HL) - LD L,A - LD C,02H - JP (HL) ;JUMP TO COMMAND TABLE - - -MSG0: .DB "Z80 ROM MONITOR V1.0 (David Mehaffy 12/24/2011) $" -SP_MSG .DB CR,LF,"SP=$" - -ZPMSG: LD A,(HL) ;A ROUTINE TO PRINT OUT A STRING @ [HL] - INC HL ;UP TO THE FIRST '$' - CP '$' - RET Z - LD C,A - CALL CO - JR ZPMSG - -;THIS IS A CALLED ROUTINE USED TO CALCULATE TOP OF RAM IS USED BY -;THE ERROR TO RESET THE STACK. Returns top of RAM in [HL] - - -MEMSIZ: PUSH BC ;SAVE [BC] -MEMSZ1: LD HL,0FFFFH ;START FROM THE TOP DOWN -MEMSZ2: LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL ;PUT BACK WHAT WAS THERE - LD (HL),A - JP Z,GOTTOP - DEC H ;TRY 100H BYTES LOWER - JR MEMSZ2 ;KEEP LOOKING FOR RAM -GOTTOP: POP BC ;RESTORE [BC] - RET - - -;ABORT IF ESC AT CONSOL, PAUSE IF ^S AT CONSOL - -CCHK: CALL CSTS ;FIRST IS THERE ANYTHING THERE - RET Z - CALL CI - CP 'S'-40H - JR NZ,CCHK1 -CCHK2: CALL CSTS ;WAIT HERE UNTIL ANOTHER INPUT IS GIVEN - JR Z,CCHK2 -CCHK1: CP ESC - RET NZ ;RETURN EXECPT IF ESC - -;RESTORE SYSTEM AFTER ERROR - -ERROR: CALL MEMSIZ ;GET RAM AVAILABLE - WORKSPACE IN [HL] - LD SP,HL ;SET STACK UP IN WORKSPACE AREA - LD C,'*' - CALL CO - JP START - -;PRINT HIGHEST MEMORY FROM BOTTOM - -SIZE: - CALL MEMSIZ ;RETURNS WITH [HL]= RAM AVAILABLE-WORKSPACE - - -LFADR: CALL CRLF - -;PRINT [HL] AND A SPACE -HLSP: PUSH HL - PUSH BC - CALL LADR - LD C,SPACE - CALL CO - POP BC - POP HL - RET - -;PRINT A SPACE - -SF488: LD C,SPACE - JP CO - - -;CONVERT HEX TO ASCII - -CONV: - AND 0FH - ADD A,90H - DAA - ADC A,40H - DAA - LD C,A - RET - -;GET TWO PARAMETERS AND PUT THEM IN [HL] & [DE] THEN CRLF - -EXLF: CALL HEXSP - POP DE - POP HL - - -CRLF: - PUSH BC - LD C,LF - CALL CO - LD C,CR - CALL CO - POP BC - RET - -;PUT THREE PARAMETERS IN [BC] [DE] [HL] THEN CR/LF - -EXPR3: INC C ;ALREADY HAD [C]=2 FROM START - CALL HEXSP - CALL CRLF - POP BC - POP DE - POP HL - RET - -;GET ONE PARAMETER - -EXPR1: LD C,01H -HEXSP: LD HL,0000 -EX0: CALL TI -EX1: LD B,A - CALL NIBBLE - JR C,EX2X - ADD HL,HL - ADD HL,HL - ADD HL,HL - ADD HL,HL - OR L - LD L,A - JR EX0 -EX2X: EX (SP),HL - PUSH HL - LD A,B - CALL QCHK - JR NC,SF560 - DEC C - RET Z -SF560: JP NZ,ERROR - DEC C - JR NZ,HEXSP - RET -EXF: LD C,01H - LD HL,0000H - JR EX1 - -;RANGE TEST ROUTINE CARRY SET = RANGE EXCEEDED - -HILOX: CALL CCHK - CALL HILO - RET NC - POP DE ;DROP ONE LEVEL BACK TO START - RET -HILO: INC HL ;RANGE CHECK SET CARRY IF [DE]=[HL] - LD A,H - OR L - SCF - RET Z - LD A,E - SUB L - LD A,D - SBC A,H - RET - - -; PRINT [HL] ON CONSOLE - -LADR: LD A,H - CALL LBYTE - LD A,L -LBYTE: PUSH AF - RRCA - RRCA - RRCA - RRCA - CALL SF598 - POP AF -SF598: CALL CONV - JP CO - - -NIBBLE: SUB 30H - RET C - CP 17H - CCF - RET C - CP LF - CCF - RET NC - SUB 07H - CP LF - RET - -COPCK: LD C,'-' - CALL CO - -PCHK: CALL TI - -;TEST FOR DELIMITERS - -QCHK: CP SPACE - RET Z - CP ',' - RET Z - CP CR - SCF - RET Z - CCF - RET - -;KEYBOARD HANDLING ROUTINTE (WILL NOT ECHO CR/LF) -;IT CONVERTS LOWER CASE TO UPPERCASE FOR LOOKUP COMMANDS -;ALSO ^C WILL FOR A JUMP TO BOOT TO CP/M -;ALL OTHER CHARACTERS ARE ECHOED ON CONSOLE - -TI: - CALL CI - CP CR - RET Z - CP 'C' - 40H ;^C TO BOOT TO CP/M - JP Z,FBOOT - PUSH BC - LD C,A - CALL CO - LD A,C - POP BC - CP 40H ;LC-.UC - RET C - CP 7BH - RET NC -SF574: AND 5FH - RET - -BITS1: PUSH DE ;DISPLAY 8 BITS OF [A] - PUSH BC - LD E,A - CALL BITS - POP BC - POP DE - RET - -BITS: LD B,08H ;DISPLAY 8 BITS OF [E] - CALL SF488 -SF76E: SLA E - LD A,18H - ADC A,A - LD C,A - CALL CO - DJNZ SF76E - RET - -;<<<<<<<<<<<<<<<< MAIN CONSOLE ROUTINES <<<<<<<<<<<<< - -CO: - IN A,(ACTL) - AND 04H ;ARE WE READY FOR A CHARACTER - JR Z,CO - LD A,C - OUT (ADTA),A - RET - -CI: - IN A,(ACTL) - AND 01H - JR Z,CI - IN A,(ADTA) - RET - -CSTS: IN A,(ACTL) - AND 01H - RET Z ;RETURN Z IF NOTHING - LD A,0FFH - XOR A ;RETURN FF / NZ IF SOMETHING - RET - -;-------------- BOOT UP CPM FROM HARD DISK ON S100COMPUTERS IDR BOARD ---------------- - -;BOOT UP THE 8255/IDE Board HARD DISK/Flash Memory Card -;NOTE CODE IS ALL HERE IN CASE A 2716 IS USED - -HBOOTCPM: - POP HL ;CLEAN UP STACK - - CALL INITILIZE_IDE_BOARD ;Initilze the 8255 and drive (again just in case) - - LD D,11100000B ;Data for IDE SDH reg (512bytes, LBA mode,single drive) - LD E,REGshd ;00001110,(0EH) CS0,A2,A1, - CALL IDEwr8D ;Write byte to select the MASTER device - - LD B,0FFH ;Delay time to allow a Hard Disk to get up to speed -WaitInit: - LD E,REGstatus ;Get status after initilization - CALL IDErd8D ;Check Status (info in [D]) - BIT 7,D - JR Z,SECREAD ;Zero, so all is OK to write to drive - ;Delay to allow drive to get up to speed - PUSH BC - LD BC,0FFFFH -DXLAY2: LD D,2 ;May need to adjust delay time to allow cold drive to -DXLAY1: DEC D ;to speed - JR NZ,DXLAY1 - DEC BC - LD A,C - OR B - JR NZ,DXLAY2 - POP BC - DJNZ WaitInit ;If after 0FFH, 0FEH, 0FDH... 0, then drive initilization problem -IDError: - LD HL,DRIVE_NR_ERR ;Drive not ready - JP ABORT_ERR_MSG - -SECREAD: ;Note CPMLDR will ALWAYS be on TRK 0,SEC 1,Head 0 - CALL IDEwaitnotbusy ;Make sure drive is ready - JR C,IDError ;NC if ready - - LD D,1 ;Load track 0,sec 1, head 0 - LD E,REGsector ;Send info to drive - CALL IDEwr8D - - LD D,0 ;Send Low TRK# - LD E,REGcyLSB - CALL IDEwr8D - - LD D,0 ;Send High TRK# - LD E,REGcyMSB - CALL IDEwr8D - - LD D,SEC_COUNT ;Count of CPM sectors we wish to read - LD E,REGcnt - CALL IDEwr8D - - LD D,CMDread ;Send read CMD - LD E,REGCMD - CALL IDEwr8D ;Send sec read CMD to drive. - CALL IDEwdrq ;Wait until it's got the data - - LD HL,CPM_ADDRESS ;DMA address where the CPMLDR resides in RAM - LD B,0 ;256X2 bytes - LD C,SEC_COUNT ;Count of sectors X 512 -MoreRD16: - LD A,REGdata ;REG regsiter address - OUT (IDECport),A - - OR IDErdline ;08H+40H, Pulse RD line - OUT (IDECport),A - - IN A,(IDEAport) ;read the LOWER byte - LD (HL),A - INC HL - IN A,(IDEBport) ;read the UPPER byte - LD (HL),A - INC HL - - LD A,REGdata ;Deassert RD line - OUT (IDECport),A - DJNZ MoreRD16 - DEC C - JR NZ,MoreRD16 - - LD E,REGstatus ;Check the R/W status when done - CALL IDErd8D - BIT 0,D - JR NZ,IDEerr1 ;Z if no errors - LD HL,STARTCPM - LD A,(HL) - CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H - JP Z,STARTCPM ;AS THE FIRST INSTRUCTION. IF OK JP to 100H in RAM - JP ERR_LD1 ;Boot Sector Data incorrect - -IDEerr1: - LD HL,IDE_RW_ERROR ;Drive R/W Error - JP ABORT_ERR_MSG - - -; ----- SUPPORT ROUTINES -------------- - -INITILIZE_IDE_BOARD: ;Drive Select in [A]. Note leaves selected drive as [A] - LD A,RDcfg8255 ;Config 8255 chip (10010010B), read mode on return - OUT (IDECtrl),A ;Config 8255 chip, READ mode - - ;Hard reset the disk drive - ;For some reason some CF cards need to the RESET line - ;pulsed very carefully. You may need to play around - LD A,IDEreset ;with the pulse length. Symptoms are: incorrect data comming - OUT (IDECport),A ;back from a sector read (often due to the wrong sector being read) - ;I have a (negative)pulse of 60 uSec. (10Mz Z80, two IO wait states). - - LD C,IDE_Reset_Delay ;~60 uS seems to work for the 5 different CF cards I have -ResetDelay: - DEC C - JP NZ,ResetDelay ;Delay (reset pulse width) - XOR A - OUT (IDECport),A ;No IDE control lines asserted (just bit 7 of port C) - - CALL DELAY_15 ;Need to delay a little before checking busy status - -IDEwaitnotbusy: ;Drive READY if 01000000 - LD B,0FFH - LD C,080H ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreWait: - LD E,REGstatus ;Wait for RDY bit to be set - CALL IDErd8D - LD A,D - AND 11000000B - XOR 01000000B - JR Z,DoneNotBusy - DJNZ MoreWait - DEC C - JR NZ,MoreWait - SCF ;Set carry to indicate an error - RET -DoneNotBusy: - OR A ;Clear carry it indicate no error - RET - - - ;Wait for the drive to be ready to transfer data. -IDEwdrq: ;Returns the drive's status in Acc - LD B,0FFH - LD C,0FFH ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreDRQ: - LD E,REGstatus ;wait for DRQ bit to be set - CALL IDErd8D - LD A,D - AND 10001000B - CP 00001000B - JR Z,DoneDRQ - DJNZ MoreDRQ - DEC C - JR NZ,MoreDRQ - SCF ;Set carry to indicate error - RET -DoneDRQ: - OR A ;Clear carry - RET -; -;------------------------------------------------------------------ -; Low Level 8 bit R/W to the drive controller. These are the routines that talk -; directly to the drive controller registers, via the 8255 chip. -; Note the 16 bit I/O to the drive (which is only for SEC Read here) is done directly -; in the routine MoreRD16 for speed reasons. - -IDErd8D: ;READ 8 bits from IDE register in [E], return info in [D] - LD A,E - OUT (IDECport),A ;drive address onto control lines - - OR IDErdline ;RD pulse pin (40H) - OUT (IDECport),A ;assert read pin - - IN A,(IDEAport) - LD D,A ;return with data in [D] - - LD A,E ;<---Ken Robbins suggestion - OUT (IDECport),A ;Deassert RD pin - - XOR A - OUT (IDECport),A ;Zero all port C lines - RET - - -IDEwr8D: ;WRITE Data in [D] to IDE register in [E] - LD A,WRcfg8255 ;Set 8255 to write mode - OUT (IDECtrl),A - - LD A,D ;Get data put it in 8255 A port - OUT (IDEAport),A - - LD A,E ;select IDE register - OUT (IDECport),A - - OR IDEwrline ;lower WR line - OUT (IDECport),A - - LD A,E ;<-- Kens Robbins suggestion, raise WR line - OUT (IDECport),A - - XOR A ;Deselect all lines including WR line - OUT (IDECport),A - - LD A,RDcfg8255 ;Config 8255 chip, read mode on return - OUT (IDECtrl),A - RET - -ERR_NR: LD HL,DRIVE_NR_ERR ;"DRIVE NOT READY - JP ABORT_ERR_MSG -ERR_LD: LD HL,BOOT_LD_ERR ;"ERROR READING BOOT/LOADER SECTORS" - JP ABORT_ERR_MSG -ERR_LD1:LD HL,BOOT_LD1_ERR ;"DATA ERROR IN BOOT SECTOR" - -ABORT_ERR_MSG: - CALL ZPMSG - JP BEGIN ;BACK TO START OF MONITOR. - -DELAY_15: ;DELAY ~15 MS - LD A,40 -DELAY1: LD B,0 -M0: DJNZ M0 - DEC A - JR NZ,DELAY1 - RET - -#INCLUDE "BTROMWBW.INC" -;--------------------------------------------------------------- - -;MEMORY MAP PROGRAM CF.DR.DOBBS VOL 31 P40. -;IT WILL SHOW ON CONSOLE TOTAL MEMORY SUMMARY OF RAM, PROM, AND NO MEMORY - -MEMMAP: - CALL CRLF - LD HL,0 - LD B,1 -MAP1: LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A - JR NZ,MAP2 - CP (HL) - JR Z,PRINT -MAP2: LD E,'p' -MAP3: LD A,0FFH - CP (HL) - JR NZ,PRINT - INC L - XOR A - CP L - JR NZ,MAP3 - LD E,'.' -PRINT: LD L,0 - DEC B - JR NZ,NLINE - LD B,16 - CALL CRLF - CALL HXOT4 -NLINE: LD A,SPACE - CALL OTA - LD A,E - CALL OTA - INC H - JR NZ,MAP1 - CALL CRLF - CALL CRLF - JP START - -;16 HEX OUTPUT ROUTINE - -HXOT4: - LD C,H - CALL HXO2 - LD C,L -HXO2: LD A,C - RRA - RRA - RRA - RRA - CALL HXO3 - LD A,C -HXO3: AND 0FH - CP 10 - JR C,HADJ - ADD A,7 -HADJ: ADD A,30H -OTA: PUSH BC - LD C,A - CALL CO - POP BC - RET - -;DISPLAY MEMORY IN HEX - -DISP: CALL EXLF ;GET PARAMETERS IN [HL],[DE] - LD A,L ;ROUND OFF ADDRESSES TO XX00H - AND 0F0H - LD L,A - LD A,E ;FINAL ADDRESS LOWER HALF - AND 0F0H - ADD A,10H ;FINISH TO END 0F LINE -SF172: CALL LFADR -SF175: CALL BLANK - LD A,(HL) - CALL LBYTE - CALL HILOX - LD A,L - AND 0FH - JR NZ,SF175 - LD C,TAB ;INSERT A TAB BETWEEN DATA - CALL CO - LD B,4H ;ALSO 4 SPACES -TA11: LD C,SPACE - CALL CO - DJNZ TA11 - LD B,16 ;NOW PRINT ASCII (16 CHARACTERS) - PUSH DE ;TEMPORLY SAVE [DE] - LD DE,0010H - SBC HL,DE - POP DE -T11: LD A,(HL) - AND 7FH - CP ' ' ;FILTER OUT CONTROL CHARACTERS' - JR NC,T33 -T22: LD A,'.' -T33: CP 07CH - JR NC,T22 - LD C,A ;SET UP TO SEND - CALL CO - INC HL - DJNZ T11 ;REPEAT FOR WHOLE LINE - JR SF172 - -BLANK: LD C,' ' - JP CO - -;INSPECT AND / OR MODIFY MEMORY - -SUBS: LD C,1 - CALL HEXSP - POP HL -SF2E3: LD A,(HL) - CALL LBYTE - LD C,'-' - CALL CO - CALL PCHK - RET C - JR Z,SF2FC - CP 5FH - JR Z,SF305 - PUSH HL - CALL EXF - POP DE - POP HL - LD (HL),E - LD A,B - CP CR - RET Z -SF2FC: INC HL -SF2FD: LD A,L - AND 07H - CALL Z,LFADR - JR SF2E3 -SF305: DEC HL - JR SF2FD - -;FILL A BLOCK OF MEMORY WITH A VALUE - -FILL: CALL EXPR3 -SF1A5: LD (HL),C - CALL HILOX - JR NC,SF1A5 - POP DE - JP START - -;GO TO A RAM LOCATION - -GOTO: LD C,1 ;SIMPLE GOTO FIRST GET PARMS. - CALL HEXSP - CALL CRLF - POP HL ;GET PARAMETER PUSHED BY EXF - JP (HL) - - -; GET OR OUTPUT TO A PORT - -QUERY: CALL PCHK - CP 'O' ;OUTPUT TO PORT - JR Z,SF77A - CP 'I' ;INPUT FROM PORT - JP Z,QQQ1 - LD C,'*' - JP CO ;WILL ABORT IF NOT 'I' OR 'O' -QQQ1: LD C,1 - CALL HEXSP - POP BC - IN A,(C) - JP BITS -; -SF77A: CALL HEXSP - POP DE - POP BC - OUT (C),E - RET - -;Display Extended memory map for 1MG RAM using IA-2 Z80 Board window registers - -XMEMMAP: - LD HL,MSG17 ;Get segment (0-F) - CALL ZPMSG - LD C,1 - CALL HEXSP ;Get 2 or 4 hex digits (count in C). - POP HL - LD A,L ;Get single byte value - AND 0FH - EXX - LD D,A ;Store in D' for 000X:YYYY display below - SLA A - SLA A - SLA A - SLA A - OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space - LD E,A ;store shifted nibble in E' - LD HL,0 ;Will store 0-FFFF for total RAM display (not actual access) - EXX - LD D,0 ;Total display line count (256 characters, 16lines X 16 characters) - - CALL CRLF - LD HL,0 - LD B,1 -XMAP1: LD A,H - AND 00111111B ;Wrap 16K window - LD H,A - LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A ;Save it back - JR NZ,XMAP2 - CP (HL) - JR Z,XPRINT -XMAP2: LD E,'p' -XMAP3: LD A,0FFH - CP (HL) - JR NZ,XPRINT - INC L - XOR A - CP L - JR NZ,XMAP3 - LD E,'.' -XPRINT: LD L,0 - DEC B - JR NZ,XNLINE - LD B,16 - CALL CRLF - CALL SET_WINDOW - LD A,SPACE - JR XN11 -XNLINE: LD A,SPACE - CALL OTA - LD A,E -XN11: CALL OTA - INC H - INC D ;Are we done yet - JR NZ,XMAP1 - CALL CRLF - XOR A - OUT (Z80PORT+2),A ;Set RAM window back to the way it was - JP START - -SET_WINDOW: ;Setup the unique IA-II Z80 board window to address > 64k - EXX - LD C,D ;Print seg value - CALL HXO2 - LD C,':' - CALL CO - CALL HXOT4 ;Print HL' (not origional HL) - - LD A,H ;get current H being displayed (Already pointed to first 16K window) -NOTW0: CP 40H - JR NZ,NOTW1 - LD A,E - ADD A,04H ;Window for 4,5,6,7, set to H from above - JR DOWIN -NOTW1: CP 80H - JR NZ,NOTW2 - LD A,E - ADD A,08H ;Window for 8,9,A,B set to H from above - JR DOWIN -NOTW2: CP 0C0H - JR NZ,NOTW3 ;Must be values in between - LD A,E - ADD A,0CH ;Window for 4,5,6,7, set to H from above -DOWIN: OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space -NOTW3: LD A,H - ADD A,10H - LD H,A - EXX ;Get back normal register set - RET - - - - -NOTIMPL: - RET - -FBOOT: - RET - -DRIVE_NR_ERR: .DB BELL,CR,LF - .DB "Drive not Ready.",CR,LF,LF,'$' -RESTORE_ERR: .DB BELL,CR,LF - .DB "Restore Failed.",CR,LF,LF,'$' -BOOT_LD_ERR: .DB BELL,CR,LF - .DB "Read Error.",CR,LF,LF,'$' -SEEK_ERROR_MSG: .DB BELL,CR,LF - .DB "Seek Error.",CR,LF,LF,'$' - -BOOT_LD1_ERR: .DB BELL,CR,LF - .DB "BOOT error.",CR,LF,LF,'$' - -IDE_RW_ERROR: .DB CR,LF - .DB "IDE Drive R/W Error" - .DB CR,LF,'$' - -MSG17: .DB CR,LF - .DB "Segement (0-F):$" - .END diff --git a/branches/s100/Source/master-yoda.asm b/branches/s100/Source/master-yoda.asm deleted file mode 100644 index 982cd1c7..00000000 --- a/branches/s100/Source/master-yoda.asm +++ /dev/null @@ -1,1035 +0,0 @@ -; -; monitor.asm This is main monitor program for my system -; -; - - -BELL .EQU 07H -SPACE .EQU 20H -TAB .EQU 09H -CR .EQU 0DH -LF .EQU 0AH -FF .EQU 0CH -ESC .EQU 1BH -DELETE .EQU 7FH - - -STARTCPM .EQU 100H ;LOCATION WHERE CPM WILL BE PLACED FOR COLD BOOT - -;---------PORT(S) TO SWITCH MASTER/SLAVE(S) - -Z80PORT .EQU 0D0H ;4 PORTS ON Z80 BOARD FOR MEMORY MANAGEMENT. - - -BCTL .EQU 0A0H ;CHANNEL B CONTROL PORT FOR SCC -ACTL .EQU 0A1H ;CHANNEL A CONTROL -BDTA .EQU 0A2H ;CHANNEL B DATA -ADTA .EQU 0A3H ;CHANNEL A DATA - -;-------------- S100Computers IDE HARD DISK CONTROLLER COMMANDS ETC. -IDEAport .EQU 030H ;lower 8 bits of IDE interface -IDEBport .EQU 031H ;upper 8 bits of IDE interface -IDECport .EQU 032H ;control lines for IDE interface -IDECtrl .EQU 033H ;8255 configuration port -IDEDrivePort .EQU 034H ;To select the 1st or 2nd CF card/drive (Not used with this monitor) - -IDE_Reset_Delay .EQU 020H ;Time delay for reset/initilization (~60 uS, with 10MHz Z80, 2 I/O wait states) - -CPM_ADDRESS .EQU 100H ;Will place the CPMLDR.COM Loader here with - ;CPMLDR.COM will ALWAYS be on TRK 0,SEC2, (LBA Mode) -SEC_COUNT .EQU 12 ;CPMLDR.COM requires (currently) 10, 512 byte sectors - ;Add extra just in case -RDcfg8255 .EQU 10010010B ;Set 8255 IDECport out, IDEAport/B input -WRcfg8255 .EQU 10000000B ;Set all three 8255 ports output -; -IDEa0line .EQU 01H ;direct from 8255 to IDE interface -IDEa1line .EQU 02H ;direct from 8255 to IDE interface -IDEa2line .EQU 04H ;direct from 8255 to IDE interface -IDEcs0line .EQU 08H ;inverter between 8255 and IDE interface -IDEcs1line .EQU 10H ;inverter between 8255 and IDE interface -IDEwrline .EQU 20H ;inverter between 8255 and IDE interface -IDErdline .EQU 40H ;inverter between 8255 and IDE interface -IDEreset .EQU 80H ;inverter between 8255 and IDE interface -; -;Symbolic constants for the IDE Drive registers, which makes the -;code more readable than always specifying the address pins -; -REGdata .EQU 08H ;IDEcs0line -REGerr .EQU 09H ;IDEcs0line + IDEa0line -REGcnt .EQU 0AH ;IDEcs0line + IDEa1line -REGsector .EQU 0BH ;IDEcs0line + IDEa1line + IDEa0line -REGcyLSB .EQU 0CH ;IDEcs0line + IDEa2line -REGcyMSB .EQU 0DH ;IDEcs0line + IDEa2line + IDEa0line -REGshd .EQU 0EH ;IDEcs0line + IDEa2line + IDEa1line ;(0EH) -REGCMD .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line ;(0FH) -REGstatus .EQU 0FH ;IDEcs0line + IDEa2line + IDEa1line + IDEa0line -REGcontrol .EQU 16H ;IDEcs1line + IDEa2line + IDEa1line -REGastatus .EQU 17H ;IDEcs1line + IDEa2line + IDEa1line + IDEa0line - -;IDE CMD Constants. These should never change. -CMDrecal .EQU 10H -CMDread .EQU 20H -CMDwrite .EQU 30H -CMDinit .EQU 91H -CMDid .EQU 0ECH -CMDdownspin .EQU 0E0H -CMDupspin .EQU 0E1H -; -; IDE Status Register: -; bit 7: Busy 1=busy, 0=not busy -; bit 6: Ready 1=ready for CMD, 0=not ready yet -; bit 5: DF 1=fault occured insIDE drive -; bit 4: DSC 1=seek complete -; bit 3: DRQ 1=data request ready, 0=not ready to xfer yet -; bit 2: CORR 1=correctable error occured -; bit 1: IDX vendor specific -; bit 0: ERR 1=error occured -; - .ORG 0F000H - JP BEGIN - -TBL: - .DW NOTIMPL ; "@" - .DW MEMMAP ; "A" DISPLAY A MAP OF MEMORY - .DW NOTIMPL ; "B" - .DW NOTIMPL ; "C" - .DW DISP ; "D" DISPLAY MEMORY (IN HEX & ASCII) - .DW NOTIMPL ; "E" ECHO CHAR IN TO CHAR OUT - .DW FILL ; "F" FILL MEMORY WITH A CONSTANT - .DW GOTO ; "G" GO TO [ADDRESS] - .DW NOTIMPL ; "H" - .DW NOTIMPL ; "I" - .DW NOTIMPL ; "J" NON-DESTRUCTIVE MEMORY TEST - .DW NOTIMPL ; "K" - .DW NOTIMPL ; "L" - .DW NOTIMPL ; "M" - .DW XMEMMAP ; "N" DISPLAY EXTENDED MEMORY SEGEMENT:ADDRESS - .DW NOTIMPL ; "O" - .DW HBOOTCPM ; "P BOOT IN CPM FROM IDE HARD DISK" - .DW QUERY ; "Q" QUERY PORT (IN OR OUT) - .DW NOTIMPL ; "R" - .DW SUBS ; "S" SUBSTITUTE &/OR EXAMINE MEMORY - .DW NOTIMPL ; "T" - .DW NOTIMPL ; "U" - .DW NOTIMPL ; "V" COMPARE MEMORY - .DW NOTIMPL ; "X" - .DW NOTIMPL ; "Y" - .DW NOTIMPL ; "Z" - - -SCCINIT: - .DB 04H ;Point to WR4 - .DB 44H ;X16 clock,1 Stop,NP -; - .DB 03H ;Point to WR3 - .DB 0C1H ;Enable reciever, Auto Enable, Recieve 8 bits -; .DB 0E1H ;Enable reciever, No Auto Enable, Recieve 8 bits (for CTS bit) -; - .DB 05H ;Point to WR5 - .DB 0EAH ;Enable, Transmit 8 bits -; ;Set RTS,DTR, Enable -; - .DB 0BH ;Point to WR11 - .DB 56H ;Recieve/transmit clock = BRG -; - .DB 0CH ;Point to WR12 -; .DB 40H ;Low Byte 2400 Baud -; .DB 1EH ;Low Byte 4800 Baud -; .DB 0EH ;Low Byte 9600 Baud - .DB 06H ;Low byte 19,200 Baud -; .DB 02H ;Low byte 38,400 Baud <<<<<<<<<<< -; .DB 00H ;Low byte 76,800 Baud -; - .DB 0DH ;Point to WR13 - .DB 00H ;High byte for Baud - - .DB 0EH ;Point to WR14 - .DB 01H ;Use 4.9152 MHz Clock. Note SD Systems uses a 2.4576 MHz clock, enable BRG -; - .DB 0FH ;Point to WR15 - .DB 00H ;Generate Int with CTS going high - .DB 00H - .DB 00H - .DB 00H - .DB 00H - .DB 00H - -; -; BEGIN OF CODE ----------------------------------------------------------------------- - -BEGIN: - LD A,0FFH - XOR A - OUT (Z80PORT+1),A - - LD A,0H - OUT (Z80PORT+2),A - LD A,04H - OUT (Z80PORT+3),A - - LD A,ACTL - LD C,A - LD B,$0E - LD HL,SCCINIT - OTIR - - LD A,BCTL - LD C,A - LD B,$0E - LD HL,SCCINIT - OTIR - -ZAXXLE: - LD SP,AHEAD-4 ;SETUP FAKE STACK FRAME - JP MEMSZ1 ;RETURNS WITH TOP OF RAM IN [HL] - .DW AHEAD ;RETURN WILL PICK UP THIS ADDRESS -AHEAD: - LD SP,HL ;[HL] CONTAINS TOP OF RAM - PUSH HL - POP IX ;SAVE STACK POINTER IN IX FOR FUTURE USE - - LD HL,MSG0 - CALL ZPMSG - - LD HL,SP_MSG ;PRINT CURRENT STACK LOCATION - CALL ZPMSG - - PUSH IX ;SP IS STORED HERE FROM ABOVE - POP HL - CALL HLSP ;PRINT HL/SP - CALL CRLF ;THEN CRLF - -START: - LD DE,START - PUSH DE ;EXTRA UNBALANCED POP & [DE] WOULD END UP IN [PC] - CALL CRLF - LD C,BELL ;A BELL HERE WILL SIGNAL WHEN JOBS ARE DONE - CALL CO - LD C,'-' - CALL CO - LD C,'>' - CALL CO - -STAR0: ;MAIN LOOP. MONITOR WILL STAY HERE UNTIL CMD. - CALL TI - AND 7FH - JR Z,STAR0 - SUB '@' ;COMMANDS @ TO Z ONLY - RET M - CP 1BH ;A-Z ONLY - RET NC - ADD A,A - LD HL,TBL - ADD A,L - LD L,A - LD A,(HL) - INC HL - LD H,(HL) - LD L,A - LD C,02H - JP (HL) ;JUMP TO COMMAND TABLE - - -MSG0: .DB "Z80 ROM MONITOR V1.0 (David Mehaffy 12/24/2011) $" -SP_MSG .DB CR,LF,"SP=$" - -ZPMSG: LD A,(HL) ;A ROUTINE TO PRINT OUT A STRING @ [HL] - INC HL ;UP TO THE FIRST '$' - CP '$' - RET Z - LD C,A - CALL CO - JR ZPMSG - -;THIS IS A CALLED ROUTINE USED TO CALCULATE TOP OF RAM IS USED BY -;THE ERROR TO RESET THE STACK. Returns top of RAM in [HL] - - -MEMSIZ: PUSH BC ;SAVE [BC] -MEMSZ1: LD HL,0FFFFH ;START FROM THE TOP DOWN -MEMSZ2: LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL ;PUT BACK WHAT WAS THERE - LD (HL),A - JP Z,GOTTOP - DEC H ;TRY 100H BYTES LOWER - JR MEMSZ2 ;KEEP LOOKING FOR RAM -GOTTOP: POP BC ;RESTORE [BC] - RET - - -;ABORT IF ESC AT CONSOL, PAUSE IF ^S AT CONSOL - -CCHK: CALL CSTS ;FIRST IS THERE ANYTHING THERE - RET Z - CALL CI - CP 'S'-40H - JR NZ,CCHK1 -CCHK2: CALL CSTS ;WAIT HERE UNTIL ANOTHER INPUT IS GIVEN - JR Z,CCHK2 -CCHK1: CP ESC - RET NZ ;RETURN EXECPT IF ESC - -;RESTORE SYSTEM AFTER ERROR - -ERROR: CALL MEMSIZ ;GET RAM AVAILABLE - WORKSPACE IN [HL] - LD SP,HL ;SET STACK UP IN WORKSPACE AREA - LD C,'*' - CALL CO - JP START - -;PRINT HIGHEST MEMORY FROM BOTTOM - -SIZE: - CALL MEMSIZ ;RETURNS WITH [HL]= RAM AVAILABLE-WORKSPACE - - -LFADR: CALL CRLF - -;PRINT [HL] AND A SPACE -HLSP: PUSH HL - PUSH BC - CALL LADR - LD C,SPACE - CALL CO - POP BC - POP HL - RET - -;PRINT A SPACE - -SF488: LD C,SPACE - JP CO - - -;CONVERT HEX TO ASCII - -CONV: - AND 0FH - ADD A,90H - DAA - ADC A,40H - DAA - LD C,A - RET - -;GET TWO PARAMETERS AND PUT THEM IN [HL] & [DE] THEN CRLF - -EXLF: CALL HEXSP - POP DE - POP HL - - -CRLF: - PUSH BC - LD C,LF - CALL CO - LD C,CR - CALL CO - POP BC - RET - -;PUT THREE PARAMETERS IN [BC] [DE] [HL] THEN CR/LF - -EXPR3: INC C ;ALREADY HAD [C]=2 FROM START - CALL HEXSP - CALL CRLF - POP BC - POP DE - POP HL - RET - -;GET ONE PARAMETER - -EXPR1: LD C,01H -HEXSP: LD HL,0000 -EX0: CALL TI -EX1: LD B,A - CALL NIBBLE - JR C,EX2X - ADD HL,HL - ADD HL,HL - ADD HL,HL - ADD HL,HL - OR L - LD L,A - JR EX0 -EX2X: EX (SP),HL - PUSH HL - LD A,B - CALL QCHK - JR NC,SF560 - DEC C - RET Z -SF560: JP NZ,ERROR - DEC C - JR NZ,HEXSP - RET -EXF: LD C,01H - LD HL,0000H - JR EX1 - -;RANGE TEST ROUTINE CARRY SET = RANGE EXCEEDED - -HILOX: CALL CCHK - CALL HILO - RET NC - POP DE ;DROP ONE LEVEL BACK TO START - RET -HILO: INC HL ;RANGE CHECK SET CARRY IF [DE]=[HL] - LD A,H - OR L - SCF - RET Z - LD A,E - SUB L - LD A,D - SBC A,H - RET - - -; PRINT [HL] ON CONSOLE - -LADR: LD A,H - CALL LBYTE - LD A,L -LBYTE: PUSH AF - RRCA - RRCA - RRCA - RRCA - CALL SF598 - POP AF -SF598: CALL CONV - JP CO - - -NIBBLE: SUB 30H - RET C - CP 17H - CCF - RET C - CP LF - CCF - RET NC - SUB 07H - CP LF - RET - -COPCK: LD C,'-' - CALL CO - -PCHK: CALL TI - -;TEST FOR DELIMITERS - -QCHK: CP SPACE - RET Z - CP ',' - RET Z - CP CR - SCF - RET Z - CCF - RET - -;KEYBOARD HANDLING ROUTINTE (WILL NOT ECHO CR/LF) -;IT CONVERTS LOWER CASE TO UPPERCASE FOR LOOKUP COMMANDS -;ALSO ^C WILL FOR A JUMP TO BOOT TO CP/M -;ALL OTHER CHARACTERS ARE ECHOED ON CONSOLE - -TI: - CALL CI - CP CR - RET Z - CP 'C' - 40H ;^C TO BOOT TO CP/M - JP Z,FBOOT - PUSH BC - LD C,A - CALL CO - LD A,C - POP BC - CP 40H ;LC-.UC - RET C - CP 7BH - RET NC -SF574: AND 5FH - RET - -BITS1: PUSH DE ;DISPLAY 8 BITS OF [A] - PUSH BC - LD E,A - CALL BITS - POP BC - POP DE - RET - -BITS: LD B,08H ;DISPLAY 8 BITS OF [E] - CALL SF488 -SF76E: SLA E - LD A,18H - ADC A,A - LD C,A - CALL CO - DJNZ SF76E - RET - -;<<<<<<<<<<<<<<<< MAIN CONSOLE ROUTINES <<<<<<<<<<<<< - -CO: - IN A,(ACTL) - AND 04H ;ARE WE READY FOR A CHARACTER - JR Z,CO - LD A,C - OUT (ADTA),A - RET - -CI: - IN A,(ACTL) - AND 01H - JR Z,CI - IN A,(ADTA) - RET - -CSTS: IN A,(ACTL) - AND 01H - RET Z ;RETURN Z IF NOTHING - LD A,0FFH - XOR A ;RETURN FF / NZ IF SOMETHING - RET - -;-------------- BOOT UP CPM FROM HARD DISK ON S100COMPUTERS IDR BOARD ---------------- - -;BOOT UP THE 8255/IDE Board HARD DISK/Flash Memory Card -;NOTE CODE IS ALL HERE IN CASE A 2716 IS USED - -HBOOTCPM: - POP HL ;CLEAN UP STACK - - CALL INITILIZE_IDE_BOARD ;Initilze the 8255 and drive (again just in case) - - LD D,11100000B ;Data for IDE SDH reg (512bytes, LBA mode,single drive) - LD E,REGshd ;00001110,(0EH) CS0,A2,A1, - CALL IDEwr8D ;Write byte to select the MASTER device - - LD B,0FFH ;Delay time to allow a Hard Disk to get up to speed -WaitInit: - LD E,REGstatus ;Get status after initilization - CALL IDErd8D ;Check Status (info in [D]) - BIT 7,D - JR Z,SECREAD ;Zero, so all is OK to write to drive - ;Delay to allow drive to get up to speed - PUSH BC - LD BC,0FFFFH -DXLAY2: LD D,2 ;May need to adjust delay time to allow cold drive to -DXLAY1: DEC D ;to speed - JR NZ,DXLAY1 - DEC BC - LD A,C - OR B - JR NZ,DXLAY2 - POP BC - DJNZ WaitInit ;If after 0FFH, 0FEH, 0FDH... 0, then drive initilization problem -IDError: - LD HL,DRIVE_NR_ERR ;Drive not ready - JP ABORT_ERR_MSG - -SECREAD: ;Note CPMLDR will ALWAYS be on TRK 0,SEC 1,Head 0 - CALL IDEwaitnotbusy ;Make sure drive is ready - JR C,IDError ;NC if ready - - LD D,1 ;Load track 0,sec 1, head 0 - LD E,REGsector ;Send info to drive - CALL IDEwr8D - - LD D,0 ;Send Low TRK# - LD E,REGcyLSB - CALL IDEwr8D - - LD D,0 ;Send High TRK# - LD E,REGcyMSB - CALL IDEwr8D - - LD D,SEC_COUNT ;Count of CPM sectors we wish to read - LD E,REGcnt - CALL IDEwr8D - - LD D,CMDread ;Send read CMD - LD E,REGCMD - CALL IDEwr8D ;Send sec read CMD to drive. - CALL IDEwdrq ;Wait until it's got the data - - LD HL,CPM_ADDRESS ;DMA address where the CPMLDR resides in RAM - LD B,0 ;256X2 bytes - LD C,SEC_COUNT ;Count of sectors X 512 -MoreRD16: - LD A,REGdata ;REG regsiter address - OUT (IDECport),A - - OR IDErdline ;08H+40H, Pulse RD line - OUT (IDECport),A - - IN A,(IDEAport) ;read the LOWER byte - LD (HL),A - INC HL - IN A,(IDEBport) ;read the UPPER byte - LD (HL),A - INC HL - - LD A,REGdata ;Deassert RD line - OUT (IDECport),A - DJNZ MoreRD16 - DEC C - JR NZ,MoreRD16 - - LD E,REGstatus ;Check the R/W status when done - CALL IDErd8D - BIT 0,D - JR NZ,IDEerr1 ;Z if no errors - LD HL,STARTCPM - LD A,(HL) - CP 31H ;EXPECT TO HAVE 31H @80H IE. LD SP,80H - JP Z,STARTCPM ;AS THE FIRST INSTRUCTION. IF OK JP to 100H in RAM - JP ERR_LD1 ;Boot Sector Data incorrect - -IDEerr1: - LD HL,IDE_RW_ERROR ;Drive R/W Error - JP ABORT_ERR_MSG - - -; ----- SUPPORT ROUTINES -------------- - -INITILIZE_IDE_BOARD: ;Drive Select in [A]. Note leaves selected drive as [A] - LD A,RDcfg8255 ;Config 8255 chip (10010010B), read mode on return - OUT (IDECtrl),A ;Config 8255 chip, READ mode - - ;Hard reset the disk drive - ;For some reason some CF cards need to the RESET line - ;pulsed very carefully. You may need to play around - LD A,IDEreset ;with the pulse length. Symptoms are: incorrect data comming - OUT (IDECport),A ;back from a sector read (often due to the wrong sector being read) - ;I have a (negative)pulse of 60 uSec. (10Mz Z80, two IO wait states). - - LD C,IDE_Reset_Delay ;~60 uS seems to work for the 5 different CF cards I have -ResetDelay: - DEC C - JP NZ,ResetDelay ;Delay (reset pulse width) - XOR A - OUT (IDECport),A ;No IDE control lines asserted (just bit 7 of port C) - - CALL DELAY_15 ;Need to delay a little before checking busy status - -IDEwaitnotbusy: ;Drive READY if 01000000 - LD B,0FFH - LD C,080H ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreWait: - LD E,REGstatus ;Wait for RDY bit to be set - CALL IDErd8D - LD A,D - AND 11000000B - XOR 01000000B - JR Z,DoneNotBusy - DJNZ MoreWait - DEC C - JR NZ,MoreWait - SCF ;Set carry to indicate an error - RET -DoneNotBusy: - OR A ;Clear carry it indicate no error - RET - - - ;Wait for the drive to be ready to transfer data. -IDEwdrq: ;Returns the drive's status in Acc - LD B,0FFH - LD C,0FFH ;Delay, must be above 80H for 4MHz Z80. Leave longer for slower drives -MoreDRQ: - LD E,REGstatus ;wait for DRQ bit to be set - CALL IDErd8D - LD A,D - AND 10001000B - CP 00001000B - JR Z,DoneDRQ - DJNZ MoreDRQ - DEC C - JR NZ,MoreDRQ - SCF ;Set carry to indicate error - RET -DoneDRQ: - OR A ;Clear carry - RET -; -;------------------------------------------------------------------ -; Low Level 8 bit R/W to the drive controller. These are the routines that talk -; directly to the drive controller registers, via the 8255 chip. -; Note the 16 bit I/O to the drive (which is only for SEC Read here) is done directly -; in the routine MoreRD16 for speed reasons. - -IDErd8D: ;READ 8 bits from IDE register in [E], return info in [D] - LD A,E - OUT (IDECport),A ;drive address onto control lines - - OR IDErdline ;RD pulse pin (40H) - OUT (IDECport),A ;assert read pin - - IN A,(IDEAport) - LD D,A ;return with data in [D] - - LD A,E ;<---Ken Robbins suggestion - OUT (IDECport),A ;Deassert RD pin - - XOR A - OUT (IDECport),A ;Zero all port C lines - RET - - -IDEwr8D: ;WRITE Data in [D] to IDE register in [E] - LD A,WRcfg8255 ;Set 8255 to write mode - OUT (IDECtrl),A - - LD A,D ;Get data put it in 8255 A port - OUT (IDEAport),A - - LD A,E ;select IDE register - OUT (IDECport),A - - OR IDEwrline ;lower WR line - OUT (IDECport),A - - LD A,E ;<-- Kens Robbins suggestion, raise WR line - OUT (IDECport),A - - XOR A ;Deselect all lines including WR line - OUT (IDECport),A - - LD A,RDcfg8255 ;Config 8255 chip, read mode on return - OUT (IDECtrl),A - RET - -ERR_NR: LD HL,DRIVE_NR_ERR ;"DRIVE NOT READY - JP ABORT_ERR_MSG -ERR_LD: LD HL,BOOT_LD_ERR ;"ERROR READING BOOT/LOADER SECTORS" - JP ABORT_ERR_MSG -ERR_LD1:LD HL,BOOT_LD1_ERR ;"DATA ERROR IN BOOT SECTOR" - -ABORT_ERR_MSG: - CALL ZPMSG - JP BEGIN ;BACK TO START OF MONITOR. - -DELAY_15: ;DELAY ~15 MS - LD A,40 -DELAY1: LD B,0 -M0: DJNZ M0 - DEC A - JR NZ,DELAY1 - RET - - -;--------------------------------------------------------------- - -;MEMORY MAP PROGRAM CF.DR.DOBBS VOL 31 P40. -;IT WILL SHOW ON CONSOLE TOTAL MEMORY SUMMARY OF RAM, PROM, AND NO MEMORY - -MEMMAP: - CALL CRLF - LD HL,0 - LD B,1 -MAP1: LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A - JR NZ,MAP2 - CP (HL) - JR Z,PRINT -MAP2: LD E,'p' -MAP3: LD A,0FFH - CP (HL) - JR NZ,PRINT - INC L - XOR A - CP L - JR NZ,MAP3 - LD E,'.' -PRINT: LD L,0 - DEC B - JR NZ,NLINE - LD B,16 - CALL CRLF - CALL HXOT4 -NLINE: LD A,SPACE - CALL OTA - LD A,E - CALL OTA - INC H - JR NZ,MAP1 - CALL CRLF - CALL CRLF - JP START - -;16 HEX OUTPUT ROUTINE - -HXOT4: - LD C,H - CALL HXO2 - LD C,L -HXO2: LD A,C - RRA - RRA - RRA - RRA - CALL HXO3 - LD A,C -HXO3: AND 0FH - CP 10 - JR C,HADJ - ADD A,7 -HADJ: ADD A,30H -OTA: PUSH BC - LD C,A - CALL CO - POP BC - RET - -;DISPLAY MEMORY IN HEX - -DISP: CALL EXLF ;GET PARAMETERS IN [HL],[DE] - LD A,L ;ROUND OFF ADDRESSES TO XX00H - AND 0F0H - LD L,A - LD A,E ;FINAL ADDRESS LOWER HALF - AND 0F0H - ADD A,10H ;FINISH TO END 0F LINE -SF172: CALL LFADR -SF175: CALL BLANK - LD A,(HL) - CALL LBYTE - CALL HILOX - LD A,L - AND 0FH - JR NZ,SF175 - LD C,TAB ;INSERT A TAB BETWEEN DATA - CALL CO - LD B,4H ;ALSO 4 SPACES -TA11: LD C,SPACE - CALL CO - DJNZ TA11 - LD B,16 ;NOW PRINT ASCII (16 CHARACTERS) - PUSH DE ;TEMPORLY SAVE [DE] - LD DE,0010H - SBC HL,DE - POP DE -T11: LD A,(HL) - AND 7FH - CP ' ' ;FILTER OUT CONTROL CHARACTERS' - JR NC,T33 -T22: LD A,'.' -T33: CP 07CH - JR NC,T22 - LD C,A ;SET UP TO SEND - CALL CO - INC HL - DJNZ T11 ;REPEAT FOR WHOLE LINE - JR SF172 - -BLANK: LD C,' ' - JP CO - -;INSPECT AND / OR MODIFY MEMORY - -SUBS: LD C,1 - CALL HEXSP - POP HL -SF2E3: LD A,(HL) - CALL LBYTE - LD C,'-' - CALL CO - CALL PCHK - RET C - JR Z,SF2FC - CP 5FH - JR Z,SF305 - PUSH HL - CALL EXF - POP DE - POP HL - LD (HL),E - LD A,B - CP CR - RET Z -SF2FC: INC HL -SF2FD: LD A,L - AND 07H - CALL Z,LFADR - JR SF2E3 -SF305: DEC HL - JR SF2FD - -;FILL A BLOCK OF MEMORY WITH A VALUE - -FILL: CALL EXPR3 -SF1A5: LD (HL),C - CALL HILOX - JR NC,SF1A5 - POP DE - JP START - -;GO TO A RAM LOCATION - -GOTO: LD C,1 ;SIMPLE GOTO FIRST GET PARMS. - CALL HEXSP - CALL CRLF - POP HL ;GET PARAMETER PUSHED BY EXF - JP (HL) - - -; GET OR OUTPUT TO A PORT - -QUERY: CALL PCHK - CP 'O' ;OUTPUT TO PORT - JR Z,SF77A - CP 'I' ;INPUT FROM PORT - JP Z,QQQ1 - LD C,'*' - JP CO ;WILL ABORT IF NOT 'I' OR 'O' -QQQ1: LD C,1 - CALL HEXSP - POP BC - IN A,(C) - JP BITS -; -SF77A: CALL HEXSP - POP DE - POP BC - OUT (C),E - RET - -;Display Extended memory map for 1MG RAM using IA-2 Z80 Board window registers - -XMEMMAP: - LD HL,MSG17 ;Get segment (0-F) - CALL ZPMSG - LD C,1 - CALL HEXSP ;Get 2 or 4 hex digits (count in C). - POP HL - LD A,L ;Get single byte value - AND 0FH - EXX - LD D,A ;Store in D' for 000X:YYYY display below - SLA A - SLA A - SLA A - SLA A - OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space - LD E,A ;store shifted nibble in E' - LD HL,0 ;Will store 0-FFFF for total RAM display (not actual access) - EXX - LD D,0 ;Total display line count (256 characters, 16lines X 16 characters) - - CALL CRLF - LD HL,0 - LD B,1 -XMAP1: LD A,H - AND 00111111B ;Wrap 16K window - LD H,A - LD E,'R' ;PRINT R FOR RAM - LD A,(HL) - CPL - LD (HL),A - CP (HL) - CPL - LD (HL),A ;Save it back - JR NZ,XMAP2 - CP (HL) - JR Z,XPRINT -XMAP2: LD E,'p' -XMAP3: LD A,0FFH - CP (HL) - JR NZ,XPRINT - INC L - XOR A - CP L - JR NZ,XMAP3 - LD E,'.' -XPRINT: LD L,0 - DEC B - JR NZ,XNLINE - LD B,16 - CALL CRLF - CALL SET_WINDOW - LD A,SPACE - JR XN11 -XNLINE: LD A,SPACE - CALL OTA - LD A,E -XN11: CALL OTA - INC H - INC D ;Are we done yet - JR NZ,XMAP1 - CALL CRLF - XOR A - OUT (Z80PORT+2),A ;Set RAM window back to the way it was - JP START - -SET_WINDOW: ;Setup the unique IA-II Z80 board window to address > 64k - EXX - LD C,D ;Print seg value - CALL HXO2 - LD C,':' - CALL CO - CALL HXOT4 ;Print HL' (not origional HL) - - LD A,H ;get current H being displayed (Already pointed to first 16K window) -NOTW0: CP 40H - JR NZ,NOTW1 - LD A,E - ADD A,04H ;Window for 4,5,6,7, set to H from above - JR DOWIN -NOTW1: CP 80H - JR NZ,NOTW2 - LD A,E - ADD A,08H ;Window for 8,9,A,B set to H from above - JR DOWIN -NOTW2: CP 0C0H - JR NZ,NOTW3 ;Must be values in between - LD A,E - ADD A,0CH ;Window for 4,5,6,7, set to H from above -DOWIN: OUT (Z80PORT+2),A ;Re-map to first 16K in segment:64K Space -NOTW3: LD A,H - ADD A,10H - LD H,A - EXX ;Get back normal register set - RET - - - - -NOTIMPL: - RET - -FBOOT: - RET - -DRIVE_NR_ERR: .DB BELL,CR,LF - .DB "Drive not Ready.",CR,LF,LF,'$' -RESTORE_ERR: .DB BELL,CR,LF - .DB "Restore Failed.",CR,LF,LF,'$' -BOOT_LD_ERR: .DB BELL,CR,LF - .DB "Read Error.",CR,LF,LF,'$' -SEEK_ERROR_MSG: .DB BELL,CR,LF - .DB "Seek Error.",CR,LF,LF,'$' - -BOOT_LD1_ERR: .DB BELL,CR,LF - .DB "BOOT error.",CR,LF,LF,'$' - -IDE_RW_ERROR: .DB CR,LF - .DB "IDE Drive R/W Error" - .DB CR,LF,'$' - -MSG17: .DB CR,LF - .DB "Segement (0-F):$" - .END diff --git a/branches/s100/Source/memmgr.asm b/branches/s100/Source/memmgr.asm deleted file mode 100644 index 823c5842..00000000 --- a/branches/s100/Source/memmgr.asm +++ /dev/null @@ -1,121 +0,0 @@ -;================================================================================================== -; MEMORY PAGE MANAGEMENT -;================================================================================================== -; -; PAGE THE REQUESTED 32K BLOCK OF RAM/ROM INTO THE LOWER 32K OF CPU ADDRESS SPACE. -; LOAD DESIRED PAGE INDEX INTO A AND CALL EITHER RAMPG OR ROMPG AS DESIRED. -; RAMPGZ AND ROMPGZ ARE SHORTCUTS TO PAGE IN THE RAM/ROM ZERO PAGE. -;______________________________________________________________________________________________________________________ -; - -;______________________________________________________________________________________________________________________; -; MACROS TO PERFORM RAM/ROM PAGE SELECTION INTO LOWER 32K OF MEMORY SPACE -; PGRAM(P) SELECT RAM PAGE P -; PGRAMF(P) SELECT RAM PAGE P, FAST VERSION ASSUMES CURRENT PAGE IS A RAM PAGE -; PGROM(P) SELECT ROM PAGE P -; PGROMF(P) SELECT ROM PAGE P, FAST VERSION ASSUMES CURRENT PAGE IS A ROM PAGE -; -; REGISTER A IS DESTROYED -;______________________________________________________________________________________________________________________ -; - -#IF ((PLATFORM == PLT_N8VEM) | (PLATFORM == PLT_ZETA)) -RAMPGZ: ; SELECT RAM PAGE ZERO - XOR A -RAMPG: - OR 80H ; TURN ON BIT 7 TO SELECT RAM PAGES - JR PGSEL -; -ROMPGZ: ; SELECT ROM PAGE ZERO - XOR A -ROMPG: - AND 7FH ; TURN OFF BIT 7 TO SELECT ROM PAGES - JR PGSEL -; -PGSEL: - OUT (MPCL_ROM),A - OUT (MPCL_RAM),A - RET -; - #DEFINE PGRAM(P) LD A,P | 80H \ OUT (MPCL_ROM),A \ OUT (MPCL_RAM),A - #DEFINE PGRAMF(P) LD A,P | 80H \ OUT (MPCL_RAM),A - - #DEFINE PGROM(P) LD A,P & 7FH \ OUT (MPCL_ROM),A \ OUT (MPCL_RAM),A - #DEFINE PGROMF(P) LD A,P & 7FH \ OUT (MPCL_ROM),A -#ENDIF - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -#IF (PLATFORM == PLT_N8) -RAMPGZ: ; SELECT RAM PAGE ZERO - XOR A -RAMPG: - RLCA - RLCA - RLCA - OUT0 (CPU_BBR),A - LD A,DEFACR | 80H - OUT0 (ACR),A - RET -; -ROMPGZ: ; SELECT ROM PAGE ZERO - XOR A -ROMPG: - OUT0 (RMAP),A - XOR A - OUT0 (CPU_BBR),A - LD A,DEFACR - OUT0 (ACR),A - RET -; - #DEFINE PGRAM(P) LD A,P << 3 \ OUT0 (CPU_BBR),A \ LD A,DEFACR | 80H \ OUT0 (ACR),A - #DEFINE PGRAMF(P) LD A,P << 3 \ OUT0 (CPU_BBR),A - - #DEFINE PGROM(P) LD A,P \ OUT0 (RMAP),A \ XOR A \ OUT0 (CPU_BBR),A \ LD A,DEFACR \ OUT0 (ACR),A - #DEFINE PGROMF(P) LD A,P \ OUT0 (RMAP),A -#ENDIF - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; NOTE: S2I HAS NO BANKED MEMORY! -; ALL FUNCTIONALITY IS NULLED OUT HERE. -; -#IF (PLATFORM == PLT_S2I) -RAMPGZ: -RAMPG: -ROMPGZ: -ROMPG: -PGSEL: - RET -; - #DEFINE PGRAM(P) ; NO BANKED MEMORY MANAGEMENT ON S2I - #DEFINE PGRAMF(P) ; NO BANKED MEMORY MANAGEMENT ON S2I - - #DEFINE PGROM(P) ; NO BANKED MEMORY MANAGEMENT ON S2I - #DEFINE PGROMF(P) ; NO BANKED MEMORY MANAGEMENT ON S2I -#ENDIF - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; NOTE: S100 NEEDS TO BE FILLED IN!!! -; THIS IS JUST A PLACE HOLDER -; - -#IF (PLATFORM == PLT_S100) -RAMPGZ: -RAMPG: -ROMPGZ: -ROMPG: -PGSEL: - RET -; - #DEFINE PGRAM(P) ; NO BANKED MEMORY MANAGEMENT ON S2I - #DEFINE PGRAMF(P) ; NO BANKED MEMORY MANAGEMENT ON S2I - - #DEFINE PGROM(P) ; NO BANKED MEMORY MANAGEMENT ON S2I - #DEFINE PGROMF(P) ; NO BANKED MEMORY MANAGEMENT ON S2I -#ENDIF - -;;;;;;;;;;;;;;;;;;;; -; EOF - MEMMGR.ASM ; -;;;;;;;;;;;;;;;;;;;; diff --git a/branches/s100/Source/n8.inc b/branches/s100/Source/n8.inc deleted file mode 100644 index dc8a5c3f..00000000 --- a/branches/s100/Source/n8.inc +++ /dev/null @@ -1,95 +0,0 @@ -; -; Z180 REGISTERS -; -CPU_BASE .EQU 40H ; ONLY RELEVANT FOR Z180 -; -CPU_CNTLA0 .EQU CPU_BASE + $00 ;ASCI0 control A -CPU_CNTLA1: .EQU CPU_BASE+$01 ;ASCI1 control A -CPU_CNTLB0: .EQU CPU_BASE+$02 ;ASCI0 control B -CPU_CNTLB1: .EQU CPU_BASE+$03 ;ASCI1 control B -CPU_STAT0: .EQU CPU_BASE+$04 ;ASCI0 status -CPU_STAT1: .EQU CPU_BASE+$05 ;ASCI1 status -CPU_TDR0: .EQU CPU_BASE+$06 ;ASCI0 transmit -CPU_TDR1: .EQU CPU_BASE+$07 ;ASCI1 transmit -CPU_RDR0: .EQU CPU_BASE+$08 ;ASCI0 receive -CPU_RDR1: .EQU CPU_BASE+$09 ;ASCI1 receive -CPU_CNTR: .EQU CPU_BASE+$0A ;CSI/O control -CPU_TRDR: .EQU CPU_BASE+$0B ;CSI/O transmit/receive -CPU_TMDR0L: .EQU CPU_BASE+$0C ;Timer 0 data lo -CPU_TMDR0H: .EQU CPU_BASE+$0D ;Timer 0 data hi -CPU_RLDR0L: .EQU CPU_BASE+$0E ;Timer 0 reload lo -CPU_RLDR0H: .EQU CPU_BASE+$0F ;Timer 0 reload hi -CPU_TCR: .EQU CPU_BASE+$10 ;Timer control -; -CPU_ASEXT0: .EQU CPU_BASE+$12 ;ASCI0 extension control (Z8S180) -CPU_ASEXT1: .EQU CPU_BASE+$13 ;ASCI1 extension control (Z8S180) -; -CPU_TMDR1L: .EQU CPU_BASE+$14 ;Timer 1 data lo -CPU_TMDR1H: .EQU CPU_BASE+$15 ;Timer 1 data hi -CPU_RLDR1L: .EQU CPU_BASE+$16 ;Timer 1 reload lo -CPU_RLDR1H: .EQU CPU_BASE+$17 ;Timer 1 reload hi -CPU_FRC: .EQU CPU_BASE+$18 ;Free running counter - -CPU_ASTC0L: .EQU CPU_BASE+$1A ;ASCI0 Time constant lo (Z8S180) -CPU_ASTC0H: .EQU CPU_BASE+$1B ;ASCI0 Time constant hi (Z8S180) -CPU_ASTC1L: .EQU CPU_BASE+$1C ;ASCI1 Time constant lo (Z8S180) -CPU_ASTC1H: .EQU CPU_BASE+$1D ;ASCI1 Time constant hi (Z8S180) -CPU_CMR: .EQU CPU_BASE+$1E ;Clock multiplier (latest Z8S180) -CPU_CCR: .EQU CPU_BASE+$1F ;CPU control (Z8S180) -; -CPU_SAR0L: .EQU CPU_BASE+$20 ;DMA0 source addr lo -CPU_SAR0H: .EQU CPU_BASE+$21 ;DMA0 source addr hi -CPU_SAR0B: .EQU CPU_BASE+$22 ;DMA0 source addr bank -CPU_DAR0L: .EQU CPU_BASE+$23 ;DMA0 dest addr lo -CPU_DAR0H: .EQU CPU_BASE+$24 ;DMA0 dest addr hi -CPU_DAR0B: .EQU CPU_BASE+$25 ;DMA0 dest addr bank -CPU_BCR0L: .EQU CPU_BASE+$26 ;DMA0 byte count lo -CPU_BCR0H: .EQU CPU_BASE+$27 ;DMA0 byte count hi -CPU_MAR1L: .EQU CPU_BASE+$28 ;DMA1 memory addr lo -CPU_MAR1H: .EQU CPU_BASE+$29 ;DMA1 memory addr hi -CPU_MAR1B: .EQU CPU_BASE+$2A ;DMA1 memory addr bank -CPU_IAR1L: .EQU CPU_BASE+$2B ;DMA1 I/O addr lo -CPU_IAR1H: .EQU CPU_BASE+$2C ;DMA1 I/O addr hi -CPU_IAR1B: .EQU CPU_BASE+$2D ;DMA1 I/O addr bank (Z8S180) -CPU_BCR1L: .EQU CPU_BASE+$2E ;DMA1 byte count lo -CPU_BCR1H: .EQU CPU_BASE+$2F ;DMA1 byte count hi -CPU_DSTAT: .EQU CPU_BASE+$30 ;DMA status -CPU_DMODE: .EQU CPU_BASE+$31 ;DMA mode -CPU_DCNTL: .EQU CPU_BASE+$32 ;DMA/WAIT control -CPU_IL: .EQU CPU_BASE+$33 ;Interrupt vector load -CPU_ITC: .EQU CPU_BASE+$34 ;INT/TRAP control -; -CPU_RCR: .EQU CPU_BASE+$36 ;Refresh control -; -CPU_CBR: .EQU CPU_BASE+$38 ;MMU common base register -CPU_BBR: .EQU CPU_BASE+$39 ;MMU bank base register -CPU_CBAR .EQU CPU_BASE+$3A ;MMU common/bank area register -; -CPU_OMCR: .EQU CPU_BASE+$3E ;Operation mode control -CPU_ICR: .EQU $3F ;I/O control register (not relocated!!!) -; -; N8 ONBOARD I/O REGISTERS -; -N8_BASE .EQU $80 -; -PPIBASE .EQU N8_BASE + $00 -PPIA .EQU PPIBASE + 0 ; PORT A -PPIB .EQU PPIBASE + 1 ; PORT B -PPIC .EQU PPIBASE + 2 ; PORT C -PPIX .EQU PPIBASE + 3 ; PPI CONTROL PORT -; -PPI2BASE .EQU N8_BASE + $04 -PPI2A .EQU PPI2BASE + 0 ; PORT A -PPI2B .EQU PPI2BASE + 1 ; PORT B -PPI2C .EQU PPI2BASE + 2 ; PORT C -PPI2X .EQU PPI2BASE + 3 ; PPI CONTROL PORT -; -RTC: .EQU N8_BASE + $08 ;RTC latch and buffer -;FDC: .EQU N8_BASE + $0C ;Floppy disk controller -;UTIL: .EQU N8_BASE + $10 ;Floppy disk utility -ACR: .EQU N8_BASE + $14 ;auxillary control register -RMAP: .EQU N8_BASE + $16 ;ROM page register -VDP: .EQU N8_BASE + $18 ;Video Display Processor (TMS9918A) -PSG: .EQU N8_BASE + $1C ;Programmable Sound Generator (AY-3-8910) -; -DEFACR .EQU $1B diff --git a/branches/s100/Source/n8chars.inc b/branches/s100/Source/n8chars.inc deleted file mode 100644 index b0dbd81c..00000000 --- a/branches/s100/Source/n8chars.inc +++ /dev/null @@ -1,259 +0,0 @@ -; n8chars.inc - automatically generated by n8vidtst - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x00(0) - .DB 030h,030h,030h,03ch,03ch,000h,000h,000h ; 0x01(1) - .DB 030h,030h,030h,0f0h,0f0h,000h,000h,000h ; 0x02(2) - .DB 000h,000h,000h,03ch,03ch,030h,030h,030h ; 0x03(3) - .DB 000h,000h,000h,0f0h,0f0h,030h,030h,030h ; 0x04(4) - .DB 030h,030h,030h,030h,030h,030h,030h,030h ; 0x05(5) - .DB 000h,000h,000h,0ffh,0ffh,000h,000h,000h ; 0x06(6) - .DB 000h,000h,020h,070h,0f8h,070h,020h,000h ; 0x07(7) - .DB 000h,0f8h,0d8h,088h,000h,088h,0d8h,0f8h ; 0x08(8) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x09(9) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x0a(10) - .DB 000h,000h,060h,090h,060h,020h,018h,018h ; 0x0b(11) - .DB 000h,000h,020h,070h,020h,020h,050h,020h ; 0x0c(12) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x0d(13) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x0e(14) - .DB 000h,0a8h,050h,050h,0d8h,050h,050h,0a8h ; 0x0f(15) - .DB 030h,030h,030h,0fch,0fch,030h,030h,030h ; 0x10(16) - .DB 000h,010h,030h,070h,0f0h,070h,030h,010h ; 0x11(17) - .DB 000h,020h,070h,020h,020h,020h,070h,020h ; 0x12(18) - .DB 000h,000h,050h,000h,050h,050h,050h,050h ; 0x13(19) - .DB 000h,000h,028h,028h,068h,0a8h,0a8h,078h ; 0x14(20) - .DB 000h,000h,000h,0fch,0fch,030h,030h,030h ; 0x15(21) - .DB 030h,030h,030h,0fch,0fch,000h,000h,000h ; 0x16(22) - .DB 030h,030h,030h,0f0h,0f0h,030h,030h,030h ; 0x17(23) - .DB 020h,020h,020h,020h,020h,020h,070h,020h ; 0x18(24) - .DB 030h,030h,030h,03ch,03ch,030h,030h,030h ; 0x19(25) - .DB 000h,000h,010h,018h,0fch,018h,010h,000h ; 0x1a(26) - .DB 000h,000h,020h,060h,0fch,060h,020h,000h ; 0x1b(27) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x1c(28) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x1d(29) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x1e(30) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x1f(31) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x20(32) - .DB 000h,000h,030h,000h,030h,078h,078h,030h ; 0x21(33) - .DB 000h,000h,000h,000h,000h,050h,0d8h,0d8h ; 0x22(34) - .DB 048h,048h,0fch,048h,048h,0fch,048h,048h ; 0x23(35) - .DB 000h,020h,0f8h,024h,078h,0a0h,078h,020h ; 0x24(36) - .DB 000h,000h,098h,058h,020h,0d0h,0c8h,000h ; 0x25(37) - .DB 000h,078h,090h,060h,050h,048h,048h,030h ; 0x26(38) - .DB 000h,000h,000h,000h,000h,040h,030h,030h ; 0x27(39) - .DB 000h,010h,020h,020h,020h,020h,020h,010h ; 0x28(40) - .DB 000h,020h,010h,010h,010h,010h,010h,020h ; 0x29(41) - .DB 000h,020h,0a8h,070h,0f8h,070h,0a8h,020h ; 0x2a(42) - .DB 000h,000h,020h,020h,0f8h,020h,020h,000h ; 0x2b(43) - .DB 040h,030h,030h,000h,000h,000h,000h,000h ; 0x2c(44) - .DB 000h,000h,000h,000h,070h,000h,000h,000h ; 0x2d(45) - .DB 000h,030h,030h,000h,000h,000h,000h,000h ; 0x2e(46) - .DB 000h,000h,080h,040h,020h,010h,008h,004h ; 0x2f(47) - .DB 000h,070h,0c8h,0a8h,0a8h,0a8h,098h,070h ; 0x30(48) - .DB 000h,0f8h,020h,020h,020h,020h,060h,020h ; 0x31(49) - .DB 000h,0f8h,080h,060h,010h,008h,088h,070h ; 0x32(50) - .DB 000h,070h,088h,008h,070h,008h,088h,070h ; 0x33(51) - .DB 000h,010h,010h,010h,0f8h,090h,050h,030h ; 0x34(52) - .DB 000h,070h,088h,008h,0f0h,080h,080h,0f8h ; 0x35(53) - .DB 000h,070h,088h,088h,0f0h,080h,040h,038h ; 0x36(54) - .DB 000h,020h,020h,020h,020h,010h,008h,0f8h ; 0x37(55) - .DB 000h,070h,088h,088h,070h,088h,088h,070h ; 0x38(56) - .DB 000h,070h,088h,008h,078h,088h,088h,070h ; 0x39(57) - .DB 000h,000h,030h,030h,000h,030h,030h,000h ; 0x3a(58) - .DB 000h,060h,030h,030h,000h,030h,030h,000h ; 0x3b(59) - .DB 000h,010h,020h,040h,080h,040h,020h,010h ; 0x3c(60) - .DB 000h,000h,000h,0fch,000h,0fch,000h,000h ; 0x3d(61) - .DB 000h,040h,020h,010h,008h,010h,020h,040h ; 0x3e(62) - .DB 000h,020h,000h,020h,030h,008h,088h,070h ; 0x3f(63) - .DB 000h,070h,080h,080h,0b0h,0b8h,088h,070h ; 0x40(64) - .DB 000h,088h,088h,088h,0f8h,088h,050h,020h ; 0x41(65) - .DB 000h,0f0h,048h,048h,070h,048h,048h,0f0h ; 0x42(66) - .DB 000h,070h,088h,080h,080h,080h,088h,070h ; 0x43(67) - .DB 000h,0f0h,048h,048h,048h,048h,048h,0f0h ; 0x44(68) - .DB 000h,0f8h,088h,080h,0e0h,080h,088h,0f8h ; 0x45(69) - .DB 000h,080h,080h,080h,0f0h,080h,088h,0f8h ; 0x46(70) - .DB 000h,070h,088h,088h,0b8h,080h,088h,070h ; 0x47(71) - .DB 000h,088h,088h,088h,0f8h,088h,088h,088h ; 0x48(72) - .DB 000h,0f8h,020h,020h,020h,020h,020h,0f8h ; 0x49(73) - .DB 000h,070h,088h,008h,008h,008h,008h,01ch ; 0x4a(74) - .DB 000h,088h,090h,0a0h,0c0h,0a0h,090h,088h ; 0x4b(75) - .DB 000h,0f8h,088h,080h,080h,080h,080h,080h ; 0x4c(76) - .DB 000h,088h,088h,088h,088h,0a8h,0d8h,088h ; 0x4d(77) - .DB 000h,088h,098h,0a8h,0a8h,0a8h,0c8h,088h ; 0x4e(78) - .DB 000h,070h,088h,088h,088h,088h,088h,070h ; 0x4f(79) - .DB 000h,080h,080h,080h,0f0h,088h,088h,0f0h ; 0x50(80) - .DB 004h,078h,098h,0a8h,088h,088h,088h,070h ; 0x51(81) - .DB 000h,088h,090h,0a0h,0f0h,088h,088h,0f0h ; 0x52(82) - .DB 000h,070h,088h,010h,020h,040h,088h,070h ; 0x53(83) - .DB 000h,020h,020h,020h,020h,020h,020h,0f8h ; 0x54(84) - .DB 000h,070h,088h,088h,088h,088h,088h,088h ; 0x55(85) - .DB 000h,020h,050h,050h,050h,088h,088h,088h ; 0x56(86) - .DB 000h,050h,0a8h,0a8h,0a8h,088h,088h,088h ; 0x57(87) - .DB 000h,088h,088h,050h,020h,050h,088h,088h ; 0x58(88) - .DB 000h,020h,020h,020h,020h,050h,088h,088h ; 0x59(89) - .DB 000h,0f8h,088h,040h,020h,010h,088h,0f8h ; 0x5a(90) - .DB 000h,078h,040h,040h,040h,040h,040h,078h ; 0x5b(91) - .DB 000h,000h,008h,010h,020h,040h,080h,000h ; 0x5c(92) - .DB 000h,078h,008h,008h,008h,008h,008h,078h ; 0x5d(93) - .DB 000h,000h,000h,000h,000h,088h,050h,020h ; 0x5e(94) - .DB 000h,0fch,000h,000h,000h,000h,000h,000h ; 0x5f(95) - .DB 000h,000h,000h,000h,000h,010h,060h,060h ; 0x60(96) - .DB 000h,070h,088h,078h,008h,0f0h,000h,000h ; 0x61(97) - .DB 000h,0f0h,088h,088h,0f0h,080h,080h,080h ; 0x62(98) - .DB 000h,070h,080h,080h,070h,000h,000h,000h ; 0x63(99) - .DB 000h,078h,088h,088h,078h,008h,008h,008h ; 0x64(100) - .DB 000h,070h,080h,0f8h,088h,070h,000h,000h ; 0x65(101) - .DB 000h,040h,040h,040h,0e0h,048h,030h,000h ; 0x66(102) - .DB 070h,008h,038h,048h,048h,038h,000h,000h ; 0x67(103) - .DB 000h,088h,088h,0c8h,0b0h,080h,080h,000h ; 0x68(104) - .DB 000h,070h,020h,060h,000h,020h,000h,000h ; 0x69(105) - .DB 030h,048h,008h,008h,018h,000h,008h,000h ; 0x6a(106) - .DB 000h,090h,0a0h,0c0h,0a0h,090h,080h,080h ; 0x6b(107) - .DB 000h,020h,020h,020h,020h,020h,020h,020h ; 0x6c(108) - .DB 000h,088h,0a8h,0a8h,050h,000h,000h,000h ; 0x6d(109) - .DB 000h,088h,088h,0c8h,0b0h,000h,000h,000h ; 0x6e(110) - .DB 000h,070h,088h,088h,070h,000h,000h,000h ; 0x6f(111) - .DB 040h,040h,070h,048h,048h,070h,000h,000h ; 0x70(112) - .DB 008h,008h,038h,048h,048h,038h,060h,000h ; 0x71(113) - .DB 000h,080h,080h,0c8h,0b0h,000h,000h,000h ; 0x72(114) - .DB 000h,060h,010h,060h,080h,060h,000h,000h ; 0x73(115) - .DB 000h,020h,040h,040h,0e0h,040h,000h,000h ; 0x74(116) - .DB 000h,068h,090h,090h,090h,000h,000h,000h ; 0x75(117) - .DB 000h,020h,050h,088h,088h,000h,000h,000h ; 0x76(118) - .DB 000h,050h,0a8h,0a8h,088h,000h,000h,000h ; 0x77(119) - .DB 000h,048h,030h,030h,048h,000h,000h,000h ; 0x78(120) - .DB 000h,080h,040h,020h,050h,088h,000h,000h ; 0x79(121) - .DB 000h,0f8h,040h,020h,010h,0f8h,000h,000h ; 0x7a(122) - .DB 000h,010h,020h,020h,040h,020h,020h,010h ; 0x7b(123) - .DB 000h,020h,020h,020h,000h,020h,020h,020h ; 0x7c(124) - .DB 000h,040h,020h,020h,010h,020h,020h,040h ; 0x7d(125) - .DB 000h,000h,000h,000h,000h,000h,090h,06ch ; 0x7e(126) - .DB 000h,070h,050h,050h,050h,050h,050h,070h ; 0x7f(127) - .DB 0a8h,0a8h,0a8h,0ach,0a0h,0bch,080h,0fch ; 0x80(128) - .DB 000h,000h,000h,0fch,000h,0fch,000h,0fch ; 0x81(129) - .DB 054h,054h,054h,0d4h,014h,0f4h,004h,0fch ; 0x82(130) - .DB 054h,054h,054h,054h,054h,054h,054h,054h ; 0x83(131) - .DB 0fch,004h,0f4h,014h,0d4h,054h,054h,054h ; 0x84(132) - .DB 0ffh,000h,0ffh,000h,0ffh,000h,000h,000h ; 0x85(133) - .DB 0fch,080h,0bch,0a0h,0ach,0a8h,0a8h,0a8h ; 0x86(134) - .DB 0a8h,0a8h,0a8h,0a8h,0a8h,0a8h,0a8h,0a8h ; 0x87(135) - .DB 0a8h,0a8h,0a8h,0ach,0a0h,0ach,0a8h,0a8h ; 0x88(136) - .DB 054h,054h,054h,0d4h,014h,0d4h,054h,054h ; 0x89(137) - .DB 000h,000h,000h,0fch,000h,0fch,000h,000h ; 0x8a(138) - .DB 080h,080h,080h,080h,080h,080h,080h,0fch ; 0x8b(139) - .DB 000h,000h,000h,000h,000h,000h,000h,0fch ; 0x8c(140) - .DB 004h,004h,004h,004h,004h,004h,004h,0fch ; 0x8d(141) - .DB 004h,004h,004h,004h,004h,004h,004h,004h ; 0x8e(142) - .DB 0fch,004h,004h,004h,004h,004h,004h,004h ; 0x8f(143) - .DB 0fch,000h,000h,000h,000h,000h,000h,000h ; 0x90(144) - .DB 0fch,080h,080h,080h,080h,080h,080h,080h ; 0x91(145) - .DB 080h,080h,080h,080h,080h,080h,080h,080h ; 0x92(146) - .DB 080h,080h,080h,080h,0fch,080h,080h,080h ; 0x93(147) - .DB 004h,004h,004h,004h,0fch,004h,004h,004h ; 0x94(148) - .DB 000h,000h,000h,000h,0fch,000h,000h,000h ; 0x95(149) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x96(150) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x97(151) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x98(152) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x99(153) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x9a(154) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x9b(155) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x9c(156) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x9d(157) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x9e(158) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0x9f(159) - .DB 000h,070h,088h,078h,008h,0f0h,040h,020h ; 0xa0(160) - .DB 000h,0f8h,020h,020h,060h,000h,020h,010h ; 0xa1(161) - .DB 000h,070h,088h,088h,070h,000h,020h,010h ; 0xa2(162) - .DB 000h,074h,088h,088h,088h,000h,020h,010h ; 0xa3(163) - .DB 000h,088h,088h,0c8h,0b0h,000h,020h,010h ; 0xa4(164) - .DB 000h,088h,098h,0a8h,0c8h,000h,020h,010h ; 0xa5(165) - .DB 000h,000h,0fch,000h,07ch,088h,088h,070h ; 0xa6(166) - .DB 000h,000h,0fch,000h,070h,088h,088h,070h ; 0xa7(167) - .DB 000h,070h,088h,040h,020h,020h,000h,020h ; 0xa8(168) - .DB 080h,080h,080h,0fch,000h,000h,000h,000h ; 0xa9(169) - .DB 004h,004h,004h,0fch,000h,000h,000h,000h ; 0xaa(170) - .DB 000h,000h,01ch,088h,054h,0a8h,090h,088h ; 0xab(171) - .DB 000h,000h,008h,0b8h,058h,0a8h,090h,088h ; 0xac(172) - .DB 000h,000h,030h,078h,078h,030h,000h,030h ; 0xad(173) - .DB 000h,014h,028h,050h,0a0h,050h,028h,014h ; 0xae(174) - .DB 000h,0a0h,050h,028h,014h,028h,050h,0a0h ; 0xaf(175) - .DB 0aah,054h,0aah,054h,0aah,054h,0aah,054h ; 0xb0(176) - .DB 054h,0aah,054h,0aah,054h,0aah,054h,0aah ; 0xb1(177) - .DB 06ch,0b6h,0dah,06ch,0b6h,0dah,06ch,0b6h ; 0xb2(178) - .DB 018h,018h,018h,018h,018h,018h,018h,018h ; 0xb3(179) - .DB 018h,018h,018h,0f8h,018h,018h,018h,018h ; 0xb4(180) - .DB 018h,018h,0f8h,018h,0f8h,018h,018h,018h ; 0xb5(181) - .DB 06ch,06ch,06ch,0ech,06ch,06ch,06ch,06ch ; 0xb6(182) - .DB 06ch,06ch,06ch,0fch,000h,000h,000h,000h ; 0xb7(183) - .DB 06ch,06ch,0ech,06ch,0fch,000h,000h,000h ; 0xb8(184) - .DB 06ch,06ch,06ch,0ech,00ch,0ech,06ch,06ch ; 0xb9(185) - .DB 06ch,06ch,06ch,06ch,06ch,06ch,06ch,06ch ; 0xba(186) - .DB 06ch,06ch,06ch,0eeh,00eh,0fch,000h,000h ; 0xbb(187) - .DB 000h,000h,000h,0fch,00ch,0ech,06ch,06ch ; 0xbc(188) - .DB 000h,000h,000h,000h,000h,0fch,064h,064h ; 0xbd(189) - .DB 000h,000h,0f0h,030h,030h,0f0h,030h,030h ; 0xbe(190) - .DB 030h,030h,030h,0f0h,000h,000h,000h,000h ; 0xbf(191) - .DB 000h,000h,000h,03ch,030h,030h,030h,030h ; 0xc0(192) - .DB 000h,000h,000h,0fch,030h,030h,030h,030h ; 0xc1(193) - .DB 030h,030h,030h,0fch,000h,000h,000h,000h ; 0xc2(194) - .DB 030h,030h,030h,03ch,030h,030h,030h,030h ; 0xc3(195) - .DB 000h,000h,000h,0fch,000h,000h,000h,000h ; 0xc4(196) - .DB 030h,030h,030h,0fch,030h,030h,030h,030h ; 0xc5(197) - .DB 030h,030h,030h,03ch,030h,03ch,030h,030h ; 0xc6(198) - .DB 0d8h,0d8h,0d8h,0d8h,0d8h,0dch,0d8h,0d8h ; 0xc7(199) - .DB 000h,000h,0fch,0c0h,0dch,0d8h,0d8h,0d8h ; 0xc8(200) - .DB 0d8h,0d8h,0dch,0c0h,0fch,000h,000h,000h ; 0xc9(201) - .DB 000h,0fch,000h,0c0h,0dch,0d8h,0d8h,0d8h ; 0xca(202) - .DB 000h,0fch,000h,000h,000h,000h,000h,000h ; 0xcb(203) - .DB 0d8h,0d8h,0dch,0c0h,0dch,0d8h,0d8h,0d8h ; 0xcc(204) - .DB 000h,000h,0fch,000h,0fch,000h,000h,000h ; 0xcd(205) - .DB 0d8h,0d8h,0dch,000h,0dch,0d8h,0d8h,0d8h ; 0xce(206) - .DB 000h,0fch,000h,000h,0fch,030h,030h,030h ; 0xcf(207) - .DB 000h,000h,000h,000h,0fch,0d8h,0d8h,0d8h ; 0xd0(208) - .DB 030h,030h,0fch,000h,000h,0fch,000h,000h ; 0xd1(209) - .DB 0d8h,0d8h,0fch,000h,000h,000h,000h,000h ; 0xd2(210) - .DB 000h,000h,000h,000h,0fch,0d8h,0d8h,0d8h ; 0xd3(211) - .DB 000h,03ch,030h,030h,03ch,030h,030h,030h ; 0xd4(212) - .DB 030h,030h,03eh,030h,03eh,000h,000h,000h ; 0xd5(213) - .DB 0d8h,0d8h,0fch,000h,000h,000h,000h,000h ; 0xd6(214) - .DB 0d8h,0d8h,0d8h,0dch,0d8h,0d8h,0d8h,0d8h ; 0xd7(215) - .DB 030h,030h,0fch,000h,000h,0fch,030h,030h ; 0xd8(216) - .DB 000h,000h,000h,000h,0f0h,030h,030h,030h ; 0xd9(217) - .DB 030h,030h,030h,030h,03ch,000h,000h,000h ; 0xda(218) - .DB 0fch,0fch,0fch,0fch,0fch,0fch,0fch,0fch ; 0xdb(219) - .DB 0c0h,0c0h,0fch,0fch,0fch,000h,000h,000h ; 0xdc(220) - .DB 0c0h,0c0h,0c0h,0c0h,0c0h,0c0h,0c0h,0c0h ; 0xdd(221) - .DB 00ch,00ch,00ch,00ch,00ch,00ch,00ch,00ch ; 0xde(222) - .DB 000h,0fch,0fch,0fch,00ch,00ch,00ch,00ch ; 0xdf(223) - .DB 000h,068h,090h,090h,068h,000h,000h,000h ; 0xe0(224) - .DB 040h,0f0h,088h,088h,0b0h,088h,088h,070h ; 0xe1(225) - .DB 000h,080h,080h,080h,080h,080h,090h,0f0h ; 0xe2(226) - .DB 000h,000h,048h,050h,050h,050h,050h,0f8h ; 0xe3(227) - .DB 000h,0f8h,088h,040h,020h,040h,088h,0f8h ; 0xe4(228) - .DB 000h,070h,088h,088h,07ch,000h,000h,000h ; 0xe5(229) - .DB 080h,070h,088h,088h,088h,000h,000h,000h ; 0xe6(230) - .DB 000h,01ch,010h,010h,098h,074h,000h,000h ; 0xe7(231) - .DB 000h,0fch,010h,038h,044h,038h,010h,0fch ; 0xe8(232) - .DB 000h,038h,0cch,0cch,0fch,0cch,0cch,030h ; 0xe9(233) - .DB 000h,084h,048h,048h,084h,084h,084h,078h ; 0xea(234) - .DB 000h,038h,044h,044h,044h,038h,040h,03ch ; 0xeb(235) - .DB 000h,000h,06ch,092h,092h,06ch,000h,000h ; 0xec(236) - .DB 000h,070h,068h,058h,038h,000h,000h,000h ; 0xed(237) - .DB 000h,038h,040h,080h,0f8h,080h,040h,038h ; 0xee(238) - .DB 000h,0cch,0cch,0cch,0cch,030h,000h,000h ; 0xef(239) - .DB 000h,0fch,000h,000h,0fch,000h,000h,0fch ; 0xf0(240) - .DB 000h,0feh,000h,010h,010h,07ch,010h,010h ; 0xf1(241) - .DB 000h,0feh,000h,020h,010h,008h,010h,020h ; 0xf2(242) - .DB 000h,0feh,000h,010h,020h,040h,020h,010h ; 0xf3(243) - .DB 030h,030h,030h,030h,030h,030h,034h,018h ; 0xf4(244) - .DB 070h,0b0h,030h,030h,030h,030h,030h,030h ; 0xf5(245) - .DB 000h,030h,030h,000h,0fch,000h,030h,030h ; 0xf6(246) - .DB 000h,000h,098h,064h,000h,098h,064h,000h ; 0xf7(247) - .DB 000h,000h,000h,000h,038h,044h,044h,038h ; 0xf8(248) - .DB 000h,000h,000h,000h,000h,038h,038h,000h ; 0xf9(249) - .DB 000h,000h,000h,000h,000h,038h,000h,000h ; 0xfa(250) - .DB 000h,008h,018h,028h,048h,008h,008h,00eh ; 0xfb(251) - .DB 000h,048h,048h,048h,0b0h,000h,000h,000h ; 0xfc(252) - .DB 000h,0f8h,080h,040h,03ch,0f0h,000h,000h ; 0xfd(253) - .DB 0fch,0fch,0fch,0fch,0fch,0fch,0fch,0fch ; 0xfe(254) - .DB 000h,000h,000h,000h,000h,000h,000h,000h ; 0xff(255) -; eof - n8chars.inc - diff --git a/branches/s100/Source/n8v.asm b/branches/s100/Source/n8v.asm deleted file mode 100644 index 25edd5cc..00000000 --- a/branches/s100/Source/n8v.asm +++ /dev/null @@ -1,770 +0,0 @@ -; ../RomWBW/Source/n8v.asm 11/22/2012 dwg - best so far -; ../RomWBW/Source/n8v.asm 11/19/2012 dwg - add snippets into video scheme -; ../RomWBW/Source/n8v.asm 11/16/2012 dwg - N8V_VDAQRY now working -; ../RomWBW/Source/n8v.asm 11/15/2012 dwg - vdaini and vdaqry retcodes ok -; ../RomWBW/Source/n8v.asm 10/28/2012 dwg - add n8v_modes -; ../RomWBW/Source/n8v.asm 10/27/2012 dwg - begin enhancement - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; N8 VIDEO DRIVER FOR ROMWBW ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor I/O Addresses for the TMS9918 ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -BASE: .EQU 128 -CMDP: .EQU BASE+25 -DATAP: .EQU BASE+24 - -;__________________________________________________________________________________________________ -; DATA CONSTANTS -;__________________________________________________________________________________________________ -; -;_________________________________________________________________________ -; BOARD INITIALIZATION -;_________________________________________________________________________ -; -N8V_INIT: - PRTS("N8V: IO=0x$") - LD A,DATAP - CALL PRTHEXBYTE -; - LD HL,CHARSET - CALL N8V_VDAINI - XOR A - RET -; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; This routine is called from bnk1.asm to init the TMS9918 ; -; If HL is non-zero, it specifies the character bitmaps to load ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDAINI: - LD A,C - LD (VDP_DEVUNIT),A - LD A,E - LD (VDP_MODE),A - PUSH HL - ; Fall through... - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; clear first 16K of TMS9918 video ram to zeroes ; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - LD C,CMDP - LD A,$00 - OUT (C),A ; out(CMDP,0); - CALL RECOVER - LD A,64 - OUT (C),A ; out(CMDP,64); - CALL RECOVER - ; - LD C,DATAP - LD HL,16384 -CLR16LOOP: - LD A,0 - OUT (C),A - DEC HL - LD A,H - OR L - JR NZ,CLR16LOOP - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Set TMS9918 into Text Mode ; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - LD C,CMDP - LD A,0 - OUT (C),A ; out(CMDP,0); - CALL RECOVER - LD A,128 - OUT (C),A ; out(CMDP,128); - CALL RECOVER - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Set TMS9918 into 40-column mode ; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - LD C,CMDP - LD A,80 - OUT (C),A ; out(CMDP,80); - CALL RECOVER - LD A,129 - OUT (C),A ; out(CMDP,129); - CALL RECOVER - ; - ;; text mode is 24x40 - LD A,0 - LD (VDP_MODE),a - LD a,40 - LD (VDP_COLS),a - LD a,24 - LD (VDP_ROWS),A - -;; CALL VDP_PNT ; set TMS9918 Pattern Name Table Pointer -;VDP_PNT: - LD C,CMDP - LD A,0 - OUT (C),A ; out(CMDP,0); - CALL RECOVER - LD A,130 - OUT (C),A ; out(CMDP,130); - CALL RECOVER - -;; CALL VDP_PGT ; set TMS9918 Pattern Generator Table Pointer -;VDP_PGT: - LD C,CMDP - LD A,1 - OUT (C),A ; out(CMDP,1); - CALL RECOVER - LD A,132 - OUT (C),A ; out(CMDP,132); - CALL RECOVER - -;; CALL VDP_COLORS ; set TMS9918 foreground(white) background(black) -;VDP_COLORS: - LD C,CMDP - LD A,(VDP_ATTR) -; LD A,240 - OUT (C),A ; out(CMDP,240); 240 is 0xF0 - 1111 0000 LSB=background MSB=foreground - CALL RECOVER - LD A,135 - OUT (C),A ; out(CMDP,135); - CALL RECOVER - - - POP HL - LD A,L - OR H - JP Z,N8V_NOLOAD -;; CALL VDP_LOAD2 ; set TMS9918 character bitmaps -;VDP_LOAD2: - LD C,CMDP - LD A,0 - OUT (C),A ; out(CMDP,0); - CALL RECOVER - LD A,72 - OUT (C),A ; out(CMDP,72); - CALL RECOVER - LD DE,256 - LD C,DATAP -VDP_LOAD2LOOP: - LD A,(HL) - LD (BYTE8),A - INC HL - LD A,(HL) - LD (BYTE7),A - INC HL - LD A,(HL) - LD (BYTE6),A - INC HL - LD A,(HL) - LD (BYTE5),A - INC HL - LD A,(HL) - LD (BYTE4),A - INC HL - LD A,(HL) - LD (BYTE3),A - INC HL - LD A,(HL) - LD (BYTE2),A - INC HL - LD A,(HL) - INC HL - OUT (C),A - CALL RECOVER - LD A,(BYTE2) - OUT (C),A - CALL RECOVER - LD A,(BYTE3) - OUT (C),A - CALL RECOVER - LD A,(BYTE4) - OUT (C),A - CALL RECOVER - LD A,(BYTE5) - OUT (C),A - CALL RECOVER - LD A,(BYTE6) - OUT (C),A - CALL RECOVER - LD A,(BYTE7) - OUT (C),A - CALL RECOVER - LD A,(BYTE8) - OUT (C),A - CALL RECOVER - DEC DE - LD A,D - OR E - JR NZ,VDP_LOAD2LOOP -N8V_NOLOAD: -; fall through... - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Display init message on composite video ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Output "N8-2312 TMS9918 Text Mode Init Done!" - LD HL,0 - CALL VDP_WRVRAM - LD HL,VDP_HELLO - LD DE,39 - LD C,DATAP -HELLO_LOOP: - LD A,(HL) - OUT (C),A - INC HL - DEC DE - LD A,D - OR E - JR NZ,HELLO_LOOP - ; - ; N8VEM HBIOS v2.2 B3 - LD HL,40+40+40+40+3 - CALL VDP_WRVRAM - LD HL,STR_BANNER - LD C,DATAP - LD DE,20 -BAN_LOOP: - LD A,(HL) - CP '(' - JP Z,BAN_DONE - OUT (C),A - INC HL - DEC DE - LD A,D - OR E - JR NZ,BAN_LOOP -BAN_DONE: - ; - ; (rOMwbw-DOUG-121113t0113) - LD HL,40+40+40+40+40+3 - CALL VDP_WRVRAM - ; - LD HL,STR_BANNER + 20 - LD C,DATAP - ; - LD DE,27 -BAN_LOOP2: - LD A,(HL) - CP ' ' - JP Z,BAN_DONE2 - OUT (C),A - INC HL - DEC DE - LD A,D - OR E - JR NZ,BAN_LOOP2 - LD A,'|' - OUT (C),A - CALL RECOVER -BAN_DONE2: - ; - ; n8 z180 sbc, floppy (autosize), ppide.. - PUSH HL - LD HL,40+40+40+40+40+40+3 - CALL VDP_WRVRAM - POP HL - ; - LD C,DATAP - LD DE,60 -BAN_LOOP3: - LD A,(HL) - CP '$' - JP Z,BAN_DONE3 - OUT (C),A - INC HL - DEC DE - LD A,D - OR E - JP NZ,BAN_LOOP3 -BAN_DONE3: -; fall through... - -; WBW: PPK_INIT SHOULD ONLY BE CALLED FROM HBIOS INIT -; CALL PPK_INIT - ; fall through... - - XOR A - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; This is the end of the init routine ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -;__________________________________________________________________________________________________ -; CHARACTER I/O (CIO) DISPATCHER -;__________________________________________________________________________________________________ -; -N8V_DISPCIO: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,PPK_READ - DEC A - JR Z,N8V_CIOOUT - DEC A - JP Z,PPK_STAT - DEC A - JR Z,N8V_CIOOST - CALL PANIC -; -N8V_CIOOUT: - JP N8V_VDAWRC -; -N8V_CIOOST: - XOR A - INC A - RET -; -;__________________________________________________________________________________________________ -; VIDEO DISPLAY ADAPTER (VDA) DISPATCHER -;__________________________________________________________________________________________________ -; -N8V_DISPVDA: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JP Z,N8V_VDAINI - DEC A - JP Z,N8V_VDAQRY - DEC A - JP Z,N8V_VDARES - DEC A - JP Z,N8V_VDASCS - DEC A - JP Z,N8V_VDASCP - DEC A - JP Z,N8V_VDASAT - DEC A - JP Z,N8V_VDASCO - DEC A - JP Z,N8V_VDAWRC - DEC A - JP Z,N8V_VDAFIL - DEC A - JP Z,N8V_VDACPY - DEC A - JP Z,N8V_VDASCR - DEC A - JP Z,PPK_STAT - DEC A - JP Z,PPK_FLUSH - DEC A - JP Z,PPK_READ - CALL PANIC - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Query ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDAQRY: - LD A,H - OR L - JP Z,N8V_QDONE - ; - ; read bitmaps and - LD C,CMDP - LD A,0 - OUT (C),A ; out(CMDP,0); - CALL RECOVER - LD A,72 - OUT (C),A ; out(CMDP,72); - CALL RECOVER - ; - LD DE,256 - LD C,DATAP - IN A,(C) ; read status - CALL RECOVER -VDP_QLOOP: - IN A,(C) - CALL RECOVER - LD (BYTE8),A - ; - IN A,(C) - CALL RECOVER - LD (BYTE7),A - ; - IN A,(C) - CALL RECOVER - LD (BYTE6),A - ; - IN A,(C) - CALL RECOVER - LD (BYTE5),A - ; - IN A,(C) - CALL RECOVER - LD (BYTE4),A - ; - IN A,(C) - CALL RECOVER - LD (BYTE3),A - ; - IN A,(C) - CALL RECOVER - LD (BYTE2),A - ; - IN A,(C) - CALL RECOVER -; LD (BYTE1),A - ; - LD (HL),A - INC HL - ; - LD A,(BYTE2) - LD (HL),A - INC HL - ; - LD A,(BYTE3) - LD (HL),A - INC HL - ; - LD A,(BYTE4) - LD (HL),A - INC HL - ; - LD A,(BYTE5) - LD (HL),A - INC HL - ; - LD A,(BYTE6) - LD (HL),A - INC HL - ; - LD A,(BYTE7) - LD (HL),A - INC HL - - LD A,(BYTE8) - LD (HL),A - INC HL - - DEC DE - LD A,D - OR E - JR NZ,VDP_QLOOP -N8V_QDONE: - LD A,(VDP_MODE) - LD C,A - LD A,(VDP_ROWS) - LD D,A - LD A,(VDP_COLS) - LD E,A - - LD A,0 ; return SUCCESS - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Reset ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDARES: - LD HL,CHARSET - JP N8V_VDAINI - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Set Cursor Style ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDASCS: - CALL PANIC - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Set Cursor Position ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDASCP: - LD A,E - LD (VDP_COL),A ; keep private copy of column - LD A,C - LD (VDP_DEVUNIT),A ; keep private copy of dev/unit - LD A,D - LD (VDP_ROW),A ; keep private copy of row - XOR A - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Set Character Attributes ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDASAT: - CALL PANIC - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Set Color Color ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDASCO: - CALL PANIC - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Calculate Row Offset ; -; Enter with A = Row number (rel 0) ; -; returns with HL = offset ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_OFFSET: - PUSH DE - LD hl,row_offs ; hl -> row offset table - LD E,A ; place in LO byte of DE - LD d,0 ; make 16 bits - add hl,DE ; - add hl,DE ; hl -> word in offset table for desired row - LD e,(hl) ; pick up the LO byte of the row ptr - INC HL - ld d,(hl) ; pick up the HO byte of the ROW ptr - EX DE,HL ; hl -> offset of first column in row - POP DE - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Write Character ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDAWRC: - -;;; LD (VDP_POS),HL ; accept curpos from caller in HL - - PUSH DE - - LD A,(VDP_ROW) ; pick up cursor row - LD E,A ; place in LO byte of DE - LD d,0 ; make 16 bits - add hl,DE ; - add hl,DE ; hl -> word in offset table for desired row - LD e,(hl) ; pick up the LO byte of the row ptr - INC HL - ld d,(hl) ; pick up the HO byte of the ROW ptr - EX DE,HL ; hl -> offset of first column in row - LD A,(VDP_COL) ; pick up the current column number - LD E,A ; use as LO byte of DE - LD D,0 ; make 16 bits - ADD HL,DE ; hl = offset in name table of row and column - call VDP_WRVRAM ; set vram write ptr to proper byte in name table - - POP DE ; restore the output byte into E - LD A,E ; move into A for output - LD C,DATAP ; I/O address for subsequent VRAM write - OUT (C),a ; prime the auto incrementer - OUT (C),a ; output the data byte into the name table - - XOR A ; set SUCCESS return code - RET ; return from HBIOS call - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Fill ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDAFIL: - XOR A - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Copy ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -N8V_VDACPY: - XOR A - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Scroll ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; COPY DATA ZONE FROM VRAM TO SCRLBUF -VDASCR_RVRAM: - - ; CALCULATE AND SET OFFSET TO START OF DATA ZONE IN VRAM - LD A,(VDASCR_DIST) ; from number lines to scroll, - CALL N8V_OFFSET ; set HL to offset of data in name table - CALL VDP_WRVRAM - - ; SETUP FOR VRAM DATA READ - LD C,DATAP ; using the TMS9918 data port - IN A,(C) ; PRIME AUTOINCREMENT - LD HL,SCRLBUF ; DEST IS SCRLBUF OFFSET 0 - - ; COPY VDASCR_SIZE BYTES FROM VRAM TO HEAD OF SCRLBUF - LD DE,(VDASCR_SIZE) ; SIZE OF DATA ZONE -N8V_VDASCR2: - IN A,(C) ; FETCH NEXT BYTE FROM VRAM - LD (HL),A ; STORE IN SEQUENTIAL LOCATIONS IN SCRBUF - INC HL ; BUMP STORAGE INDEX - DEC DE ; DECREMENT BYTE COUNT REMAINING - LD A,D ; OR D - OR E ; WITH E - JR NZ,N8V_VDASCR2 ; AND DO MORE IF NOT ZERO - - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -VDASCR_WVRAM: - LD HL,0 - CALL VDP_WRVRAM - LD C,DATAP -; OUT (C),A - LD HL,SCRLBUF - LD DE,(VDASCR_SIZE) -N8V_VDASCR3: - LD A,(HL) ; FETCH NEXT BYTE FROM SCRLBUF - OUT (C),A - INC HL - DEC DE - LD A,D - OR E - JR NZ,N8V_VDASCR3 - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -VDASCR_BLANKING: - ; CALCULATE SIZE OF BLANKING ZONE - LD A,(VDASCR_DIST) - CALL N8V_OFFSET - EX DE,HL ; NUMBER OF BYTES TO BLANK -N8V_VDASCR4: - LD A,' ' ; WE WILL BE STORING BLANKS - OUT (C),A ; OUTPUT A BYTE TO THE VRAM NAME TABLE BLANKING ZONE - DEC DE ; DECREMENT COUNT - LD A,D ; OR THE HO BYTE - OR E ; WITH THE LO BYTE - JR NZ,N8V_VDASCR4 ; ;AND LOOP IF NOT ZERO - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -VDASCR_DIST .DB 0 ; NUMBER OF ROWS TO SCROLL -VDASCR_SIZE .DW 0 ; SIZE IN BYTES OF DATA REGION - -N8V_VDASCR: - ; E = scroll distance (# lines) - LD A,E - LD (VDASCR_DIST),A - - LD A,(VDP_ROWS) ; NUMBER OF ROWS ON SCREEN - SUB E ; MINUS DIST IS ROWS OF DATA - CALL N8V_OFFSET ; CVT ROWS OF DATA TO NUMBER OF BYTES - LD (VDASCR_SIZE),HL ; AND SAVE FOR LATER USE - - CALL VDASCR_RVRAM ; read data region of name table into scrlbuf - - CALL VDASCR_WVRAM ; write scrlbuf to head of name table in VRAM - - CALL VDASCR_BLANKING ; blank dist lines at end of name table - - XOR A ; SET SUCCESSFUL RETURN CODE - RET ; RETURN TO CALLER - - -SCRLBUF .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - -;------------------------------------------------- - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Write the VRAM address registers ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VDP_WRVRAM: - ; HL -> points to ram location - LD C,CMDP - OUT (C),L - CALL RECOVER - OUT (C),H - CALL RECOVER - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Recovery-time delay routine - Conservatively long delay ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -RECOVER: - PUSH BC - PUSH DE - PUSH HL - POP HL - POP DE - POP BC - RET - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Video Display Processor Local Driver Data ; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -VDP_DEVUNIT .DB 0 - - -; The following data items, VDP_COL and VDP_ROW area -; data bytes that can be retrieved together with a -; word fetch using the VDP_POS label. It is generally -; set by a call to VDASCP from the emulation layer. -; It is used by VDAFIL specifically to denote the beginning -; of the fill area not specified in the API of VDAFIL. - -VDP_POS: -VDP_COL .DB 0 ; col number 0-39 -VDP_ROW .DB 0 ; row number 0-23 - -VDP_ROWS .DB 24 ; number of rows -VDP_COLS .DB 40 ; -VDP_MODE .DB 0 -VDP_ATTR .DB 240 ; default to white on black -VDP_HELLO .TEXT " N8-2312 TMS9918 Text Mode Init Done!!" -VDP_HELLOLEN .DB $-VDP_HELLO - -BYTE1 .DB 0 -BYTE2 .DB 0 -BYTE3 .DB 0 -BYTE4 .DB 0 -BYTE5 .DB 0 -BYTE6 .DB 0 -BYTE7 .DB 0 -BYTE8 .DB 0 - -CHARSET: -#INCLUDE "n8chars.inc" - -row_offs .dw 40* 0,40* 1,40* 2,40* 3,40* 4,40* 5,40* 6,40* 7 - .dw 40* 8,40* 9,40*10,40*11,40*12,40*13,40*14,40*15 - .dw 40*16,40*17,40*18,40*19,40*20,40*21,40*22,40*23 -; - - -;;;;;;;;;;;;;;;;; -; eof - n8v.asm ; -;;;;;;;;;;;;;;;;; diff --git a/branches/s100/Source/n8vem.inc b/branches/s100/Source/n8vem.inc deleted file mode 100644 index 7b915565..00000000 --- a/branches/s100/Source/n8vem.inc +++ /dev/null @@ -1,30 +0,0 @@ -; -; N8VEM HARDWARE IO PORT ADDRESSES AND MEMORY LOCATIONS -; -MPCL_RAM .EQU 78H ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH -MPCL_ROM .EQU 7CH ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH -RTC .EQU 70H ; ADDRESS OF RTC LATCH AND INPUT PORT -; -; PPI 82C55 I/O IS DECODED TO PORT 60-67 -; -PPIBASE .EQU 60H -PPIA .EQU PPIBASE + 0 ; PORT A -PPIB .EQU PPIBASE + 1 ; PORT B -PPIC .EQU PPIBASE + 2 ; PORT C -PPIX .EQU PPIBASE + 3 ; PPI CONTROL PORT -; -; 16C550 SERIAL LINE UART -; -SIO_BASE .EQU 68H -SIO_RBR .EQU SIO_BASE + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY) -SIO_THR .EQU SIO_BASE + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY) -SIO_IER .EQU SIO_BASE + 1 ; DLAB=0: INT ENABLE REG -SIO_IIR .EQU SIO_BASE + 2 ; INT IDENT REGISTER (READ ONLY) -SIO_FCR .EQU SIO_BASE + 2 ; FIFO CONTROL REG (WRITE ONLY) -SIO_LCR .EQU SIO_BASE + 3 ; LINE CONTROL REG -SIO_MCR .EQU SIO_BASE + 4 ; MODEM CONTROL REG -SIO_LSR .EQU SIO_BASE + 5 ; LINE STATUS REG -SIO_MSR .EQU SIO_BASE + 6 ; MODEM STATUS REG -SIO_SCR .EQU SIO_BASE + 7 ; SCRATCH REGISTER -SIO_DLL .EQU SIO_BASE + 0 ; DLAB=1: DIVISOR LATCH (LS) -SIO_DLM .EQU SIO_BASE + 1 ; DLAB=1: DIVISOR LATCH (MS) diff --git a/branches/s100/Source/pgzero.asm b/branches/s100/Source/pgzero.asm deleted file mode 100644 index d8cc6904..00000000 --- a/branches/s100/Source/pgzero.asm +++ /dev/null @@ -1,28 +0,0 @@ -;___PGZERO_____________________________________________________________________________________________________________ -; - .ORG 0000H -; -; NORMAL PAGE ZERO SETUP, RET/RETI/RETN AS APPROPRIATE -; - .FILL (000H - $),0FFH ; RST 0 - JP 0100H ; JUMP TO BOOT CODE - .FILL (008H - $),0FFH ; RST 8 - RET - .FILL (010H - $),0FFH ; RST 10 - RET - .FILL (018H - $),0FFH ; RST 18 - RET - .FILL (020H - $),0FFH ; RST 20 - RET - .FILL (028H - $),0FFH ; RST 28 - RET - .FILL (030H - $),0FFH ; RST 30 - RET - .FILL (038H - $),0FFH ; INT - RETI - .FILL (066H - $),0FFH ; NMI - RETN -; - .FILL (100H - $),0FFH -; - .END diff --git a/branches/s100/Source/ppide.asm b/branches/s100/Source/ppide.asm deleted file mode 100644 index bfbd3fc3..00000000 --- a/branches/s100/Source/ppide.asm +++ /dev/null @@ -1,700 +0,0 @@ -; -;================================================================================================== -; PPIDE DISK DRIVER -;================================================================================================== -; -; 11/29/2011 dwg - DOUGDEBUG controls the embedded NOPs which adjust for -; recovery time while using the parallel port to talk to the PPIDE and IDE -; device. Using this stabilized by Zeta (8MHz) with a CF chip. -; -; 12/02/2011 wbw - renamed DOUGDEBUG to PPIDESLOW and exposed in config -; PPIDESLOW now controls the RECOVERY macro definition. -; -#IF (PPIDESLOW) -#DEFINE RECOVERY NOP\ NOP\ NOP\ NOP -#ELSE -#DEFINE RECOVERY ; -#ENDIF -; -; MAP PPI PORTS TO PPIDE PORTS -; -#IF (PPIDEMODE == PPIDEMODE_DIO3) -IDELSB .EQU 20H ; LSB -IDEMSB .EQU 21H ; MSB -IDECTL .EQU 22H ; CONTROL SIGNALS -PPI1CONT .EQU 23H ; CONTROL BYTE PPI 82C55 -#ELSE -IDELSB .EQU PPIA ; LSB -IDEMSB .EQU PPIB ; MSB -IDECTL .EQU PPIC ; CONTROL SIGNALS -PPI1CONT .EQU PPIX ; CONTROL BYTE PPI 82C55 -#ENDIF -; -; PPI control bytes for read and write to IDE drive -; -RD_IDE_8255 .EQU 10010010B ; IDE_8255_CTL OUT, IDE_8255_LSB/MSB INPUT -WR_IDE_8255 .EQU 10000000B ; ALL THREE PORTS OUTPUT -; -; IDE CONTROL LINES FOR USE WITH IDE_8255_CTL. CHANGE THESE 8 -; CONSTANTS TO REFLECT WHERE EACH SIGNAL OF THE 8255 EACH OF THE -; IDE CONTROL SIGNALS IS CONNECTED. ALL THE CONTROL SIGNALS MUST -; BE ON THE SAME PORT, BUT THESE 8 LINES LET YOU CONNECT THEM TO -; WHICHEVER PINS ON THAT PORT. -; -PPIDE_A0_LINE .EQU 01H ; DIRECT FROM 8255 TO IDE INTERFACE -PPIDE_A1_LINE .EQU 02H ; DIRECT FROM 8255 TO IDE INTERFACE -PPIDE_A2_LINE .EQU 04H ; DIRECT FROM 8255 TO IDE INTERFACE -PPIDE_CS0_LINE .EQU 08H ; INVERTER BETWEEN 8255 AND IDE INTERFACE -PPIDE_CS1_LINE .EQU 10H ; INVERTER BETWEEN 8255 AND IDE INTERFACE -PPIDE_WR_LINE .EQU 20H ; INVERTER BETWEEN 8255 AND IDE INTERFACE -PPIDE_RD_LINE .EQU 40H ; INVERTER BETWEEN 8255 AND IDE INTERFACE -PPIDE_RST_LINE .EQU 80H ; INVERTER BETWEEN 8255 AND IDE INTERFACE -; -;------------------------------------------------------------------ -; MORE SYMBOLIC CONSTANTS... THESE SHOULD NOT BE CHANGED, UNLESS OF -; COURSE THE IDE DRIVE INTERFACE CHANGES, PERHAPS WHEN DRIVES GET -; TO 128G AND THE PC INDUSTRY WILL DO YET ANOTHER KLUDGE. -; -; SOME SYMBOLIC CONSTANTS FOR THE IDE REGISTERS, WHICH MAKES THE -; CODE MORE READABLE THAN ALWAYS SPECIFYING THE ADDRESS PINS -; -PPIDE_DATA .EQU PPIDE_CS0_LINE -PPIDE_ERROR .EQU PPIDE_CS0_LINE + PPIDE_A0_LINE -PPIDE_FEATURE .EQU PPIDE_CS0_LINE + PPIDE_A0_LINE -PPIDE_SEC_CNT .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE -PPIDE_SECTOR .EQU PPIDE_CS0_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE -PPIDE_CYL_LSB .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE -PPIDE_CYL_MSB .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A0_LINE -PPIDE_HEAD .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE -PPIDE_COMMAND .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE -PPIDE_STTS .EQU PPIDE_CS0_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE -PPIDE_CONTROL .EQU PPIDE_CS1_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE -PPIDE_ASTTS .EQU PPIDE_CS1_LINE + PPIDE_A2_LINE + PPIDE_A1_LINE + PPIDE_A0_LINE -; -; IDE COMMAND CONSTANTS. THESE SHOULD NEVER CHANGE. -; -PPIDECMD_RECAL .EQU 010H -PPIDECMD_READ .EQU 020H -PPIDECMD_WRITE .EQU 030H -PPIDECMD_INIT .EQU 091H -PPIDECMD_ID .EQU 0ECH -PPIDECMD_SPINDOWN .EQU 0E0H -PPIDECMD_SPINUP .EQU 0E1H -PPIDECMD_SETFEAT .EQU 0EFH -; -PPIDERC_OK .EQU 0 -PPIDERC_CMDERR .EQU 1 -PPIDERC_RDYTO .EQU 2 -PPIDERC_BUFTO .EQU 3 -; -; UNIT CONFIGURATION -; -PPIDE0_DEVICE .DB 11100000B ; LBA, MASTER DEVICE -PPIDE1_DEVICE .DB 11110000B ; LBA, SLAVE DEVICE -; -; -; -PPIDE_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JR Z,PPIDE_RD - DEC A - JR Z,PPIDE_WR - DEC A - JR Z,PPIDE_ST - DEC A - JR Z,PPIDE_MED - CALL PANIC -; -PPIDE_RD: - JP PPIDE_XREAD -PPIDE_WR: - JP PPIDE_XWRITE -PPIDE_ST: - JP PPIDE_STATUS -PPIDE_MED: - JP PPIDE_MEDIA -; -; PPIDE_MEDIA -; -PPIDE_MEDIA: - LD A,MID_HD - RET -; -; -; -PPIDE_INIT: - PRTS("PPIDE: IO=0x$") - LD A,IDELSB - CALL PRTHEXBYTE - PRTS(" UNITS=2$") -#IF (PPIDESLOW) - PRTS(" SLOW$") -#ENDIF - CALL PPIDE_RESET - XOR A - DEC A ; INITIAL STATUS IS NOT READY $FF - LD (PPIDE_STAT),A ; SAVE IT - RET -; -; -; -PPIDE_STATUS: - LD A,(PPIDE_STAT) ; LOAD STATUS - OR A ; SET FLAGS - RET -; -; -; -PPIDE_XREAD: - LD A,PPIDECMD_READ - LD (PPIDEP_CMD),A - JP PPIDE_RW -; -; -; -PPIDE_XWRITE: - LD A,PPIDECMD_WRITE - LD (PPIDEP_CMD),A - JP PPIDE_RW -; -; -; -PPIDE_RW: - ; CLEAR RESULTS - XOR A ; A = 0 - LD (PPIDE_RC),A ; CLEAR RETURN CODE - LD (PPIDEP_STTS),A ; CLEAR SAVED STTS - LD (PPIDEP_ERR),A ; CLEAR SAVED ERR - - ; INIT REQUIRED? - LD A,(PPIDE_STAT) - OR A ; SET FLAGS - JR Z,PPIDE_RW0 ; IF STATUS OK, BYPASS RESET - - CALL PPIDE_RESET ; DO THE RESET - -#IF (PPIDE8BIT) - CALL PPIDE_WAITRDY - LD C,PPIDE_FEATURE ; IDE FEATURE REGISTER - LD A,01H ; VALUE := 1 - CALL PPIDE_WRITE ; DO IT - LD C,PPIDE_COMMAND ; IDE COMMAND REGISTER - LD A,PPIDECMD_SETFEAT ; SET FEATURE - CALL PPIDE_WRITE ; DO IT - CALL PPIDE_WAITRDY - JP NC,PPIDE_ERR - CALL PPIDE_CHKERR ; CHECK FOR ERRORS - JP NC,PPIDE_ERR -#IF (PPIDETRACE >= 2) - CALL PPIDE_PRT -#ENDIF -#ENDIF - -PPIDE_RW0: - CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,PPIDE_ERR - CALL PPIDE_SETUP ; SETUP CYL, TRK, HEAD - LD C,PPIDE_COMMAND ; IDE COMMAND REGISTER - LD A,(PPIDEP_CMD) ; COMMAND VALUE - CALL PPIDE_WRITE ; DO IT - CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,PPIDE_ERR - CALL PPIDE_CHKERR ; CHECK FOR ERRORS - JP NC,PPIDE_ERR - CALL PPIDE_WAITBUF ; WAIT FOR BUFFER READY - JP NC,PPIDE_ERR - - LD A,(PPIDEP_CMD) ; DISPATCH TO READ OR WRITE SPECIFIC LOGIC - CP PPIDECMD_WRITE - JP Z,PPIDE_RW1 - - CALL PPIDE_BUFRD ; READ BUFFER - CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,PPIDE_ERR - CALL PPIDE_CHKERR ; CHECK FOR ERRORS - JP NC,PPIDE_ERR - JP PPIDE_OK - -PPIDE_RW1: - CALL PPIDE_BUFWR ; WRITE BUFFER - CALL PPIDE_WAITRDY ; WAIT FOR DRIVE READY - JP NC,PPIDE_ERR - CALL PPIDE_CHKERR ; CHECK FOR ERRORS - JP NC,PPIDE_ERR - JP PPIDE_OK - -PPIDE_ERR: - XOR A - DEC A ; A = $FF TO SIGNAL ERROR - LD (PPIDE_STAT),A ; SAVE IT -#IF (PPIDETRACE >= 1) - PUSH AF - CALL PPIDE_PRT - POP AF -#ENDIF - RET - -PPIDE_OK: -#IF (PPIDETRACE >= 2) - CALL PPIDE_PRT -#ENDIF - XOR A - RET -; -; -; -PPIDE_RESET: - LD C,PPIDE_CONTROL ; IDE CONTROL REGISTER - LD A,000001110B ; NO INTERRUPTS, ASSERT RESET BOTH DRIVES - CALL PPIDE_WRITE ; DO IT - LD DE,8 ; DELAY ABOUT 200ms - CALL VDELAY - LD C,PPIDE_CONTROL ; IDE CONTROL REGISTER - LD A,000000010B ; NO INTERRUPTS, DEASSERT RESET - CALL PPIDE_WRITE ; DO IT - XOR A ; STATUS OK - LD (PPIDE_STAT),A ; SAVE IT - - RET -; -; -; -PPIDE_WAITRDY: - LD DE,0 ; TIMEOUT IS 250us * 65536 = 15 SECONDS -PPIDE_WBSY: - PUSH DE - LD DE,10 ; INNER LOOP DELAY IS 250us (25us * 10) - CALL VDELAY - POP DE - DEC DE - LD A,D - OR E - JP Z,PPIDE_TO - LD C,PPIDE_STTS ; IDE STATUS REGISTER - CALL PPIDE_READ ; READ ID - LD (PPIDEP_STTS),A ; SAVE IT - AND 011000000B ; ISOLATE BUSY AND RDY BITS - XOR 001000000B ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 - JP NZ,PPIDE_WBSY - SCF ; CARRY 1 = OK - RET -PPIDE_TO: - LD A,PPIDERC_RDYTO - LD (PPIDE_RC),A - XOR A ; CARRY 0 = TIMEOUT - RET -; -; -; -PPIDE_CHKERR: - LD C,PPIDE_STTS ; IDE STATUS REGISTER - CALL PPIDE_READ ; READ IT - LD (PPIDEP_STTS),A ; SAVE IT - AND 000000001B ; ERROR BIT SET? - SCF ; ASSUME NO ERR - RET Z ; NO ERR, RETURN WITH CF SET -; - LD C,PPIDE_ERROR ; IDE ERROR REGISTER - CALL PPIDE_READ ; READ IT - LD (PPIDEP_ERR),A ; SAVE IT -; - LD A,PPIDERC_CMDERR ; COMMAND ERROR - LD (PPIDE_RC),A ; SAVE IT -; - OR A ; CLEAR CF TO SIGNAL ERROR - RET -; -; -; -PPIDE_WAITBUF: - LD DE,0 -PPIDE_WDRQ: - CALL DELAY - INC DE - LD A,D - OR E - JP Z,PPIDE_TO2 - LD C,PPIDE_STTS ; IDE STATUS REGISTER - CALL PPIDE_READ ; READ IT - LD (PPIDEP_STTS),A ; SAVE IT - AND 010001000B ; TO FILL (OR READY TO FILL) - XOR 000001000B - JP NZ,PPIDE_WDRQ - SCF ; CARRY 1 = OK - RET -PPIDE_TO2: - LD A,PPIDERC_BUFTO - LD (PPIDE_RC),A - XOR A ; CARRY 0 = TIMED OUT - RET -; -; -; -PPIDE_BUFRD: - ; SETUP PPI TO READ - LD A,RD_IDE_8255 ; READ CONFIG - OUT (PPI1CONT),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY -; - ; SELECT READ/WRITE IDE REGISTER - LD A,PPIDE_DATA ; DATA REGISTER - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY - LD E,A ; E := READ UNASSERTED - XOR PPIDE_RD_LINE ; SWAP THE READ LINE BIT - LD D,A ; D := READ ASSERTED -; - ; LOOP SETUP - LD HL,(DIOBUF) ; LOCATION OF BUFFER - LD B,0 ; 256 ITERATIONS - LD C,IDEMSB ; SETUP C WITH IO PORT (MSB) -; - CALL PPIDE_BUFRD1 ; FIRST PASS (FIRST 256 BYTES) - CALL PPIDE_BUFRD1 ; SECOND PASS (LAST 256 BYTES) -; - ; CLEAN UP - XOR A ; ZERO A - OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS - RECOVERY ; OPTIONAL SMALL DELAY - RET -; -PPIDE_BUFRD1: ; START OF READ LOOP -#IF (!PPIDE8BIT) - DEC C ; MSB -> LSB -#ENDIF - LD A,D ; ASSERT READ - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY - INI ; GET AND SAVE NEXT BYTE - RECOVERY ; OPTIONAL SMALL DELAY -#IF (!PPIDE8BIT) - INC C ; LSB -> MSB - INI ; GET AND SAVE NEXT BYTE - RECOVERY ; OPTIONAL SMALL DELAY -#ENDIF - LD A,E ; DEASSERT READ - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY - JR NZ,PPIDE_BUFRD1 ; LOOP UNTIL DONE - RET -; -; -; -PPIDE_BUFWR: - ; SETUP PPI TO WRITE - LD A,WR_IDE_8255 ; READ CONFIG - OUT (PPI1CONT),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY -; - ; SELECT READ/WRITE IDE REGISTER - LD A,PPIDE_DATA ; DATA REGISTER - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY - LD E,A ; E := READ UNASSERTED - XOR PPIDE_WR_LINE ; SWAP THE WRITE LINE BIT - LD D,A ; D := READ ASSERTED -; - ; LOOP SETUP - LD HL,(DIOBUF) ; LOCATION OF BUFFER - LD B,0 ; 256 ITERATIONS - LD C,IDEMSB ; SETUP C WITH IO PORT (MSB) -; - CALL PPIDE_BUFWR1 ; FIRST PASS (FIRST 256 BYTES) - CALL PPIDE_BUFWR1 ; SECOND PASS (LAST 256 BYTES) -; - ; CLEAN UP - XOR A ; ZERO A - OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS - RECOVERY ; OPTIONAL SMALL DELAY - RET -; -PPIDE_BUFWR1: ; START OF READ LOOP -#IF (!PPIDE8BIT) - DEC C ; MSB -> LSB -#ENDIF - OUTI ; SEND NEXT BYTE OF BUFFER - RECOVERY ; OPTIONAL SMALL DELAY -#IF (!PPIDE8BIT) - INC C ; LSB -> MSB - OUTI ; SEND NEXT BYTE OF BUFFER - RECOVERY ; OPTIONAL SMALL DELAY -#ENDIF - LD A,D ; ASSERT WRITE - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY - LD A,E ; DEASSERT WRITE - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY - JR NZ,PPIDE_BUFWR1 ; LOOP UNTIL DONE - RET -; -; -; -PPIDE_SETUP: - LD C,PPIDE_SEC_CNT ; IDE SECTOR COUNT REGISTER - LD A,1 ; 1 SECTOR - CALL PPIDE_WRITE ; DO IT - - LD A,(HSTDSK) ; HSTDSK -> HEAD BIT 4 TO SELECT UNIT - AND 0FH - CP 0 - JP Z,PPIDE_SETUP_UNIT0 - CP 1 - JP Z,PPIDE_SETUP_UNIT1 - CALL PANIC -PPIDE_SETUP_UNIT0: - LD A,(PPIDE0_DEVICE) -; LD DE,(PPIDE0_OFFSET) - JP PPIDE_SETUP1 -PPIDE_SETUP_UNIT1: - LD A,(PPIDE1_DEVICE) -; LD DE,(PPIDE1_OFFSET) - JP PPIDE_SETUP1 -PPIDE_SETUP1: - LD C,PPIDE_HEAD ; IDE HEAD REGISTER - LD (PPIDEP_HEAD),A ; SAVE HEAD VALUE - CALL PPIDE_WRITE ; WRITE IT - - LD HL,(HSTTRK) ; HSTTRK -> IDECYLHI/LO - LD C,PPIDE_CYL_MSB ; IDE MSB CYL REGISTER - LD A,H ; MSB CYL VALUE - LD (PPIDEP_CYLHI),A ; SAVE IT - CALL PPIDE_WRITE ; WRITE IT - LD C,PPIDE_CYL_LSB ; IDE LSB CYL REGISTER - LD A,L ; LSB CYL VALUE - LD (PPIDEP_CYLLO),A ; SAVE IT - CALL PPIDE_WRITE ; WRITE IT - - LD HL,(HSTSEC) ; HSTSEC -> IDESECTN - LD C,PPIDE_SECTOR ; IDE SECTOR REGISTER - LD A,L ; SECTOR VALUE - LD (PPIDEP_SEC),A ; SAVE IT - CALL PPIDE_WRITE ; WRITE IT - -#IF (DSKYENABLE) - CALL PPIDE_DSKY -#ENDIF - - RET -; -; -; -PPIDE_READ: -; - ; SET PPI MODE TO READ CONFIGURATION - LD A,RD_IDE_8255 ; PPI MODE TO READ - OUT (PPI1CONT),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY -; - ; SELECT REQUESTED IDE REGISTER AND ASSERT READ - LD A,C ; REGISTER SELECTION -> A - OR PPIDE_RD_LINE ; ASSERT READ - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY -; - ; READ THE BYTE - IN A,(IDELSB) ; READ LSB - RECOVERY ; OPTIONAL SMALL DELAY - PUSH AF ; SAVE IT FOR NOW -; - ; CLEAN UP AND RETURN - XOR A ; ZERO A - OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS - RECOVERY ; OPTIONAL SMALL DELAY -; - POP AF ; RECOVER THE DATA BYTE - RET ; RETURN -; -; -; -PPIDE_WRITE: -; - ; SAVE THE INCOMING VALUE TO WRITE - PUSH AF -; - ; SET PPI MODE TO WRITE CONFIGURATION - LD A,WR_IDE_8255 ; PPI MODE TO WRITE - OUT (PPI1CONT),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY -; - ; SET THE VALUE TO WRITE - POP AF ; GET VALUE BACK - OUT (IDELSB),A ; SET IDE LSB - RECOVERY ; OPTIONAL SMALL DELAY -; XOR A ; ZERO A -; OUT (IDELSB),A ; SET IDE MSB -; RECOVERY ; OPTIONAL SMALL DELAY -; - ; PULSE THE WRITE LINE - LD A,C ; REGISTER SELECTION -> A - OR PPIDE_WR_LINE ; ASSERT WRITE - OUT (IDECTL),A ; DO IT - RECOVERY ; OPTIONAL SMALL DELAY -; - ; CLEAN UP AND RETURN - XOR A ; ZERO A - OUT (IDECTL),A ; RELEASE ALL BUS SIGNALS - RECOVERY ; OPTIONAL SMALL DELAY -; - RET ; RETURN -; -; -; -#IF (DSKYENABLE) -PPIDE_DSKY: - LD HL,DSKY_HEXBUF - LD A,(PPIDEP_HEAD) - LD (HL),A - INC HL - LD A,(PPIDEP_CYLHI) - LD (HL),A - INC HL - LD A,(PPIDEP_CYLLO) - LD (HL),A - INC HL - LD A,(PPIDEP_SEC) - LD (HL),A - CALL DSKY_HEXOUT - RET -#ENDIF -; -; -; -PPIDE_PRT: - CALL NEWLINE - - LD DE,PPIDESTR_PREFIX - CALL WRITESTR - - CALL PC_SPACE - LD DE,PPIDESTR_CMD - CALL WRITESTR - LD A,(PPIDEP_CMD) - CALL PRTHEXBYTE - - CALL PC_SPACE - CALL PC_LBKT - LD A,(PPIDEP_CMD) - LD DE,PPIDESTR_READ - CP PPIDECMD_READ - JP Z,PPIDE_PRTCMD - LD DE,PPIDESTR_WRITE - CP PPIDECMD_WRITE - JP Z,PPIDE_PRTCMD - LD DE,PPIDESTR_UNKCMD -PPIDE_PRTCMD: - CALL WRITESTR - CALL PC_RBKT - - CALL PC_SPACE - LD A,(PPIDEP_HEAD) - CALL PRTHEXBYTE - LD A,(PPIDEP_CYLHI) - CALL PRTHEXBYTE - LD A,(PPIDEP_CYLLO) - CALL PRTHEXBYTE - LD A,(PPIDEP_SEC) - CALL PRTHEXBYTE - - CALL PC_SPACE - LD DE,PPIDESTR_ARROW - CALL WRITESTR - - CALL PC_SPACE - LD C,PPIDE_STTS ; IDE STATUS REGISTER - CALL PPIDE_READ ; READ IT - CALL PRTHEXBYTE - - CALL PC_SPACE - LD C,PPIDE_ERROR ; IDE ERROR REGISTER - CALL PPIDE_READ ; READ IT - CALL PRTHEXBYTE - - CALL PC_SPACE - LD DE,PPIDESTR_RC - CALL WRITESTR - LD A,(PPIDE_RC) - CALL PRTHEXBYTE - - CALL PC_SPACE - CALL PC_LBKT - LD A,(PPIDE_RC) - LD DE,PPIDESTR_RCOK - CP PPIDERC_OK - JP Z,PPIDE_PRTRC - LD DE,PPIDESTR_RCCMDERR - CP PPIDERC_CMDERR - JP Z,PPIDE_PRTRC - LD DE,PPIDESTR_RCRDYTO - CP PPIDERC_RDYTO - JP Z,PPIDE_PRTRC - LD DE,PPIDESTR_RCBUFTO - CP PPIDERC_BUFTO - JP Z,PPIDE_PRTRC - LD DE,PPIDESTR_RCUNK -PPIDE_PRTRC: - CALL WRITESTR - CALL PC_RBKT - - RET -; -; -; -PPIDESTR_PREFIX .TEXT "PPIDE:$" -PPIDESTR_CMD .TEXT "CMD=$" -PPIDESTR_RC .TEXT "RC=$" -PPIDESTR_ARROW .TEXT "-->$" -PPIDESTR_READ .TEXT "READ$" -PPIDESTR_WRITE .TEXT "WRITE$" -PPIDESTR_UNKCMD .TEXT "UNKCMD$" -PPIDESTR_RCOK .TEXT "OK$" -PPIDESTR_RCCMDERR .TEXT "COMMAND ERROR$" -PPIDESTR_RCRDYTO .TEXT "READY TIMEOUT$" -PPIDESTR_RCBUFTO .TEXT "BUFFER TIMEOUT$" -PPIDESTR_RCUNK .TEXT "UNKNOWN ERROR$" -; -;================================================================================================== -; PPIDE DISK DRIVER - DATA -;================================================================================================== -; -PPIDE_STAT .DB 0 -PPIDE_RC .DB 0 -; -; PPIDE PARAMETERS -; -PPIDEP_CMD .DB 0 -PPIDEP_HEAD .DB 0 -PPIDEP_CYLHI .DB 0 -PPIDEP_CYLLO .DB 0 -PPIDEP_SEC .DB 0 -PPIDEP_STTS .DB 0 -PPIDEP_ERR .DB 0 -; -; -; -; -; -; -; -; Error Register (ERR bit being set in the Status Register) -; -; Bit 7: BBK (Bad Block Detected) Set when a Bad Block is detected. -; Bit 6: UNC (Uncorrectable Data Error) Set when Uncorrectable Error is encountered. -; Bit 5: MC (Media Changed) Set to 0. -; Bit 4: IDNF (ID Not Found) Set when Sector ID not found. -; Bit 3: MCR (Media Change Request) Set to 0. -; Bit 2: ABRT (Aborted Command) Set when Command Aborted due to drive error. -; Bit 1: TKONF (Track 0 Not Found) Set when Executive Drive Diagnostic Command. -; Bit 0: AMNF (Address mark Not Found) Set in case of a general error. -; -; Status Register (When the contents of this register are read by the host, the IREQ# bit is cleared) -; -; Bit 7: BSY (Busy) Set when the drive is busy and unable to process any new ATA commands. -; Bit 6: DRDY (Data Ready) Set when the device is ready to accept ATA commands from the host. -; Bit 5: DWF (Drive Write Fault) Always set to 0. -; Bit 4: DSC (Drive Seek Complete) Set when the drive heads have been positioned over a specific track. -; Bit 3: DRQ (Data Request) Set when device is ready to transfer a word or byte of data to or from the host and the device. -; Bit 2: CORR (Corrected Data) Always set to 0. -; Bit 1: IDX (Index) Always set to 0. -; Bit 0: ERR (Error) Set when an error occurred during the previous ATA command. \ No newline at end of file diff --git a/branches/s100/Source/ppide_data.asm b/branches/s100/Source/ppide_data.asm deleted file mode 100644 index 2fb4c2b3..00000000 --- a/branches/s100/Source/ppide_data.asm +++ /dev/null @@ -1,61 +0,0 @@ -; -;================================================================================================== -; PPIDE DISK DRIVER - DATA -;================================================================================================== -; -PPIDE_SLICETRKS .EQU 65 ; TRACKS PER SLICE -PPIDE_TRKSIZE .EQU 128 ; SIZE OF TRACK (IN KB) -PPIDE_SLICESIZE .EQU ((PPIDE_SLICETRKS * PPIDE_TRKSIZE) + 1023) / 1024 ; SIZE OF EACH SLICE (IN MB) -PPIDE_NUMSLICES .EQU PPIDECAPACITY / PPIDE_SLICESIZE ; TOTAL SLICES IN DEVICE -PPIDE0_SLICEDEF .EQU 0 ; DEFAULT SLICE FOR UNIT 0 -PPIDE1_SLICEDEF .EQU 1 ; DEFAULT SLICE FOR UNIT 1 -PPIDE2_SLICEDEF .EQU 2 ; DEFAULT SLICE FOR UNIT 0 -PPIDE3_SLICEDEF .EQU 3 ; DEFAULT SLICE FOR UNIT 1 -; - .DB DIODEV_PPIDE + 0 -PPIDEDPH0 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PPIDECSV0,PPIDEALV0 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPIDE0_SLICE .DW PPIDE0_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPIDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PPIDE + 0 -PPIDEDPH1 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,0FFFFH - .DW PPIDECSV1,PPIDEALV1 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPIDE1_SLICE .DW PPIDE1_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPIDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PPIDE + 0 -PPIDEDPH2 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,0FFFFH - .DW PPIDECSV2,PPIDEALV2 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPIDE2_SLICE .DW PPIDE2_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPIDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PPIDE + 0 -PPIDEDPH3 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,0FFFFH - .DW PPIDECSV3,PPIDEALV3 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPIDE3_SLICE .DW PPIDE3_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPIDE_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; -PPIDECKS .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -PPIDEALS .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) -; -PPIDECSV0: .FILL PPIDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPIDEALV0: .FILL PPIDEALS ; MAX OF 2048 DATA BLOCKS -PPIDECSV1: .FILL PPIDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPIDEALV1: .FILL PPIDEALS ; MAX OF 2048 DATA BLOCKS -PPIDECSV2: .FILL PPIDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPIDEALV2: .FILL PPIDEALS ; MAX OF 2048 DATA BLOCKS -PPIDECSV3: .FILL PPIDECKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPIDEALV3: .FILL PPIDEALS ; MAX OF 2048 DATA BLOCKS diff --git a/branches/s100/Source/ppk.asm b/branches/s100/Source/ppk.asm deleted file mode 100644 index 64d6da5a..00000000 --- a/branches/s100/Source/ppk.asm +++ /dev/null @@ -1,854 +0,0 @@ -;__________________________________________________________________________________________________ -; -; PARALLEL PORT KEYBOARD DRIVER FOR N8VEM -; SUPPORT KEYBOARD/MOUSE ON VDU AND N8 -; -; ORIGINAL CODE BY DR JAMES MOXHAM -; ROMWBW ADAPTATION BY WAYNE WARTHEN -;__________________________________________________________________________________________________ -; -; TODO: -;__________________________________________________________________________________________________ -; DATA CONSTANTS -;__________________________________________________________________________________________________ -; -; IO PORTS -; -#IF (PLATFORM == PLT_N8) -PPK_PPI .EQU 084H ; PPI PORT BASE FOR N8 -#ELSE -PPK_PPI .EQU 0F4H ; PPI PORT BASE FOR VDU -#ENDIF - -PPK_PPIA .EQU PPK_PPI + 0 ; KEYBOARD PPI PORT A -PPK_PPIB .EQU PPK_PPI + 1 ; KEYBOARD PPI PORT B -PPK_PPIC .EQU PPK_PPI + 2 ; KEYBOARD PPI PORT C -PPK_PPIX .EQU PPK_PPI + 3 ; KEYBOARD PPI CONTROL PORT - -PPK_DAT .EQU 01111000B ; PPIX MASK TO MANAGE DATA LINE (C:4) -PPK_CLK .EQU 01111010B ; PPIX MASK TO MANAGE CLOCK LINE (C:5) - -PPK_WAITTO .EQU 50 * CPUFREQ ; TUNE!!! WANT SMALL AS POSSIBLE W/O ERRORS -PPK_WAITRDY .EQU 10 * CPUFREQ ; TUNE!!! 100US LOOP DELAY TO ENSURE DEVICE READY -; -; STATUS BITS (FOR PPK_STATUS) -; -PPK_EXT .EQU 01H ; BIT 0, EXTENDED SCANCODE ACTIVE -PPK_BREAK .EQU 02H ; BIT 1, THIS IS A KEY UP (BREAK) EVENT -PPK_KEYRDY .EQU 80H ; BIT 7, INDICATES A DECODED KEYCODE IS READY -; -; STATE BITS (FOR PPK_STATE, PPK_LSTATE, PPK_RSTATE) -; -PPK_SHIFT .EQU 01H ; BIT 0, SHIFT ACTIVE (PRESSED) -PPK_CTRL .EQU 02H ; BIT 1, CONTROL ACTIVE (PRESSED) -PPK_ALT .EQU 04H ; BIT 2, ALT ACTIVE (PRESSED) -PPK_WIN .EQU 08H ; BIT 3, WIN ACTIVE (PRESSED) -PPK_SCRLCK .EQU 10H ; BIT 4, CAPS LOCK ACTIVE (TOGGLED ON) -PPK_NUMLCK .EQU 20H ; BIT 5, NUM LOCK ACTIVE (TOGGLED ON) -PPK_CAPSLCK .EQU 40H ; BIT 6, SCROLL LOCK ACTIVE (TOGGLED ON) -PPK_NUMPAD .EQU 80H ; BIT 7, NUM PAD KEY (KEY PRESSED IS ON NUM PAD) -; -PPK_DEFRPT .EQU $40 ; DEFAULT REPEAT RATE (.5 SEC DELAY, 30CPS) -PPK_DEFSTATE .EQU PPK_NUMLCK ; DEFAULT STATE (NUM LOCK ON) -; -;__________________________________________________________________________________________________ -; DATA -;__________________________________________________________________________________________________ -; -PPK_SCANCODE .DB 0 ; RAW SCANCODE -PPK_KEYCODE .DB 0 ; RESULTANT KEYCODE AFTER DECODING -PPK_STATE .DB 0 ; STATE BITS (SEE ABOVE) -PPK_LSTATE .DB 0 ; STATE BITS FOR "LEFT" KEYS -PPK_RSTATE .DB 0 ; STATE BITS FOR "RIGHT" KEYS -PPK_STATUS .DB 0 ; CURRENT STATUS BITS (SEE ABOVE) -PPK_REPEAT .DB 0 ; CURRENT REPEAT RATE -PPK_IDLE .DB 0 ; IDLE COUNT -; -;__________________________________________________________________________________________________ -; KEYBOARD INITIALIZATION -;__________________________________________________________________________________________________ -; -PPK_INIT: - PRTS("PPK: IO=0x$") - LD A,PPK_PPIA - CALL PRTHEXBYTE -; - CALL PPK_INITPORT ; SETS PORT C SO CAN INPUT AND OUTPUT - - LD A,PPK_DEFRPT ; GET DEFAULT REPEAT RATE - LD (PPK_REPEAT),A ; SAVE IT - LD A,PPK_DEFSTATE ; GET DEFAULT STATE - LD (PPK_STATE),A ; SAVE IT - - CALL PPK_RESET ; RESET THE KEYBOARD - CALL PPK_SETLEDS ; UPDATE LEDS BASED ON CURRENT TOGGLE STATE BITS - CALL PPK_SETRPT ; UPDATE REPEAT RATE BASED ON CURRENT SETTING - - XOR A ; SIGNAL SUCCESS - RET -; -;__________________________________________________________________________________________________ -; KEYBOARD STATUS -;__________________________________________________________________________________________________ -; -; CHECKING THE KEYBOARD REQUIRES "WAITING" FOR A KEY TO BE SENT AND USING A TIMEOUT -; TO DETECT THAT NO KEY IS READY. MANY APPS CALL STATUS REPEATEDLY. IN ORDER TO AVOID -; SLOWING THEM DOWN, WE IGNORE 1/256 OF THE CALLS. -; -PPK_STAT: - LD A,(PPK_STATUS) ; GET STATUS - AND PPK_KEYRDY ; ISOLATE READY BIT - JR NZ,PPK_STAT3 ; KEY READY, DONE - -PPK_STAT1: - LD A,(PPK_IDLE) ; GET IDLE COUNT - DEC A ; DECREMENT IT - LD (PPK_IDLE),A ; SAVE IT - JR Z,PPK_STAT2 ; ZERO? OK, DO A REAL KEY CHECK - XOR A ; RETURN KEY NOT READY - RET - -PPK_STAT2: - CALL Z,PPK_DECODE ; NOT READY, RUN THE DECODING ENGINE - LD A,(PPK_STATUS) ; GET STATUS - AND PPK_KEYRDY ; ISOLATE READ BIT - -PPK_STAT3: - RLCA ; ROTATE READY BIT TO LOW ORDER BIT - RET -; -;__________________________________________________________________________________________________ -; KEYBOARD READ -; -; RETURNS ASCII VALUE IN E. SEE END OF FILE FOR VALUES RETURNED FOR SPECIAL KEYS -; LIKE PGUP, ARROWS, FUNCTION KEYS, ETC. -;__________________________________________________________________________________________________ -; -PPK_READ: -; CALL PPK_STAT ; CHECK TO SEE IF KEY READY - LD A,(PPK_STATUS) ; GET STATUS - AND PPK_KEYRDY ; ISOLIATE KEY READY BIT - JR NZ,PPK_READ1 ; READY, GO GET THE KEY AND RETURN - CALL PPK_DECODE ; TRY TO GET A KEY - JR PPK_READ ; AND LOOP -; -PPK_READ1: - LD A,(PPK_STATE) ; GET STATE - AND $01 ; ISOLATE EXTENDED SCANCODE BIT - RRCA ; ROTATE IT TO HIGH ORDER BIT - LD E,A ; SAVE IT IN E FOR NOW - LD A,(PPK_SCANCODE) ; GET SCANCODE - OR E ; COMBINE WITH EXTENDED BIT - LD C,A ; STORE IT IN C FOR RETURN - LD A,(PPK_KEYCODE) ; GET KEYCODE - LD E,A ; SAVE IT IN E - LD A,(PPK_STATE) ; GET STATE FLAGS - LD D,A ; SAVE THEM IN D - XOR A ; SIGNAL SUCCESS - LD (PPK_STATUS),A ; CLEAR STATUS TO INDICATE BYTE RECEIVED - RET -; -;__________________________________________________________________________________________________ -; KEYBOARD FLUSH -;__________________________________________________________________________________________________ -; -PPK_FLUSH: - XOR A ; A = 0 - LD (PPK_STATUS),A ; CLEAR STATUS - RET -; -;__________________________________________________________________________________________________ -; HARDWARE INTERFACE -;__________________________________________________________________________________________________ -; -;__________________________________________________________________________________________________ -PPK_GETDATA: -; -; GET RAW BYTE FROM KEYBOARD INTERFACE INTO A -; IF TIMEOUT, RETURN WITH A=0 AND Z SET -; - CALL PPK_CLKHI ; ALLOW KEYBOARD TO XMIT - CALL PPK_WTCLKLO ; WAIT FOR CLOCK LINE TO GO LOW - JP NZ,PPK_GETDATA1 ; IF IT WENT LOW, READ THE BYTE - CALL PPK_CLKLO ; SUPPRESS KEYBOARD XMIT - XOR A ; SIGNAL TIMEOUT - RET - -PPK_GETDATA1: - CALL PPK_WTCLKHI ; WAIT FOR END OF START BIT - LD B,8 ; SAMPLE 8 TIMES - LD E,0 ; START WITH E=0 - -PPK_GETDATA2: - CALL PPK_WTCLKLO ; WAIT TILL CLOCK GOES LOW - IN A,(PPK_PPIB) ; SAMPLE THE DATA LINE - RRA ; MOVE THE DATA BIT INTO THE CARRY REGISTER - LD A,E ; GET THE BYTE WE ARE BUILDING IN E - RRA ; MOVE THE CARRY BIT INTO BIT 7 AND SHIFT RIGHT - LD E,A ; STORE IT BACK AFTER 8 CYCLES 1ST BIT READ WILL BE IN B0 - CALL PPK_WTCLKHI ; WAIT TILL GOES HIGH - DJNZ PPK_GETDATA2 ; DO THIS 8 TIMES - CALL PPK_WTCLKLO ; GET THE PARITY BIT - CALL PPK_WTCLKHI - CALL PPK_WTCLKLO ; GET THE STOP BIT - CALL PPK_WTCLKHI - CALL PPK_CLKLO ; SUPPRESS KEYBOARD XMIT - LD A,E ; RETURN WITH RAW SCANCODE BYTE IN A - -#IF (PPKTRACE >= 2) - CALL PC_SPACE - CALL PC_LT - CALL PRTHEXBYTE -#ENDIF - - OR A - RET -; -;__________________________________________________________________________________________________ -PPK_PUTDATA: -; -; PUT A RAW BYTE FROM A TO THE KEYBOARD INTERFACE -; - LD E,A ; STASH INCOMING BYTE VALUE IN E - -#IF (PPKTRACE >= 2) - CALL PC_SPACE - CALL PC_GT - CALL PRTHEXBYTE -#ENDIF - - ; START WITH DATA HI AND CLOCK LOW - CALL PPK_DATHI - CALL PPK_CLKLO ; NEED CLOCK LOW TO GET DEVICE ATTENTION - - ; WAIT 100US TO MAKE SURE DEVICE IS READY TO RECEIVE - LD B,PPK_WAITRDY ; WAIT 100US - DJNZ $ ; SPIN - - ; SEND START BIT - CALL PPK_DATLO ; SET DATA LOW - REQUEST TO SEND/START BIT - CALL PPK_CLKHI ; RELEASE THE CLOCK LINE - CALL PPK_WTCLKLO ; DEVICE HAS RECEIVED THE START BIT - - ; SEND DATA BITS - LD B,8 ; 8 DATA BITS -PPK_PUTDATA1: - RRC E ; ROTATE LOW BIT OF E TO CARRY (NEXT BIT TO SEND) - LD A,PPK_DAT >> 1 ; INIT A WITH DATA MASK SHIFTED RIGHT BY ONE BIT - RLA ; SHIFT CARRY INTO LOW BIT OF A - OUT (PPK_PPIX),A ; SET/RESET DATA LINE FOR NEXT BIT VALUE - CALL PPK_WTCLKHI ; WAIT FOR CLOCK TO TRANSTION HI - CALL PPK_WTCLKLO ; THEN LO, BIT HAS NOW BEEN RECEIVED BY DEVICE - DJNZ PPK_PUTDATA1 ; LOOP TO SEND 8 DATA BITS - - ; SEND PARITY BIT - XOR A ; CLEAR A - OR E ; OR WITH SENT VALUE, SETS PARITY FLAG! - LD A,PPK_DAT ; PREPARE A WITH DATA MASK - JP PO,PPK_PUTDATA2 ; PARITY IS ALREADY ODD, LEAVE A ALONE - INC A ; SET PARITY BIT BY INCREMENTING A -PPK_PUTDATA2: - OUT (PPK_PPIX),A ; SET THE DATA LINE - CALL PPK_WTCLKHI ; WAIT FOR CLOCK TO TRANSITION HI - CALL PPK_WTCLKLO ; THEN LO, BIT HAS NOW BEEN RECEIVED BY DEVICE - - ; SEND STOP BIT, NO NEED TO WATCH CLOCK, JUST WAIT FOR START OF DEVICE ACK - CALL PPK_DATHI ; STOP BIT IS 1 (HI) - - ; HANDLE DEVICE ACK - CALL PPK_WTDATLO ; WAIT FOR DEVICE TO START ACK - CALL PPK_WTCLKLO ; WAIT FOR CLOCK TO TRANSITION LO - CALL PPK_WTCLKHI ; THEN HI - CALL PPK_WTDATHI ; FINALLY WAIT FOR DEVICE TO RELEASE DATA LINE - - ; ASSERT CLOCK TO INHIBIT DEVICE FROM SENDING US ANYTHING UNTIL WE ARE READY - CALL PPK_CLKLO ; SET CLOCK LOW - - RET -; -;__________________________________________________________________________________________________ -PPK_INITPORT: -; -; INITIALIZE PPI -; - LD A,10000010B ; A=OUT B=IN, C HIGH=OUT, CLOW=OUT - OUT (PPK_PPIX),A ; SET PPI CONTROL PORT - XOR A ; A=0 - OUT (PPK_PPIA),A ; PPI PORT A TO ZERO (REQUIRED FOR PAR PRINTER) - CALL PPK_DATHI ; KBD DATA LINE HI (IDLE) - CALL PPK_CLKHI ; KBD CLOCK LINE HI (IDLE) - RET -; -;__________________________________________________________________________________________________ -; -; BIT TESTING (PORT B) -; -; B:0 = KBD DATA LINE (INPUT) -; B:1 = KBD CLOCK LINE (INPUT) -; -; TEST PPI PORT B BIT(S) DESIGNATED BY BITMASK IN D AFTER XOR WITH E -; WAIT FOR ANY OF THE DESIGNATED BITS TO BE SET, THEN RETURN -; IF TIMEOUT, RETURN WITH A=0 AND Z SET -; HL IS DESTROYED, A IS OVERWRITTEN WITH RETURN VALUE -; -PPK_WTCLKLO: ; WAIT FOR CLOCK LINE TO BE LOW - PUSH DE - LD DE,0202H ; TEST BIT 1 AFTER INVERTING - JR PPK_WAIT -; -PPK_WTCLKHI: ; WAIT FOR CLOCK LINE TO BE HIGH - PUSH DE - LD DE,0200H ; TEST BIT 1 - JR PPK_WAIT -; -PPK_WTDATLO: ; WAIT FOR DATA LINE TO BE LOW - PUSH DE - LD DE,0101H ; TEST BIT 0 AFTER INVERTING - JR PPK_WAIT -; -PPK_WTDATHI: ; WAIT FOR DATA LINE TO BE HIGH - PUSH DE - LD DE,0100H ; TEST BIT 0 - JR PPK_WAIT -; -PPK_WAIT: ; COMPLETE THE WAIT PROCESSING - LD HL,PPK_WAITTO -PPK_WAIT1: - IN A,(PPK_PPIB) ; GET BYTE FROM PORT B - XOR E - AND D - JR NZ,PPK_WAIT2 ; EXIT IF ANY BIT IS SET - DEC HL - LD A,H - OR L - JR NZ,PPK_WAIT1 -PPK_WAIT2: - POP DE - RET -; -;__________________________________________________________________________________________________ -; -; BIT MANAGEMENT (PORT C) -; -; C:4 = KBD DATA LINE (LATCHED OUTPUT) -; C:5 = KBD CLOCK LINE (LATCHED OUTPUT) -; -; A IS DESTROYED (OVERWRITTEN WITH PORT OUTPUT VALUE) -; -PPK_DATHI: - LD A,PPK_DAT + 1 - JR PPK_SETBIT -PPK_DATLO: - LD A,PPK_DAT - JR PPK_SETBIT -PPK_CLKHI: - LD A,PPK_CLK + 1 - JR PPK_SETBIT -PPK_CLKLO: - LD A,PPK_CLK - JR PPK_SETBIT -PPK_SETBIT: - OUT (PPK_PPIX),A - RET -; -;__________________________________________________________________________________________________ -; RESET KEYBOARD -;__________________________________________________________________________________________________ -; -PPK_RESET: - LD A,$FF ; RESET COMMAND - CALL PPK_PUTDATA ; SEND IT - CALL PPK_GETDATA ; GET THE ACK - LD B,0 ; SETUP LOOP COUNTER -PPK_RESET0: - PUSH BC ; PRESERVE COUNTER - CALL DELAY ; DELAY 25MS - CALL PPK_GETDATA ; TRY TO GET THE RESPONSE - POP BC ; RECOVER COUNTER - JR NZ,PPK_RESET1 ; GOT A BYTE? IF SO, GET OUT OF LOOP - DJNZ PPK_RESET0 ; LOOP TILL COUNTER EXHAUSTED -PPK_RESET1: - LD A,B - XOR A ; SIGNAL SUCCESS (RESPONSE IS IGNORED...) - RET ; DONE -; -;__________________________________________________________________________________________________ -; UPDATE KEYBOARD LEDS BASED ON CURRENT TOGGLE FLAGS -;__________________________________________________________________________________________________ -; -PPK_SETLEDS: - LD A,$ED ; SET/RESET LED'S COMMAND - CALL PPK_PUTDATA ; SEND THE COMMAND - CALL PPK_GETDATA ; READ THE RESPONSE - CP $FA ; MAKE SURE WE GET ACK - RET NZ ; ABORT IF NO ACK - LD A,(PPK_STATE) ; LOAD THE STATE BYTE - RRCA ; ROTATE TOGGLE KEY BITS AS NEEDED - RRCA - RRCA - RRCA - AND $07 ; CLEAR THE IRRELEVANT BITS - CALL PPK_PUTDATA ; SEND THE LED DATA - CALL PPK_GETDATA ; READ THE ACK - JP PPK_DECNEW ; RESTART DECODER FOR A NEW KEY - RET ; DONE -; -;__________________________________________________________________________________________________ -; UPDATE KEYBOARD REPEAT RATE BASED ON CURRENT SETTING -;__________________________________________________________________________________________________ -; -PPK_SETRPT: - LD A,$F3 ; COMMAND = SET TYPEMATIC RATE/DELAY - CALL PPK_PUTDATA ; SEND IT - CALL PPK_GETDATA ; GET THE ACK - CP $FA ; MAKE SURE WE GET ACK - RET NZ ; ABORT IF NO ACK - LD A,(PPK_REPEAT) ; LOAD THE CURRENT RATE/DELAY BYTE - CALL PPK_PUTDATA ; SEND IT - CALL PPK_GETDATA ; GET THE ACK - RET -; -;__________________________________________________________________________________________________ -; DECODING ENGINE -;__________________________________________________________________________________________________ -; -;__________________________________________________________________________________________________ -PPK_DECODE: -; -; RUN THE DECODING ENGINE UNTIL EITHER: 1) NO MORE SCANCODES ARE AVAILABLE -; FROM THE KEYBOARD, OR 2) A DECODED KEY VALUE IS AVAILABLE -; -; RETURNS A=0 AND Z SET IF NO KEYCODE READY, OTHERWISE A DECODED KEY VALUE IS AVAILABLE. -; THE DECODED KEY VALUE AND KEY STATE IS STORED IN PPK_KEYCODE AND PPK_STATE. -; -; PPK_STATUS IS NOT CLEARED AT START. IT IS THE CALLER'S RESPONSIBILITY -; TO CLEAR PPK_STATUS WHEN IT HAS RETRIEVED A PENDING VALUE. IF DECODE IS CALLED -; WITH A KEYCODE STILL PENDING, IT WILL JUST RETURN WITHOUT DOING ANYTHING. -; -; Step 0: Check keycode buffer -; if status[keyrdy] -; return -; -; Step 1: Get scancode -; if no scancode ready -; return -; read scancode -; -; Step 2: Detect and handle special keycodes -; if scancode == $AA -; *** handle hot insert somehow *** -; -; Step 3: Detect and handle scancode prefixes -; if scancode == $E0 -; set status[extended] -; goto Step 1 -; -; if scancode == $E1 -; *** handle pause key somehow *** -; -; Step 4: Detect and flag break event -; *** scancode set #1 variation *** -; set status[break] = high bit of scancode -; clear high order bit -; continue to Step 5 -; *** scancode set #2 variation *** -; if scancode == $F0 -; set status[break] -; goto Step 1 -; -; Step 5: Map scancode to keycode -; if status[extended] -; apply extended-map[scancode] -> keycode -; else if state[shifted] -; apply shifted-map[scancode] -> keycode -; else -; apply normal-map[scancode] -> keycode -; -; Step 6: Handle modifier keys -; if keycode is modifier (shift, ctrl, alt, win) -; set (l/r)state[] = not status[break] -; clear modifier bits in state -; set state = (lstate OR rstate OR state) -; goto New Key -; -; Step 7: Complete procesing of key break events -; if status[break] -; goto New Key -; -; Step 8: Handle toggle keys -; if keycode is toggle (capslock, numlock, scrolllock) -; invert (XOR) state[] -; update keyboard LED's -; goto New Key -; -; Step 9: Adjust keycode for control modifier -; if state[ctrl] -; if keycode is 'a'-'z' -; subtract 20 (clear bit 5) from keycode -; if keycode is '@'-'_' -; subtract 40 (clear bit 6) from keycode -; -; Step 10: Adjust keycode for caps lock -; if state[capslock] -; if keycode is 'a'-'z' OR 'A'-'Z' -; toggle (XOR) bit 5 of keycode -; -; Step 11: Handle num pad keys -; clear state[numpad] -; if keycode is numpad -; set state[numpad] -; if state[numlock] -; toggle (XOR) bit 4 of keycode -; apply numpad-map[keycode] -> keycode -; -; Step 12: Detect unknown/invalid keycodes -; if keycode == $FF -; goto New Key -; -; Step 13: Done -; set status[keyrdy] -; return -; -; New Key: -; clear status -; goto Step 1 -; -PPK_DEC0: ; CHECK KEYCODE BUFFER - LD A,(PPK_STATUS) ; GET CURRENT STATUS - AND PPK_KEYRDY ; ISOLATE KEY READY FLAG - RET NZ ; ABORT IF KEY IS ALREADY PENDING - -PPK_DEC1: ; PROCESS NEXT SCANCODE - CALL PPK_GETDATA ; GET THE SCANCODE - RET Z ; TIMEOUT, RETURN WITH A=0, Z SET - LD (PPK_SCANCODE),A ; SAVE SCANCODE - -PPK_DEC2: ; DETECT AND HANDLE SPECIAL KEYCODES - LD A,(PPK_SCANCODE) ; GET THE CURRENT SCANCODE - CP $AA ; KEYBOARD INSERTION? - JR NZ,PPK_DEC3 ; NOPE, BYPASS - CALL LDELAY ; WAIT A BIT - CALL PPK_RESET ; RESET KEYBOARD - CALL PPK_SETLEDS ; SET LEDS - CALL PPK_SETRPT ; SET REPEAT RATE - JP PPK_DECNEW ; RESTART THE ENGINE - -PPK_DEC3: ; DETECT AND HANDLE SCANCODE PREFIXES - LD A,(PPK_SCANCODE) ; GET THE CURRENT SCANCODE - -PPK_DEC3A: ; HANDLE SCANCODE PREFIX $E0 (EXTENDED SCANCODE FOLLOWS) - CP $E0 ; EXTENDED KEY PREFIX $E0? - JR NZ,PPK_DEC3B ; NOPE MOVE ON - LD A,(PPK_STATUS) ; GET STATUS - OR PPK_EXT ; SET EXTENDED BIT - LD (PPK_STATUS),A ; SAVE STATUS - JR PPK_DEC1 ; LOOP TO DO NEXT SCANCODE - -PPK_DEC3B: ; HANDLE SCANCODE PREFIX $E1 (PAUSE KEY) - CP $E1 ; EXTENDED KEY PREFIX $E1 - JR NZ,PPK_DEC4 ; NOPE MOVE ON - LD A,$EE ; MAP TO KEYCODE $EE - LD (PPK_KEYCODE),A ; SAVE IT - ; SWALLOW NEXT 7 SCANCODES - LD B,7 ; LOOP 5 TIMES -PPK_DEC3B1: - PUSH BC - CALL PPK_GETDATA ; RETRIEVE NEXT SCANCODE - POP BC - DJNZ PPK_DEC3B1 ; LOOP AS NEEDED - JP PPK_DEC6 ; RESUME AFTER MAPPING - -PPK_DEC4: ; DETECT AND FLAG BREAK EVENT - CP $F0 ; BREAK (KEY UP) PREFIX? - JR NZ,PPK_DEC5 ; NOPE MOVE ON - LD A,(PPK_STATUS) ; GET STATUS - OR PPK_BREAK ; SET BREAK BIT - LD (PPK_STATUS),A ; SAVE STATUS - JR PPK_DEC1 ; LOOP TO DO NEXT SCANCODE - -PPK_DEC5: ; MAP SCANCODE TO KEYCODE - LD A,(PPK_STATUS) ; GET STATUS - AND PPK_EXT ; EXTENDED BIT SET? - JR Z,PPK_DEC5C ; NOPE, MOVE ON - - ; PERFORM EXTENDED KEY MAPPING - LD A,(PPK_SCANCODE) ; GET SCANCODE - LD E,A ; STASH IT IN E - LD HL,PPK_MAPEXT ; POINT TO START OF EXT MAP TABLE -PPK_DEC5A: - LD A,(HL) ; GET FIRST BYTE OF PAIR - CP $00 ; END OF TABLE? - JP Z,PPK_DECNEW ; UNKNOWN OR BOGUS, START OVER - INC HL ; INC HL FOR FUTURE - CP E ; DOES MATCH BYTE EQUAL SCANCODE? - JR Z,PPK_DEC5B ; YES! JUMP OUT - INC HL ; BUMP TO START OF NEXT PAIR - JR PPK_DEC5A ; LOOP TO CHECK NEXT TABLE ENTRY -PPK_DEC5B: - LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE - LD (PPK_KEYCODE),A ; SAVE IT - JR PPK_DEC6 - -PPK_DEC5C: ; PERFORM REGULAR KEY (NOT EXTENDED) KEY MAPPING - LD A,(PPK_SCANCODE) ; GET THE SCANCODE - CP PPK_MAPSIZ ; COMPARE TO SIZE OF TABLE - JR NC,PPK_DEC6 ; PAST END, SKIP OVER LOOKUP - - ; SETUP POINTER TO MAPPING TABLE BASED ON SHIFTED OR UNSHIFTED STATE - LD A,(PPK_STATE) ; GET STATE - AND PPK_SHIFT ; SHIFT ACTIVE? - LD HL,PPK_MAPSTD ; LOAD ADDRESS OF NON-SHIFTED MAPPING TABLE - JR Z,PPK_DEC5D ; NON-SHIFTED, MOVE ON - LD HL,PPK_MAPSHIFT ; LOAD ADDRESS OF SHIFTED MAPPING TABLE -PPK_DEC5D: - LD A,(PPK_SCANCODE) ; GET THE SCANCODE - LD E,A ; SCANCODE TO E FOR TABLE OFFSET - LD D,0 ; D -> 0 - ADD HL,DE ; COMMIT THE TABLE OFFSET TO HL - LD A,(HL) ; GET THE KEYCODE VIA MAPPING TABLE - LD (PPK_KEYCODE),A ; SAVE IT - -PPK_DEC6: ; HANDLE MODIFIER KEYS - LD A,(PPK_KEYCODE) ; MAKE SURE WE HAVE KEYCODE - CP $B8 ; END OF MODIFIER KEYS - JR NC,PPK_DEC7 ; BYPASS MODIFIER KEY CHECKING - CP $B0 ; START OF MODIFIER KEYS - JR C,PPK_DEC7 ; BYPASS MODIFIER KEY CHECKING - - LD B,4 ; LOOP COUNTER TO LOOP THRU 4 MODIFIER BITS - LD E,$80 ; SETUP E TO ROATE THROUGH MODIFIER STATE BITS - SUB $B0 - 1 ; SETUP A TO DECREMENT THROUGH MODIFIER VALUES - -PPK_DEC6A: - RLC E ; SHIFT TO NEXT MODIFIER STATE BIT - DEC A ; L-MODIFIER? - JR Z,PPK_DEC6B ; YES, HANDLE L-MODIFIER MAKE/BREAK - DEC A ; R-MODIFIER? - JR Z,PPK_DEC6C ; YES, HANDLE R-MODIFIER MAKE/BREAK - DJNZ PPK_DEC6A ; LOOP THRU 4 MODIFIER BITS - JR PPK_DEC7 ; FAILSAFE, SHOULD NEVER GET HERE! - -PPK_DEC6B: ; LEFT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) - LD HL,PPK_LSTATE ; POINT TO LEFT STATE BYTE - JR PPK_DEC6D ; CONTINUE - -PPK_DEC6C: ; RIGHT STATE KEY MAKE/BREAK (STATE BIT TO SET/CLEAR IN E) - LD HL,PPK_RSTATE ; POINT TO RIGHT STATE BYTE - JR PPK_DEC6D ; CONTINUE - -PPK_DEC6D: ; BRANCH BASED ON WHETHER THIS IS A MAKE OR BREAK EVENT - LD A,(PPK_STATUS) ; GET STATUS FLAGS - AND PPK_BREAK ; BREAK EVENT? - JR Z,PPK_DEC6E ; NO, HANDLE A MODIFIER KEY MAKE EVENT - JR PPK_DEC6F ; YES, HANDLE A MODIFIER BREAK EVENT - -PPK_DEC6E: ; HANDLE STATE KEY MAKE EVENT - LD A,E ; GET THE BIT TO SET - OR (HL) ; OR IN THE CURRENT BITS - LD (HL),A ; SAVE THE RESULT - JR PPK_DEC6G ; CONTINUE - -PPK_DEC6F: ; HANDLE STATE KEY BREAK EVENT - LD A,E ; GET THE BIT TO CLEAR - XOR $FF ; FLIP ALL BITS TO SETUP FOR A CLEAR OPERATION - AND (HL) ; AND IN THE FLIPPED BITS TO CLEAR DESIRED BIT - LD (HL),A ; SAVE THE RESULT - JR PPK_DEC6G ; CONTINUE - -PPK_DEC6G: ; COALESCE L/R STATE FLAGS - LD A,(PPK_STATE) ; GET EXISTING STATE BITS - AND $F0 ; GET RID OF OLD MODIFIER BITS - LD DE,(PPK_LSTATE) ; LOAD BOTH L/R STATE BYTES IN D/E - OR E ; MERGE IN LEFT STATE BITS - OR D ; MERGE IN RIGHT STATE BITS - LD (PPK_STATE),A ; SAVE IT - JP PPK_DECNEW ; DONE WITH CURRENT KEYSTROKE - -PPK_DEC7: ; COMPLETE PROCESSING OF EXTENDED AND KEY BREAK EVENTS - LD A,(PPK_STATUS) ; GET CURRENT STATUS FLAGS - AND PPK_BREAK ; IS THIS A KEY BREAK EVENT? - JP NZ,PPK_DECNEW ; PROCESS NEXT KEY - -PPK_DEC8: ; HANDLE TOGGLE KEYS - LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE INTO A - LD E,PPK_CAPSLCK ; SETUP E WITH CAPS LOCK STATE BIT - CP $BC ; IS THIS THE CAPS LOCK KEY? - JR Z,PPK_DEC8A ; YES, GO TO BIT SET ROUTINE - LD E,PPK_NUMLCK ; SETUP E WITH NUM LOCK STATE BIT - CP $BD ; IS THIS THE NUM LOCK KEY? - JR Z,PPK_DEC8A ; YES, GO TO BIT SET ROUTINE - LD E,PPK_SCRLCK ; SETUP E WITH SCROLL LOCK STATE BIT - CP $BE ; IS THIS THE SCROLL LOCK KEY? - JR Z,PPK_DEC8A ; YES, GO TO BIT SET ROUTINE - JR PPK_DEC9 ; NOT A TOGGLE KEY, CONTINUE - -PPK_DEC8A: ; RECORD THE TOGGLE - LD A,(PPK_STATE) ; GET THE CURRENT STATE FLAGS - XOR E ; SET THE TOGGLE KEY BIT FROM ABOVE - LD (PPK_STATE),A ; SAVE IT - CALL PPK_SETLEDS ; UPDATE LED LIGHTS ON KBD - JP PPK_DECNEW ; RESTART DECODER FOR A NEW KEY - -PPK_DEC9: ; ADJUST KEYCODE FOR CONTROL MODIFIER - LD A,(PPK_STATE) ; GET THE CURRENT STATE BITS - AND PPK_CTRL ; CHECK THE CONTROL BIT - JR Z,PPK_DEC10 ; CONTROL KEY NOT PRESSED, MOVE ON - LD A,(PPK_KEYCODE) ; GET CURRENT KEYCODE IN A - CP 'a' ; COMPARE TO LOWERCASE A - JR C,PPK_DEC9A ; BELOW IT, BYPASS - CP 'z' + 1 ; COMPARE TO LOWERCASE Z - JR NC,PPK_DEC9A ; ABOVE IT, BYPASS - RES 5,A ; KEYCODE IN LOWERCASE A-Z RANGE CLEAR BIT 5 TO MAKE IT UPPERCASE -PPK_DEC9A: - CP '@' ; COMPARE TO @ - JR C,PPK_DEC10 ; BELOW IT, BYPASS - CP '_' + 1 ; COMPARE TO _ - JR NC,PPK_DEC10 ; ABOVE IT, BYPASS - RES 6,A ; CONVERT TO CONTROL VALUE BY CLEARING BIT 6 - LD (PPK_KEYCODE),A ; UPDATE KEYCODE TO CONTROL VALUE - -PPK_DEC10: ; ADJUST KEYCODE FOR CAPS LOCK - LD A,(PPK_STATE) ; LOAD THE STATE FLAGS - AND PPK_CAPSLCK ; CHECK CAPS LOCK - JR Z,PPK_DEC11 ; CAPS LOCK NOT ACTIVE, MOVE ON - LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE VALUE - CP 'a' ; COMPARE TO LOWERCASE A - JR C,PPK_DEC10A ; BELOW IT, BYPASS - CP 'z' + 1 ; COMPARE TO LOWERCASE Z - JR NC,PPK_DEC10A ; ABOVE IT, BYPASS - JR PPK_DEC10B ; IN RANGE LOWERCASE A-Z, GO TO CASE SWAPPING LOGIC -PPK_DEC10A: - CP 'A' ; COMPARE TO UPPERCASE A - JR C,PPK_DEC11 ; BELOW IT, BYPASS - CP 'Z' + 1 ; COMPARE TO UPPERCASE Z - JR NC,PPK_DEC11 ; ABOVE IT, BYPASS - JR PPK_DEC10B ; IN RANGE UPPERCASE A-Z, GO TO CASE SWAPPING LOGIC -PPK_DEC10B: - LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE - XOR $20 ; FLIP BIT 5 TO SWAP UPPER/LOWER CASE - LD (PPK_KEYCODE),A ; SAVE IT - -PPK_DEC11: ; HANDLE NUM PAD KEYS - LD A,(PPK_STATE) ; GET THE CURRENT STATE FLAGS - AND ~PPK_NUMPAD ; ASSUME NOT A NUMPAD KEY, CLEAR THE NUMPAD BIT - LD (PPK_STATE),A ; SAVE IT - - LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE - AND 11100000B ; ISOLATE TOP 3 BITS - CP 11000000B ; IS IN NUMPAD RANGE? - JR NZ,PPK_DEC12 ; NOPE, GET OUT - - LD A,(PPK_STATE) ; LOAD THE CURRENT STATE FLAGS - OR PPK_NUMPAD ; TURN ON THE NUMPAD BIT - LD (PPK_STATE),A ; SAVE IT - - AND PPK_NUMLCK ; IS NUM LOCK BIT SET? - JR Z,PPK_DEC11A ; NO, SKIP NUMLOCK PROCESSING - LD A,(PPK_KEYCODE) ; GET THE KEYCODE - XOR $10 ; FLIP VALUES FOR NUMLOCK - LD (PPK_KEYCODE),A ; SAVE IT - -PPK_DEC11A: ; APPLY NUMPAD MAPPING - LD A,(PPK_KEYCODE) ; GET THE CURRENT KEYCODE - LD HL,PPK_MAPNUMPAD ; LOAD THE START OF THE MAPPING TABLE - SUB $C0 ; KEYCODES START AT $C0 - LD E,A ; INDEX TO E - LD D,0 ; D IS ZERO - ADD HL,DE ; POINT TO RESULT OF MAPPING - LD A,(HL) ; GET IT IN A - LD (PPK_KEYCODE),A ; SAVE IT - -PPK_DEC12: ; DETECT UNKNOWN/INVALID KEYCODES - LD A,(PPK_KEYCODE) ; GET THE FINAL KEYCODE - CP $FF ; IS IT $FF (UNKNOWN/INVALID) - JP Z,PPK_DECNEW ; IF SO, JUST RESTART THE ENGINE - -PPK_DEC13: ; DONE - RECORD RESULTS - LD A,(PPK_STATUS) ; GET CURRENT STATUS - OR PPK_KEYRDY ; SET KEY READY BIT - LD (PPK_STATUS),A ; SAVE IT - XOR A ; A=0 - INC A ; SIGNAL SUCCESS WITH A=1 - RET - -PPK_DECNEW: ; START NEW KEYPRESS (CLEAR ALL STATUS BITS) - XOR A ; A = 0 - LD (PPK_STATUS),A ; CLEAR STATUS - JP PPK_DEC1 ; RESTART THE ENGINE -; -;__________________________________________________________________________________________________ -; MAPPING TABLES -;__________________________________________________________________________________________________ -; -PPK_MAPSTD: ; SCANCODE IS INDEX INTO TABLE TO RESULTANT LOOKUP KEYCODE - .DB $FF,$E8,$FF,$E4,$E2,$E0,$E1,$EB,$FF,$E9,$E7,$E5,$E3,$09,'`',$FF - .DB $FF,$B4,$B0,$FF,$B2,'q','1',$FF,$FF,$FF,'z','s','a','w','2',$FF - .DB $FF,'c','x','d','e','4','3',$FF,$FF,' ','v','f','t','r','5',$FF - .DB $FF,'n','b','h','g','y','6',$FF,$FF,$FF,'m','j','u','7','8',$FF - .DB $FF,',','k','i','o','0','9',$FF,$FF,'.','/','l',';','p','-',$FF - .DB $FF,$FF,$27,$FF,'[','=',$FF,$FF,$BC,$B1,$0D,']',$FF,'\',$FF,$FF - .DB $FF,$FF,$FF,$FF,$FF,$FF,$08,$FF,$FF,$C0,$FF,$C3,$C6,$FF,$FF,$FF - .DB $C9,$CA,$C1,$C4,$C5,$C7,$1B,$BD,$FA,$CE,$C2,$CD,$CC,$C8,$BE,$FF - .DB $FF,$FF,$FF,$E6,$EC -; -PPK_MAPSIZ .EQU ($ - PPK_MAPSTD) -; -PPK_MAPSHIFT: ; SCANCODE IS INDEX INTO TABLE TO RESULTANT LOOKUP KEYCODE WHEN SHIFT ACTIVE - .DB $FF,$E8,$FF,$E4,$E2,$E0,$E1,$EB,$FF,$E9,$E7,$E5,$E3,$09,'~',$FF - .DB $FF,$B4,$B0,$FF,$B2,'Q','!',$FF,$FF,$FF,'Z','S','A','W','@',$FF - .DB $FF,'C','X','D','E','$','#',$FF,$FF,' ','V','F','T','R','%',$FF - .DB $FF,'N','B','H','G','Y','^',$FF,$FF,$FF,'M','J','U','&','*',$FF - .DB $FF,'<','K','I','O',')','(',$FF,$FF,'>','?','L',':','P','_',$FF - .DB $FF,$FF,$22,$FF,'{','+',$FF,$FF,$BC,$B1,$0D,'}',$FF,'|',$FF,$FF - .DB $FF,$FF,$FF,$FF,$FF,$FF,$08,$FF,$FF,$D0,$FF,$D3,$D6,$FF,$FF,$FF - .DB $D9,$DA,$D1,$D4,$D5,$D7,$1B,$BD,$FA,$DE,$D2,$DD,$DC,$D8,$BE,$FF - .DB $FF,$FF,$FF,$E6,$EC -; -PPK_MAPEXT: ; PAIRS ARE [SCANCODE,KEYCODE] FOR EXTENDED SCANCODES - .DB $11,$B5, $14,$B3, $1F,$B6, $27,$B7 - .DB $2F,$EF, $37,$FA, $3F,$FB, $4A,$CB - .DB $5A,$CF, $5E,$FC, $69,$F3, $6B,$F8 - .DB $6C,$F2, $70,$F0, $71,$F1, $72,$F7 - .DB $74,$F9, $75,$F6, $7A,$F5, $7C,$ED - .DB $7D,$F4, $7E,$FD, $00,$00 -; -PPK_MAPNUMPAD: ; KEYCODE TRANSLATION FROM NUMPAD RANGE TO STD ASCII/KEYCODES - .DB $F3,$F7,$F5,$F8,$FF,$F9,$F2,$F6,$F4,$F0,$F1,$2F,$2A,$2D,$2B,$0D - .DB $31,$32,$33,$34,$35,$36,$37,$38,$39,$30,$2E,$2F,$2A,$2D,$2B,$0D -; -;__________________________________________________________________________________________________ -; KEYCODE VALUES RETURNED BY THE DECODER -;__________________________________________________________________________________________________ -; -; VALUES 0-127 ARE STANDARD ASCII, SPECIAL KEYS WILL HAVE THE FOLLOWING VALUES: -; -; F1 $E0 -; F2 $E1 -; F3 $E2 -; F4 $E3 -; F5 $E4 -; F6 $E5 -; F7 $E6 -; F8 $E7 -; F9 $E8 -; F10 $E9 -; F11 $EA -; F12 $EB -; SYSRQ $EC -; PRTSC $ED -; PAUSE $EE -; APP $EF -; INS $F0 -; DEL $F1 -; HOME $F2 -; END $F3 -; PGUP $F4 -; PGDN $F5 -; UP $F6 -; DOWN $F7 -; LEFT $F8 -; RIGHT $F9 -; POWER $FA -; SLEEP $FB -; WAKE $FC -; BREAK $FD diff --git a/branches/s100/Source/ppp.asm b/branches/s100/Source/ppp.asm deleted file mode 100644 index 9d4cb29a..00000000 --- a/branches/s100/Source/ppp.asm +++ /dev/null @@ -1,474 +0,0 @@ -; -;================================================================================================== -; PARPORTPROP DRIVER -;================================================================================================== -; -; COMMAND BYTES -; -PPP_CMDNOP .EQU $00 ; DO NOTHING -PPP_CMDECHOBYTE .EQU $01 ; RECEIVE A BYTE, INVERT IT, SEND IT BACK -PPP_CMDECHOBUF .EQU $02 ; RECEIVE 512 BYTE BUFFER, SEND IT BACK -; -PPP_CMDDSKRES .EQU $10 ; RESTART SD CARD SUPPORT -PPP_CMDDSKSTAT .EQU $11 ; SEND LAST SD CARD STATUS (4 BYTES) -PPP_CMDDSKPUT .EQU $12 ; PPI -> SECTOR BUFFER -> PPP -PPP_CMDDSKGET .EQU $13 ; PPP -> SECTOR BUFFER -> PPI -PPP_CMDDSKRD .EQU $14 ; READ SCTOR FROM SD CARD INTO PPP BUFFER, RETURN 1 BYTE STATUS -PPP_CMDDSKWR .EQU $15 ; WRITE SECTOR TO SD CARD FROM PPP BUFFER, RETURN 1 BYTE STATUS -; -PPP_CMDVIDOUT .EQU $20 ; WRITE A BYTE TO THE TERMINAL EMULATOR -; -PPP_CMDKBDSTAT .EQU $30 ; RETURN A BYTE WITH NUMBER OF CHARACTERS IN BUFFER -PPP_CMDKBDRD .EQU $31 ; RETURN A CHARACTER, WAIT IF NECESSARY -; -PPP_CMDSPKTONE .EQU $40 ; EMIT SPEAKER TONE AT SPECIFIED FREQUENCY AND DURATION -; -PPP_CMDSIOINIT .EQU $50 ; RESET SERIAL PORT AND ESTABLISH A NEW BAUD RATE (4 BYTE BAUD RATE) -PPP_CMDSIORX .EQU $51 ; RECEIVE A BYTE IN FROM SERIAL PORT -PPP_CMDSIOTX .EQU $52 ; TRANSMIT A BYTE OUT OF THE SERIAL PORT -PPP_CMDSIORXST .EQU $53 ; SERIAL PORT RECEIVE STATUS (RETURNS # BYTES OF RX BUFFER USED) -PPP_CMDSIOTXST .EQU $54 ; SERIAL PORT TRANSMIT STATUS (RETURNS # BYTES OF TX BUFFER SPACE AVAILABLE) -PPP_CMDSIORXFL .EQU $55 ; SERIAL PORT RECEIVE BUFFER FLUSH -PPP_CMDSIOTXFL .EQU $56 ; SERIAL PORT TRANSMIT BUFFER FLUSH (NOT IMPLEMENTED) -; -PPP_CMDRESET .EQU $F0 ; SOFT RESET PROPELLER -; -; GLOBAL PARPORTPROP INITIALIZATION -; -PPP_INIT: - PRTS("PPP: RESET$") -; - LD A,$9B ; PPI MODE 0, ALL PINS INPUT - OUT (PPIX),A ; SEND IT - - LD A,11000010B ; PPI MODE 2 (BI HANDSHAKE), PC0-2 OUT, PB IN - OUT (PPIX),A - - CALL DELAY ; PROBABLY NOT NEEDED - - LD A,00000000B ; SET PC0 -> 0 - OUT (PPIX),A - LD A,00000010B ; SET PC1 -> 0 - OUT (PPIX),A - LD A,00000101B ; SET PC2 -> 1 - ASSERT RESET ON PPP - OUT (PPIX),A - LD A,00000110B ; SET PC3 -> 0 - OUT (PPIX),A - - CALL DELAY ; PROBABLY NOT NEEDED - - IN A,(PPIA) ; CLEAR GARBAGE??? - - CALL DELAY ; PROBABLY NOT NEEDED - - LD A,00000001B ; SET CMD FLAG - OUT (PPIX),A ; SEND IT - LD E,PPP_CMDRESET - CALL PUTBYTE ; SEND THE COMMAND BYTE - CALL DELAY - LD A,00000000B ; CLEAR CMD FLAG - OUT (PPIX),A - - LD A,00000100B ; SET PC2 -> 0 - DEASSERT RESET ON PPP - OUT (PPIX),A - - CALL DELAY ; PROBABLY NOT NEEDED - - LD BC,0 -INIT1: - PUSH BC - CALL DELAY - CALL DELAY - CALL DELAY - CALL DELAY - IN A,(PPIA) - POP BC - CP $AA - RET Z - DEC BC - LD A,B - OR C - JR NZ,INIT1 - - CALL NEWLINE - LD DE,PPPSTR_TIMEOUT - CALL WRITESTR - - CALL PPPSD_INIT ; SD CARD INITIALIZATION - - RET -; -;================================================================================================== -; PARPORTPROP CONSOLE DRIVER -;================================================================================================== -; -; DISPATCH FOR CONSOLE SUBFUNCTIONS -; -PPPCON_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,PPPCON_IN ; JUMP IF CHARACTER IN - DEC A ; NEXT SUBFUNCTION - JR Z,PPPCON_OUT ; JUMP IF CHARACTER OUT - DEC A ; NEXT SUBFUCNTION - JR Z,PPPCON_IST ; JUMP IF INPUT STATUS - DEC A ; NEXT SUBFUNCTION - JR Z,PPPCON_OST ; JUMP IF OUTPUT STATUS - CALL PANIC ; OTHERWISE SOMETHING IS BADLY BROKEN -; -; CHARACTER INPUT -; WAIT FOR A CHARACTER AND RETURN IT IN E -; -PPPCON_IN: - CALL PPPCON_IST ; CHECK FOR CHAR PENDING - JR Z,PPPCON_IN ; WAIT FOR IT IF NECESSARY - LD D,PPP_CMDKBDRD ; CMD = KEYBOARD READ - CALL SENDCMD ; SEND COMMAND - CALL GETBYTE ; GET CHARACTER READ - XOR A ; CLEAR A (SUCCESS) - RET ; AND RETURN -; -; CHARACTER INPUT STATUS -; RETURN STATUS IN A, 0 = NOTHING PENDING, > 0 CHAR PENDING -; -PPPCON_IST: - LD D,PPP_CMDKBDSTAT ; CMD = KEYBOARD STATUS - CALL SENDCMD ; SEND COMMAND - CALL GETBYTE ; GET RESPONSE - LD A,E ; MOVE IT TO A - OR A ; SET FLAGS - RET NZ ; A <> 0, CHAR(S) PENDING - JP CIO_IDLE ; OTHERWISE RET VIA IDLE PROCESSING -; -; CHARACTER OUTPUT -; WRITE CHARACTER IN E -; -PPPCON_OUT: - CALL PPPCON_OST ; CHECK FOR OUTPUT READY - JR Z,PPPCON_OUT ; WAIT IF NECESSARY - LD D,PPP_CMDVIDOUT ; CMD = VIDEO OUTPUT - CALL SENDCMD ; SEND COMMAND - CALL PUTBYTE ; SEND IT - RET ; RETURN -; -; CHARACTER OUTPUT STATUS -; RETURN STATUS IN A, 0 = NOT READY, > 0 READY TO SEND -; CONSOLE IS ALWAYS READY TO SEND (SYNCHRONOUS OUTPUT) -; -PPPCON_OST: - XOR A ; SET A=$01 TO SIGNAL READY - INC A - RET -; -;================================================================================================== -; PARPORTPROP SD CARD DRIVER -;================================================================================================== -; -PPPSD_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JP Z,PPPSD_READ ; READ - DEC A - JP Z,PPPSD_WRITE ; WRITE - DEC A - JP Z,PPPSD_STATUS ; STATUS - DEC A - JP Z,PPPSD_MEDIA ; MEDIA ID - CALL PANIC -; -; SETUP FOR SUBSEQUENT ACCESS -; INIT CARD IF NOT READY OR ON DRIVE LOG IN -; -PPPSD_MEDIA: - ; REINITIALIZE THE CARD HERE TO DETERMINE PRESENCE - CALL PPPSD_INITCARD - LD A,MID_NONE ; ASSUME FAILURE - RET NZ - - ; ALL IS WELL, RETURN MEDIA IDENTIFIER - LD A,MID_HD ; SET MEDIA ID - RET -; -; SD CARD INITIALIZATION -; -PPPSD_INIT: - ; MARK DRIVE NOT READY - ; HARDWARE INIT DEFERRED UNTIL DRIVE SELECT - XOR A - DEC A - LD (PPPSD_STAT),A - RET -; -; REPORT SD CARD READY STATE -; -PPPSD_STATUS: - LD A,(PPPSD_STAT) ; GET THE CURRENT READY STATUS - OR A - RET -; -; READ AN LBA BLOCK FROM THE SD CARD -; -PPPSD_READ: - CALL PPPSD_CHKCARD ; CHECK / REINIT CARD AS NEEDED - RET NZ ; BAIL OUT ON ERROR - - ; READ A SECTOR - CALL PPPSD_SETBLK ; SETUP PPP_LBA WITH BLOCK NUMBER - LD D,PPP_CMDDSKRD ; COMMAND = DSKWR - CALL SENDCMD ; SEND COMMAND - CALL PPPSD_SENDBLK ; SEND THE LBA BLOCK NUMBER - CALL GETBYTE - LD A,E - LD (PPPSD_STAT),A ; SAVE STATUS - CALL PPPSD_PRTREAD ; PRINT DIAGNOSTICS AS NEEDED - OR A ; SET FLAGS - RET NZ ; BAIL OUT ON ERROR - - ; GET THE SECTOR DATA - LD D,PPP_CMDDSKGET ; COMMAND = DSKGET - CALL SENDCMD ; SEND COMMAND - - ; READ THE SECTOR DATA - LD BC,512 - LD HL,(DIOBUF) -DSKREAD1: - CALL GETBYTE - LD (HL),E - INC HL - DEC BC - LD A,B - OR C - JP NZ,DSKREAD1 - - XOR A ; SUCCESS - RET -; -; WRITE AN LBA BLOCK TO THE SD CARD -; -PPPSD_WRITE: - CALL PPPSD_CHKCARD ; CHECK / REINIT CARD AS NEEDED - RET NZ ; BAIL OUT ON ERROR - - CALL PPPSD_SETBLK ; SETUP THE LBA BLOCK INDEX - - ; PUT THE SECTOR DATA - LD D,PPP_CMDDSKPUT ; COMMAND = DSKPUT - CALL SENDCMD ; SEND COMMAND - - ; SEND OVER THE SECTOR CONTENTS - LD BC,512 - LD HL,(DIOBUF) -DSKWRITE1: - LD E,(HL) - INC HL - CALL PUTBYTE - DEC BC - LD A,B - OR C - JP NZ,DSKWRITE1 - - ; WRITE THE SECTOR - LD D,PPP_CMDDSKWR ; COMMAND = DSKWR - CALL SENDCMD - CALL PPPSD_SENDBLK ; SEND THE LBA BLOCK NUMBER - CALL GETBYTE - LD A,E - LD (PPPSD_STAT),A ; SAVE STATUS - CALL PPPSD_PRTWRITE ; PRINT DIAGNOSTICS AS NEEDED - OR A ; SET FLAGS - RET ; ALL DONE -; -; REINITIALIZE THE SD CARD -; -PPPSD_INITCARD: - ; RESET & STATUS DISK - LD D,PPP_CMDDSKRES ; COMMAND = DSKRESET - CALL SENDCMD - CALL GETBYTE - LD A,E - LD (PPPSD_STAT),A ; SAVE UPDATED STATUS - OR A - RET ; Z/NZ SET, A HAS RESULT CODE -; -; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED -; -PPPSD_CHKCARD: - LD A,(PPPSD_STAT) ; GET STATUS - OR A ; SET FLAGS - CALL NZ,PPPSD_INITCARD ; INIT CARD IF NOT READY - RET ; RETURN WITH STATUS IN A -; -; SET UP LBA BLOCK INDEX BASED ON HSTTRK AND HSTSEC -; NOTE THAT BYTE ORDER IS LITTLE ENDIAN FOR PROPLELLER! -; SEE MAPPING IN COMMENTS -; NOTE THAT HSTSEC:MSB IS UNUSED -; -PPPSD_SETBLK: - LD HL,PPP_LBA + 3 ; WORK BACKWARDS, START WITH END OF LBA - XOR A ; MSB OF LBA IS ALWAYS ZERO - LD (HL),A ; LBAHI:MSB = 0 - DEC HL ; POINT TO NEXT BYTE - LD DE,(HSTTRK) ; DE = HSTTRK - LD (HL),D ; LBAHI:LSB = D = HSTTRK:MSB - DEC HL ; POINT TO NEXT BYTE - LD (HL),E ; LBALO:MSB = E = HSTTRK:LSB - DEC HL ; POINT TO NEXT BYTE - LD A,(HSTSEC) ; A = HSTSEC:LSB - LD (HL),A ; LBALO:LSB = A = HSTSEC:LSB - RET -; -; SEND INDEX OF BLOCK TO READ FROM SD CARD -; 32 BIT VALUE (4 BYTES) -; NOTE THAT BYTES ARE SENT REVERSED, PROPELLER IS LITTLE ENDIAN -; -PPPSD_SENDBLK: - LD HL,PPP_LBA - LD B,4 -PPPSD_SENDBLK1: - LD E,(HL) - INC HL - CALL PUTBYTE - DJNZ PPPSD_SENDBLK1 - RET -; -; PRINT DIAGNOSTICS AFTER COMMAND EXECUTION -; -PPPSD_PRTREAD: - LD DE,PPPSTR_READ - JR PPPSD_PRT - -PPPSD_PRTWRITE: - LD DE,PPPSTR_WRITE - JR PPPSD_PRT - -PPPSD_PRT: - OR A -#IF (PPPSDTRACE == 0) - RET -#ELSE -#IF (PPPSDTRACE == 1) - RET Z -#ENDIF - PUSH AF - CALL NEWLINE - LD DE,PPPSTR_PREFIX ; PRINT DRIVER PREFIX - CALL WRITESTR - CALL PC_SPACE - CALL WRITESTR ; PRINT FUNCTION - CALL PPPSD_PRTBLK ; PRINT BLOCK NUMBER - CALL PC_SPACE - LD DE,PPPSTR_ARROW ; PRINT ARROW - CALL WRITESTR - CALL PC_SPACE - POP AF - PUSH AF - CALL PRTHEXBYTE ; PRINT RESULT BYTE - CALL NZ,PPPSD_PRTERR ; PRINT DETAILED ERROR VALUE IF APPROPRIATE - POP AF - RET ; RET WITH A = STATUS - -PPPSD_PRTBLK: - CALL PC_SPACE - LD HL,PPP_LBA + 4 - LD B,4 -PPPSD_PRTBLK1: - DEC HL - LD A,(HL) - CALL PRTHEXBYTE - DJNZ PPPSD_PRTBLK1 - RET - -PPPSD_PRTERR: - LD D,PPP_CMDDSKSTAT - CALL SENDCMD - - LD HL,PPP_DSKSTAT - LD B,4 -PPPSD_PRTERR1: - CALL GETBYTE - LD (HL),E - INC HL - DJNZ PPPSD_PRTERR1 - - CALL PC_LBKT - LD BC,(PPP_DSKSTHI) - CALL PRTHEXWORD - LD BC,(PPP_DSKSTLO) - CALL PRTHEXWORD - CALL PC_RBKT - - RET -#ENDIF -; -;================================================================================================== -; PPPSD DISK DRIVER - DATA -;================================================================================================== -; -PPPSD_STAT .DB 0 -; -PPP_LBA: -PPP_LBALO .DW 0 -PPP_LBAHI .DW 0 -PPP_DSKSTAT: -PPP_DSKSTLO .DW 0 -PPP_DSKSTHI .DW 0 -; -PPPSTR_PREFIX .TEXT "PPPDSK:$" -PPPSTR_CMD .TEXT "CMD=$" -PPPSTR_READ .TEXT "READ$" -PPPSTR_WRITE .TEXT "WRITE$" -;PPPSTR_RC .TEXT "RC=$" -PPPSTR_ARROW .TEXT "-->$" -PPPSTR_ERR .TEXT "ERR=$" -;PPPSTR_RCOK .TEXT "OK$" -;PPPSTR_RCRDYTO .TEXT "READY TIMEOUT$" -; -;================================================================================================== -; GLOBAL PPP DRIVER FUNCTIONS -;================================================================================================== -; -PUTBYTE: - IN A,(PPIC) - BIT 7,A - JR Z,PUTBYTE - LD A,E - OUT (PPIA),A - RET -; -GETBYTE: - IN A,(PPIC) - BIT 5,A - JR Z,GETBYTE - IN A,(PPIA) - LD E,A - RET -; -SENDCMD: - IN A,(PPIA) ; DISCARD ANYTHING PENDING - ; WAIT FOR OBF HIGH (OUTPUT BUFFER TO BE EMPTY) - IN A,(PPIC) - BIT 7,A - JR Z,SENDCMD - - LD A,00000001B ; SET CMD FLAG - OUT (PPIX),A ; SEND IT - -SENDCMD0: - IN A,(PPIC) - BIT 7,A - JR Z,SENDCMD0 - LD A,D - OUT (PPIA),A - -SENDCMD1: - ; WAIT FOR OBF HIGH (BYTE HAS BEEN RECEIVED) - IN A,(PPIC) - BIT 7,A - JR Z,SENDCMD1 - ; TURN OFF CMD - LD A,00000000B ; CLEAR CMD FLAG - OUT (PPIX),A - - RET -; -PPPSTR_TIMEOUT .TEXT "ParPortProp not responding!$" diff --git a/branches/s100/Source/ppp_data.asm b/branches/s100/Source/ppp_data.asm deleted file mode 100644 index 94e0ccc1..00000000 --- a/branches/s100/Source/ppp_data.asm +++ /dev/null @@ -1,61 +0,0 @@ -; -;================================================================================================== -; PPPSD DISK DRIVER - DATA -;================================================================================================== -; -PPPSD_SLICETRKS .EQU 65 ; TRACKS PER SLICE -PPPSD_TRKSIZE .EQU 128 ; SIZE OF TRACK (IN KB) -PPPSD_SLICESIZE .EQU ((PPPSD_SLICETRKS * PPPSD_TRKSIZE) + 1023) / 1024 ; SIZE OF EACH SLICE (IN MB) -PPPSD_NUMSLICES .EQU PPPSDCAPACITY / PPPSD_SLICESIZE ; TOTAL SLICES IN DEVICE -PPPSD0_SLICEDEF .EQU 0 ; DEFAULT SLICE FOR UNIT 0 -PPPSD1_SLICEDEF .EQU 1 ; DEFAULT SLICE FOR UNIT 1 -PPPSD2_SLICEDEF .EQU 2 ; DEFAULT SLICE FOR UNIT 0 -PPPSD3_SLICEDEF .EQU 3 ; DEFAULT SLICE FOR UNIT 1 -; - .DB DIODEV_PPPSD + 0 -PPPSDDPH0 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PPPSDCSV0,PPPSDALV0 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPPSD0_SLICE .DW PPPSD0_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PPPSD + 0 -PPPSDDPH1 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PPPSDCSV1,PPPSDALV1 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPPSD1_SLICE .DW PPPSD1_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PPPSD + 0 -PPPSDDPH2 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PPPSDCSV2,PPPSDALV2 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPPSD2_SLICE .DW PPPSD2_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PPPSD + 0 -PPPSDDPH3 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PPPSDCSV3,PPPSDALV3 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PPPSD3_SLICE .DW PPPSD3_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PPPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; -PPPSDCKS .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -PPPSDALS .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) -; -PPPSDCSV0 .FILL PPPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPPSDALV0 .FILL PPPSDALS ; MAX OF 2048 DATA BLOCKS -PPPSDCSV1 .FILL PPPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPPSDALV1 .FILL PPPSDALS ; MAX OF 2048 DATA BLOCKS -PPPSDCSV2 .FILL PPPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPPSDALV2 .FILL PPPSDALS ; MAX OF 2048 DATA BLOCKS -PPPSDCSV3 .FILL PPPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PPPSDALV3 .FILL PPPSDALS ; MAX OF 2048 DATA BLOCKS diff --git a/branches/s100/Source/prefix.asm b/branches/s100/Source/prefix.asm deleted file mode 100644 index ddc69c08..00000000 --- a/branches/s100/Source/prefix.asm +++ /dev/null @@ -1,53 +0,0 @@ -;---------------------------------------------------------------------------- -; PREFIX.ASM -; -; PUT AT THE HEAD OF BOOT.BIN TO XFER TO A FLOPPY DISK -; -;---------------------------------------------------------------------------- - -; 5/11/2012 dwg - changed offset to BIOS booting fixup location -; 3/ 2/2012 dwg - fixed BOOT_INFO_LOC (moved when jump added for bnksel) -; 2/15/2012 dwg - added origin data written by formatter -; 2/ 5/2012 dwg - added version quad, updates counter, and write protect boolean to metadata -; 1/ 9/2012 wbw - added signature -; 1/ 5/2012 dwg - added version of build generating system image -; 1/ 5/2012 dwg - added drive label to metadata for 1.4 - -#INCLUDE "std.asm" - -BYT .EQU 1 ; used to describe METADATA_SIZE below -WRD .EQU 2 - -SECTOR_SIZE .EQU 512 -BLOCK_SIZE .EQU 128 -PREFIX_SIZE .EQU (3 * SECTOR_SIZE) ; 3 SECTORS -METADATA_SIZE .EQU BYT+WRD+(4*BYT)+16+BYT+WRD+WRD+WRD+WRD ; (as defined below) - -BOOT_INFO_LOC .EQU CPM_ENT + 04BH -; PTR TO LOCATION TO RECORD BOOT INFO IN MEMORY IMAGE -; FIXUP REQUIRED WHEN BIOS HEADER CHANGES - - .ORG 0000H - JP CPM_ENT -; - .FILL ((PREFIX_SIZE - BLOCK_SIZE) - $),00H -PR_SIG .DW 0A55AH ; SIGNATURE GOES HERE - -PR_PLATFORM .DB 0 -PR_DEVICE .DB 0 -PR_FORMATTER .DB 0,0,0,0,0,0,0,0 -PR_DRIVE .DB 0 -PR_LOG_UNIT .DW 0 - -; - .FILL ((PREFIX_SIZE - METADATA_SIZE) - $),00H - .DB 0 ; write protect boolean - .DW 0 ; starting update number - .DB RMJ,RMN,RUP,RTP - .DB "Unlabeled Drive ","$" - .DW BOOT_INFO_LOC ; PTR TO LOCATION TO STORE DISKBOOT & BOOTDRIVE (SEE CNFGDATA) - .DW CPM_LOC ; CCP START - .DW CPM_END ; END OF CBIOS - .DW CPM_ENT ; COLD BOOT LOCATION - - .END \ No newline at end of file diff --git a/branches/s100/Source/prp.asm b/branches/s100/Source/prp.asm deleted file mode 100644 index 5abd7546..00000000 --- a/branches/s100/Source/prp.asm +++ /dev/null @@ -1,359 +0,0 @@ -; -;================================================================================================== -; PROPIO DRIVER -;================================================================================================== -; -; -; GLOBAL PARPORTPROP INITIALIZATION -; -PRP_INIT: - PRTS("PRP:$") -; - CALL PRPSD_INIT ; SD CARD INITIALIZATION - - RET -; -;================================================================================================== -; PROPIO CONSOLE DRIVER -;================================================================================================== -; -PRPCON_CMD .EQU $40 ; PROPIO CONSOLE COMMAND PORT (WHEN WRITTEN) -PRPCON_STATUS .EQU $40 ; PROPIO CONSOLE STATUS PORT (WHEN READ) -PRPCON_DATA .EQU $41 ; PROPIO CONSOLE DATA PORT (READ=KBD, WRITE=DISPLAY) -; -PRPCON_BUSY .EQU $80 ; BIT SET WHEN PROPIO CONSOLE INTERFACE IS BUSY -PRPCON_ERR .EQU $40 ; BIT SET WHEN PROPIO CONSOLE ERROR HAS OCCURRED -PRPCON_KBDRDY .EQU $20 ; BIT SET WHEN KEYBOARD BUF HAS A BYTE READY (BUF FULL) -PRPCON_DSPRDY .EQU $10 ; BIT SET WHEN DISPLAY BUF IS READY FOR A BYTE (BUF EMPTY) -; -; -; -PRPCON_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,PRPCON_IN - DEC A - JR Z,PRPCON_OUT - DEC A - JR Z,PRPCON_IST - DEC A - JR Z,PRPCON_OST - CALL PANIC -; -; -; -PRPCON_IN: - CALL PRPCON_IST ; CHECK FOR CHAR PENDING - JR Z,PRPCON_IN ; WAIT FOR IT IF NECESSARY - IN A,(PRPCON_DATA) ; READ THE CHAR FROM PROPIO - LD E,A - RET -; -; -; -PRPCON_IST: - IN A,(PRPCON_STATUS) ; READ LINE STATUS REGISTER - AND PRPCON_KBDRDY | PRPCON_BUSY ; ISOLATE KBDRDY AND BUSY - SUB PRPCON_KBDRDY ; KBD RDY BUT NOT BUSY? - JR Z,PRPCON_IST1 ; YES, GO TO READY LOGIC - JP CIO_IDLE -PRPCON_IST1: - DEC A ; SET A=$FF TO SIGNAL READY - RET ; RETURN -; -; -; -PRPCON_OUT: - CALL PRPCON_OST ; CHECK FOR OUTPUT READY - JR Z,PRPCON_OUT ; WAIT IF NECESSARY - LD A,E ; RECOVER THE CHAR TO WRITE - OUT (PRPCON_DATA),A ; WRITE THE CHAR TO PROPIO - RET -; -PRPCON_OST: - IN A,(PRPCON_STATUS) ; READ LINE STATUS REGISTER - AND PRPCON_DSPRDY | PRPCON_BUSY ; ISOLATE DSPRDY AND BUSY - SUB PRPCON_DSPRDY ; DSP RDY BUT NOT BUSY? - JR Z,PRPCON_OST1 ; YES, GO TO READY LOGIC - JP CIO_IDLE -PRPCON_OST1: - DEC A ; SET A=$FF TO SIGNAL READY - RET ; RETURN -; -;================================================================================================== -; PRPSD DISK DRIVER -;================================================================================================== -; -; IO PORT ADDRESSES -; -PRPSD_DSKCMD .EQU 42H -PRPSD_DSKST .EQU 42H -PRPSD_DSKIO .EQU 43H -; -PRPSD_CMDRESET .EQU 10H -PRPSD_CMDINIT .EQU 20H -PRPSD_CMDREAD .EQU 30H -PRPSD_CMDPREP .EQU 40H -PRPSD_CMDWRITE .EQU 50H -; -PRPSD_STBUSY .EQU 80H -PRPSD_STERR .EQU 40H -PRPSD_STOVR .EQU 20H -PRPSD_STTO .EQU 10H -; -; -; -PRPSD_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JR Z,PRPSD_RD - DEC A - JR Z,PRPSD_WR - DEC A - JR Z,PRPSD_ST - DEC A - JR Z,PRPSD_MED - CALL PANIC -; -PRPSD_RD: - JP PRPSD_READ -PRPSD_WR: - JP PRPSD_WRITE -PRPSD_ST: - JP PRPSD_STATUS -PRPSD_MED: - JP PRPSD_MEDIA -; -; PRPSD_MEDIA -; -PRPSD_MEDIA: - ; REINITIALIZE THE CARD HERE - CALL PRPSD_INITCARD - LD A,MID_NONE ; ASSUME FAILURE - RET NZ - - ; ALL IS WELL, RETURN MEDIA IDENTIFIER - LD A,MID_HD ; SET MEDIA ID - RET -; -; -; -PRPSD_INIT: - ; MARK DRIVE NOT READY - ; HARDWARE INIT DEFERRED UNTIL DRIVE SELECT - XOR A - DEC A - LD (PRPSD_STAT),A - RET -; -; -; -PRPSD_STATUS: - LD A,(PRPSD_STAT) ; GET THE CURRENT READY STATUS - OR A - RET -; -; -; -PRPSD_READ: - CALL PRPSD_CHKCARD ; CHECK / REINIT CARD AS NEEDED - RET NZ ; BAIL OUT ON ERROR - - LD A,PRPSD_CMDRESET - CALL PRPSD_SNDCMD - RET NZ ; RETURN ON FAILURE, A = STATUS - - CALL PRPSD_SETBLK - - LD A,PRPSD_CMDREAD - CALL PRPSD_SNDCMD - RET NZ ; RETURN ON FAILURE, A = STATUS - - LD C,PRPSD_DSKIO - LD B,0 - LD HL,(DIOBUF) - INIR - INIR - - OR A ; SET FLAGS - RET ; RETURN WITH A = STATUS -; -; -; -PRPSD_WRITE: - CALL PRPSD_CHKCARD ; CHECK / REINIT CARD AS NEEDED - RET NZ ; BAIL OUT ON ERROR - - LD A,PRPSD_CMDRESET - CALL PRPSD_SNDCMD - RET NZ ; RETURN ON FAILURE, A = STATUS - - CALL PRPSD_SETBLK - - LD A,PRPSD_CMDPREP - CALL PRPSD_SNDCMD - RET NZ ; RETURN ON FAILURE, A = STATUS - - LD C,PRPSD_DSKIO - LD B,0 - LD HL,(DIOBUF) - OTIR - OTIR - - LD A,PRPSD_CMDWRITE - CALL PRPSD_SNDCMD - RET NZ ; RETURN ON FAILURE, A = STATUS - - OR A ; SET FLAGS - RET ; RETURN WITH A = STATUS -; -; -; -PRPSD_SNDCMD: - LD (PRPSD_CMD),A - OUT (PRPSD_DSKCMD),A - NOP ; SETTLE - NOP ; SETTLE - LD BC,0 -PRPSD_SNDCMD1: - IN A,(PRPSD_DSKST) - BIT 7,A - JR Z,PRPSD_SNDCMD2 ; RET WITH A = STATUS - LD E,A ; SAVE STATUS - CALL DELAY - DEC BC - LD A,B - OR C - JR NZ,PRPSD_SNDCMD1 - LD A,E ; RECOVER STATUS - OR PRPSD_STTO ; SET TIMEOUT BIT -PRPSD_SNDCMD2: - LD (PRPSD_STAT),A - JR PRPSD_PRT ; RET WITH A = STATUS -; -; -; -PRPSD_INITCARD: - ; RESET INTERFACE, RETURN WITH NZ ON FAILURE - LD A,PRPSD_CMDRESET - CALL PRPSD_SNDCMD - RET NZ ; NZ SET, A HAS ERROR CODE - - ; REQUEST HARDWARE INIT, RESULT IN A, Z/NZ SET - LD A,PRPSD_CMDINIT - CALL PRPSD_SNDCMD - RET ; Z/NZ SET, A HAS RESULT CODE -; -; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED -; -PRPSD_CHKCARD: - LD A,(PRPSD_STAT) ; GET STATUS - OR A ; SET FLAGS - CALL NZ,PRPSD_INITCARD ; INIT CARD IF NOT READY - RET ; RETURN WITH STATUS IN A -; -; SEND INDEX OF BLOCK TO READ FROM SD CARD -; 32 BIT VALUE (4 BYTES) -; NOTE THAT BYTES ARE SENT REVERSED, PROPELLER IS LITTLE ENDIAN -; -PRPSD_SETBLK: - LD DE,PRPSD_BLK + 3 - LD A,(HSTSEC) ; A = LSB OF OS SECTOR - CALL PRPSD_SETBLK1 - LD HL,(HSTTRK) ; GET OS TRACK VALUE - LD A,L ; EXTRACT LSB - CALL PRPSD_SETBLK1 - LD A,H ; EXTRACT MSB - CALL PRPSD_SETBLK1 - XOR A ; A = 0, NOT USED - CALL PRPSD_SETBLK1 - RET -PRPSD_SETBLK1: - OUT (PRPSD_DSKIO),A ; SEND IT - LD (DE),A - DEC DE - RET - -PRPSD_PRT: - BIT 6,A -#IF (PRPSDTRACE == 0) - RET -#ELSE -#IF (PRPSDTRACE == 1) - RET Z -#ENDIF - PUSH AF - CALL NEWLINE - CALL PC_LBKT - CALL PRTHEXWORD - CALL PC_RBKT - CALL PC_SPACE - LD DE,PRPSTR_PREFIX - CALL WRITESTR - CALL PC_SPACE - LD DE,PRPSTR_CMD - CALL WRITESTR - LD A,(PRPSD_CMD) - CALL PRTHEXBYTE - CP PRPSD_CMDREAD - CALL Z,PRPSD_PRTBLK - CP PRPSD_CMDWRITE - CALL Z,PRPSD_PRTBLK - CALL PC_SPACE - LD DE,PRPSTR_ARROW - CALL WRITESTR - CALL PC_SPACE - POP AF - PUSH AF - CALL PRTHEXBYTE - BIT 6,A - CALL NZ,PRPSD_PRTERR - POP AF - RET ; RET WITH A = STATUS - -PRPSD_PRTBLK: - CALL PC_SPACE - LD HL,PRPSD_BLK - LD B,4 -PRPSD_PRTBLK1: - LD A,(HL) - CALL PRTHEXBYTE - INC HL - DJNZ PRPSD_PRTBLK1 - RET - -PRPSD_PRTERR: - LD B,4 -PRPSD_PRTERR1: - IN A,(PRPSD_DSKIO) - PUSH AF - DJNZ PRPSD_PRTERR1 - CALL PC_SPACE - LD DE,PRPSTR_ERR - CALL WRITESTR - LD B,4 -PRPSD_PRTERR2: - POP AF - CALL PRTHEXBYTE - DJNZ PRPSD_PRTERR2 - RET -#ENDIF -; -; -; -PRPSTR_PREFIX .TEXT "PRPDSK:$" -PRPSTR_CMD .TEXT "CMD=$" -;PRPSTR_RC .TEXT "RC=$" -PRPSTR_ARROW .TEXT "-->$" -PRPSTR_ERR .TEXT "ERR=$" -;PRPSTR_RCOK .TEXT "OK$" -;PRPSTR_RCRDYTO .TEXT "READY TIMEOUT$" -; -;================================================================================================== -; PRPSD DISK DRIVER - DATA -;================================================================================================== -; -PRPSD_STAT .DB 0 -; -PRPSD_CMD .DB 0 -PRPSD_BLK .DB 0, 0, 0, 0 diff --git a/branches/s100/Source/prp_data.asm b/branches/s100/Source/prp_data.asm deleted file mode 100644 index 34041c1c..00000000 --- a/branches/s100/Source/prp_data.asm +++ /dev/null @@ -1,61 +0,0 @@ -; -;================================================================================================== -; PRPSD DISK DRIVER - DATA -;================================================================================================== -; -PRPSD_SLICETRKS .EQU 65 ; TRACKS PER SLICE -PRPSD_TRKSIZE .EQU 128 ; SIZE OF TRACK (IN KB) -PRPSD_SLICESIZE .EQU ((PRPSD_SLICETRKS * PRPSD_TRKSIZE) + 1023) / 1024 ; SIZE OF EACH SLICE (IN MB) -PRPSD_NUMSLICES .EQU PRPSDCAPACITY / PRPSD_SLICESIZE ; TOTAL SLICES IN DEVICE -PRPSD0_SLICEDEF .EQU 0 ; DEFAULT SLICE FOR UNIT 0 -PRPSD1_SLICEDEF .EQU 1 ; DEFAULT SLICE FOR UNIT 1 -PRPSD2_SLICEDEF .EQU 2 ; DEFAULT SLICE FOR UNIT 0 -PRPSD3_SLICEDEF .EQU 3 ; DEFAULT SLICE FOR UNIT 1 -; - .DB DIODEV_PRPSD + 0 -PRPSDDPH0 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PRPSDCSV0,PRPSDALV0 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PRPSD0_SLICE .DW PRPSD0_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PRPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PRPSD + 0 -PRPSDDPH1 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PRPSDCSV1,PRPSDALV1 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PRPSD1_SLICE .DW PRPSD1_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PRPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PRPSD + 0 -PRPSDDPH2 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PRPSDCSV2,PRPSDALV2 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PRPSD2_SLICE .DW PRPSD2_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PRPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_PRPSD + 0 -PRPSDDPH3 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW PRPSDCSV3,PRPSDALV3 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -PRPSD3_SLICE .DW PRPSD3_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW PRPSD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; -PRPSDCKS .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -PRPSDALS .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) -; -PRPSDCSV0 .FILL PRPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PRPSDALV0 .FILL PRPSDALS ; MAX OF 2048 DATA BLOCKS -PRPSDCSV1 .FILL PRPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PRPSDALV1 .FILL PRPSDALS ; MAX OF 2048 DATA BLOCKS -PRPSDCSV2 .FILL PRPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PRPSDALV2 .FILL PRPSDALS ; MAX OF 2048 DATA BLOCKS -PRPSDCSV3 .FILL PRPSDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -PRPSDALV3 .FILL PRPSDALS ; MAX OF 2048 DATA BLOCKS diff --git a/branches/s100/Source/romfill.asm b/branches/s100/Source/romfill.asm deleted file mode 100644 index e52d3bbf..00000000 --- a/branches/s100/Source/romfill.asm +++ /dev/null @@ -1,8 +0,0 @@ -; -;================================================================================================== -; FILLER FOR ROM PAGE 0 (SEE BANKEDBIOS.TXT) -;================================================================================================== -; - .FILL 3000H -; - .END diff --git a/branches/s100/Source/s100cpu.inc b/branches/s100/Source/s100cpu.inc deleted file mode 100644 index b0724861..00000000 --- a/branches/s100/Source/s100cpu.inc +++ /dev/null @@ -1,6 +0,0 @@ -; ~/RomWBW/branches/s100/Source/s100cpu.inc 1/17/2013 dwg - - -; S100COMPUTERS.COM Z80 Master CPU Board Schema - -#DEFINE IC_Z80 - diff --git a/branches/s100/Source/s100dide.inc b/branches/s100/Source/s100dide.inc deleted file mode 100644 index af1543bc..00000000 --- a/branches/s100/Source/s100dide.inc +++ /dev/null @@ -1,10 +0,0 @@ -; ~/RomWBW/branches/s100/Source/s100dide.inc 1/17/2013 dwg - - -; S100COMPUTERS.COM Dual IDE Board Schema - -;#DEFINE IC_SCC_8530 - -;#DEFINE IC_PPI_8255 - - - diff --git a/branches/s100/Source/s100iob.inc b/branches/s100/Source/s100iob.inc deleted file mode 100644 index dac8eb20..00000000 --- a/branches/s100/Source/s100iob.inc +++ /dev/null @@ -1,38 +0,0 @@ -; ~/RomWBW/branches/s100/Source/s100iob.inc 1/17/2013 dwg - - -; S100COMPUTERS.COM Input Output Board Schema - -#DEFINE IC_SCC_8530 - -#DEFINE IC_PPI_8255 - -; -;================================================================== -; WBW: STUFF BELOW IS TEMPORARY TO ALLOW S100 TO BUILD WITHOUT ERROR -;================================================================== -; -; PPI 82C55 I/O IS DECODED TO PORT 60-67 -; -PPIBASE .EQU 60H -PPIA .EQU PPIBASE + 0 ; PORT A -PPIB .EQU PPIBASE + 1 ; PORT B -PPIC .EQU PPIBASE + 2 ; PORT C -PPIX .EQU PPIBASE + 3 ; PPI CONTROL PORT -; -; 16C550 SERIAL LINE UART -; -SIO_BASE .EQU 68H -SIO_RBR .EQU SIO_BASE + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY) -SIO_THR .EQU SIO_BASE + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY) -SIO_IER .EQU SIO_BASE + 1 ; DLAB=0: INT ENABLE REG -SIO_IIR .EQU SIO_BASE + 2 ; INT IDENT REGISTER (READ ONLY) -SIO_FCR .EQU SIO_BASE + 2 ; FIFO CONTROL REG (WRITE ONLY) -SIO_LCR .EQU SIO_BASE + 3 ; LINE CONTROL REG -SIO_MCR .EQU SIO_BASE + 4 ; MODEM CONTROL REG -SIO_LSR .EQU SIO_BASE + 5 ; LINE STATUS REG -SIO_MSR .EQU SIO_BASE + 6 ; MODEM STATUS REG -SIO_SCR .EQU SIO_BASE + 7 ; SCRATCH REGISTER -SIO_DLL .EQU SIO_BASE + 0 ; DLAB=1: DIVISOR LATCH (LS) -SIO_DLM .EQU SIO_BASE + 1 ; DLAB=1: DIVISOR LATCH (MS) -; -;================================================================== diff --git a/branches/s100/Source/s100rrf.inc b/branches/s100/Source/s100rrf.inc deleted file mode 100644 index ec8716b8..00000000 --- a/branches/s100/Source/s100rrf.inc +++ /dev/null @@ -1,10 +0,0 @@ -; ~/RomWBW/branches/s100/Source/s100rrf.inc 1/17/2013 dwg - - -; S100COMPUTERS.COM Ram Rom Flash Board Schema - -;#DEFINE IC_SCC_8530 - -;#DEFINE IC_PPI_8255 - - - diff --git a/branches/s100/Source/sd.asm b/branches/s100/Source/sd.asm deleted file mode 100644 index e5b99875..00000000 --- a/branches/s100/Source/sd.asm +++ /dev/null @@ -1,1042 +0,0 @@ -; -;============================================================================= -; SD DISK DRIVER -;============================================================================= -; -; - CATER FOR THE VARIOUS SDCARD HARDWARE VERSIONS -; CSIO IS FOR N8-2312 PRODUCTION BOARDS AND MODIFIED N8-2511 PROTOTYPE BOARDS -; RTC IS FOR UNMODIFIED N8-2511 BOARDS AND N8VEM/ZETA USING JUHA MINI-BOARDS -; PPISD IS FOR A PPISD MINI-BOARD CONNECTED TO 26-PIN PPI HEADER -; - MAKE RTC A PSEUDO-REGISTER FOR NON-CSIO -; - PERFORM BOOT INITIALIZATION OF RTC SOMEWHERE ELSE??? -; - PUT RELEVANT RTC BITS TO A KNOWN STATE AT ALL I/O ENTRY POINTS -; -; CONTROL BITS -; -#IF (PLATFORM==PLT_N8) -SD_CS .EQU $04 ; RTC BIT 2, SD CARD SELECT (ACTIVE HI) - #IF (!SDCSIO) -SD_CLK .EQU $02 ; RTC BIT 1, SD CLOCK -SD_DOUT .EQU $01 ; RTC BIT 0, SD DATA OUT -SD_DIN .EQU $40 ; RTC BIT 6, SD DATA IN - #ENDIF -#ELSE - #IF (PPISD) -SD_CS .EQU $10 ; PC4, SD CARD SELECT (ACTIVE LO) -SD_CLK .EQU $02 ; PC1, SD CLOCK -SD_DOUT .EQU $01 ; PC0, SD DATA OUT -SD_DIN .EQU $80 ; PB7, SD DATA IN - #ELSE - #IF (S2ISD) -SD_CS .EQU $08 ; MCR:3 OUT2, CD, ACT=LO=0 -SD_CLK .EQU $04 ; MCR:2 OUT1, CLK, ACT=LO=1 -SD_DOUT .EQU $20 ; MSR:5 DSR, DAT0, ACT=HI=0 (INV) -SD_DIN .EQU $01 ; MCR:0 DTR, CMD, ACT=HI=0 (INV) - #ELSE -SD_CS .EQU $04 ; RTC BIT 2, SD CARD SELECT (ACTIVE HI) -SD_CLK .EQU $40 ; RTC BIT 6, SD CLOCK -SD_DOUT .EQU $80 ; RTC BIT 7, DATA OUT TO SD-CARD -SD_DIN .EQU $40 ; RTC BIT 6, DATA IN FROM SD-CARD - #ENDIF - #ENDIF -#ENDIF -; -; SD CARD COMMANDS -; -SD_CMD0 .EQU $40 | 0 ; GO_IDLE_STATE -SD_CMD1 .EQU $40 | 1 ; SEND_OP_COND -SD_CMD8 .EQU $40 | 8 ; SEND_IF_COND -SD_CMD9 .EQU $40 | 9 ; SEND_CSD -SD_CMD10 .EQU $40 | 10 ; SEND_CID -SD_CMD16 .EQU $40 | 16 ; SET_BLOCKLEN -SD_CMD17 .EQU $40 | 17 ; READ_SINGLE_BLOCK -SD_CMD24 .EQU $40 | 24 ; WRITE_BLOCK -SD_CMD55 .EQU $40 | 55 ; APP_CMD -SD_CMD58 .EQU $40 | 58 ; READ_OCR -; SD APPLICATION SPECIFIC COMMANDS -SD_ACMD41 .EQU $40 | 41 ; SD_APP_OP_COND -; -; SD CARD TYPE -; -SD_TYPEUNK .EQU 0 -SD_TYPEMMC .EQU 1 -SD_TYPESDSC .EQU 2 -SD_TYPESDHC .EQU 3 -; -; -; -SD_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F - JR Z,SD_READ - DEC A - JR Z,SD_WRITE - DEC A - JR Z,SD_STATUS - DEC A - JR Z,SD_MEDIA - CALL PANIC -; -; -; -SD_MEDIA: - ; INITIALIZE THE SD CARD TO ACCOMMODATE HOT SWAPPING - CALL SD_INITCARD - LD A,MID_NONE ; ASSUME FAILURE - RET NZ ; INIT FAILED, RETURN WITH HL=0 - - ; SET READY AND RETURN - XOR A - LD (SD_STAT),A ; SD_STAT = 0 = OK - LD A,MID_HD - RET -; -SD_INIT: - PRTS("SD: IO=0x$") -#IF (!SDCSIO) - LD A,RTC -#ELSE - LD A,CPU_CNTR -#ENDIF - CALL PRTHEXBYTE - PRTS(" UNITS=1$") -; - LD A,20H ; PUT RTC LATCH TO IDLE - OUT (RTC),A -#IF (PPISD) - LD A,82H ; PPI PORT A=OUT, B=IN, C=OUT - OUT (PPIX),A - LD A,30H ; PC4,5 /CS HIGH - OUT (PPIC),A -#ENDIF -#IF (S2ISD) - IN A,(SIO_MCR) - OR SD_CS ; DEASSERT = HI = 1 - AND ~SD_DIN ; DEASSERT DIN = LO = 1 - AND ~SD_CLK ; DEASSERT CLK = LO = 1 - OUT (SIO_MCR),A -#ENDIF - XOR A - DEC A - LD (SD_STAT),A - RET -; -SD_STATUS: - LD A,(SD_STAT) - OR A - RET -; -SD_READ: - JP SD_RDSEC -; -SD_WRITE: - JP SD_WRSEC -; -;============================================================================= -; SD INTERFACE ROUTINES -;============================================================================= -; -; SD_SENDCLKS: A=RTC MASK, B=# OF CLK TRANSITIONS -; For bit bang versions B is number of transitions -; For PPISD B is number of bits -; For CSIO B is number of bytes -SD_SENDCLKS: -#IF (!SDCSIO) - #IF (PPISD) - LD A,03 ;PC1=1, TOGGLE CLOCK - OUT (PPIX),A - NOP - LD A,02 ;PC1=0, RESET CLOCK - OUT (PPIX),A - #ELSE - #IF (S2ISD) - OUT (SIO_MCR),A - XOR SD_CLK - #ELSE - OUT (RTC),A - XOR SD_CLK ; TOGGLE CLOCK BIT - #ENDIF - #ENDIF - DJNZ SD_SENDCLKS - RET -#ELSE -SD_SENDCLKS1: - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - LD A,0FFH - OUT0 (CPU_TRDR),A ; put byte in buffer - IN0 A,(CPU_CNTR) - SET 4,A ; set transmit enable - OUT0 (CPU_CNTR),A - DJNZ SD_SENDCLKS - RET - -SD_WAITTX: ; WAIT FOR TX EMPTY - IN0 A,(CPU_CNTR) ; get CSIO status - BIT 4,A ; Tx empty? - JR NZ,SD_WAITTX - RET - -SD_WAITRX: - IN0 A,(CPU_CNTR) ; wait for receiver to finish - BIT 5,A - JR NZ,SD_WAITRX - RET -#ENDIF -; -; COMPLETE A TRANSACTION - PRESERVE AF -; -SD_DONE: - PUSH AF -#IF (!SDCSIO) - #IF (PPISD) - LD A,30H - OUT (PPIC),A ;PC4=1 /CS INACTIVE - LD B,16 - #ELSE - #IF (S2ISD) - IN A,(SIO_MCR) - OR SD_CS ; TURN OFF CS - OUT (SIO_MCR),A - LD B,17 - #ELSE - XOR A - LD B,17 - #ENDIF - #ENDIF - CALL SD_SENDCLKS -#ELSE - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - IN A,(RTC) - AND ~SD_CS ; CLEAR CS - OUT (RTC),A - LD B,2 - CALL SD_SENDCLKS -#ENDIF - POP AF - RET -; -; SEND ONE BYTE -; -SD_PUT: -#IF (PPISD) -; CALL PRTHEXBYTE ; *DEBUG* - LD C,A ; C=BYTE TO SEND - LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) - LD A,08H ;PC4=0, /CS ACTIVE - OUT (PPIX),A -SD_PUT1: - RL C ;ROTATE NEXT BIT FROM C INTO CF - LD A,01 ;PC0=1, DATA OUT=1 - JR C,SD_PUT2 - LD A,00 ;PC0=0, DATA OUT =0 -SD_PUT2: - OUT (PPIX),A ;SEND DATA OUT - LD A,03 ;PC1=1, TOGGLE CLOCK - OUT (PPIX),A - LD A,02 ;PC1=0, RESET CLOCK - OUT (PPIX),A - DJNZ SD_PUT1 ;REPEAT FOR ALL 8 BITS - RET -#ELSE - #IF (S2ISD) -; CALL PRTHEXBYTE ; *DEBUG* - XOR $FF ; INVERT FOR S2ISD INTERFACE - LD C,A ; C=BYTE TO SEND - LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) - IN A,(SIO_MCR) ; START WITH CURRENT MCR REG VAUE -SD_PUT1: - RRA ; PREPARE A FOR ROTATE - RL C ; ROTATE NEXT DATA BIT FROM C INTO CF - RLA ; ROTATE DATA BIT INTO A:0 - OR SD_CLK ; ASSERT CLOCK - OUT (SIO_MCR),A ; SEND IT - AND ~SD_CLK ; DEASSERT CLOCK - OUT (SIO_MCR),A ; SEND IT - DJNZ SD_PUT1 ; REPEAT FOR ALL 8 BITS - RET - #ELSE - #IF (!SDCSIO) -; CALL PRTHEXBYTE ; *DEBUG* - LD C,A ; C=BYTE TO SEND - LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) -SD_PUT1: - #IF (PLATFORM==PLT_N8) - LD A,2 ; SD_CS >> 1 (SD_CS WILL BE SET AFTER ROTATE) - RL C ; ROTATE NEXT BIT FROM C INTO CF - RLA ; ROTATE CF INTO A:0, SD_DOUT is RTC:0 - #ELSE - LD A,8 ; SD_CS WILL BE IN BIT2 AFTER ROTATE - RL C ; ROTATE NEXT BIT FROM C INTO CF - RRA ; ROTATE CARRY INTO A:7, SD_DOUT is RTC:7 - #ENDIF - OUT (RTC),A ; CLOCK LOW (ABOUT TO SEND BIT) - OR SD_CLK ; SET CLOCK BIT - OUT (RTC),A ; CLOCK HIGH (SEND BIT) - DJNZ SD_PUT1 ; REPEAT FOR ALL 8 BITS - AND ~SD_CLK ; RESET CLOCK - OUT (RTC),A ; LEAVE WITH CLOCK LOW - RET - #ELSE - CALL MIRROR ; MSB<-->LSB mirror bits, result in C - CALL SD_WAITRX ; MAKE SURE WE ARE DONE SENDING - OUT0 (CPU_TRDR),C ; put byte in buffer - IN0 A,(CPU_CNTR) - SET 4,A ; set transmit enable - OUT0 (CPU_CNTR),A - RET ; let it do the rest - #ENDIF - #ENDIF -#ENDIF -; -; RECEIVE ONE BYTE -; -SD_GET: -#IF (PPISD) - LD B,8 ; RECEIVE 8 BITS (LOOP 8 TIMES) -SD_GET1: - IN A,(PPIB) ; GET BIT FROM SD-CARD - RLA ; ROTATE PB7 INTO CARRY - RL C ; ROTATE CARRY INTO C - LD A,03 ; PC1=1, TOGGLE CLOCK - OUT (PPIX),A - LD A,02 ; PC1=0, RESET CLOCK - OUT (PPIX),A - DJNZ SD_GET1 ; REPEAT FOR ALL 8 BITS - LD A,C ; GET BYTE RECEIVED INTO A -; CALL PRTHEXBYTE ; *DEBUG* - RET -#ELSE - #IF (S2ISD) - LD B,8 ; SEND 8 BITS (LOOP 8 TIMES) -SD_GET1: - IN A,(SIO_MCR) ; GET CURRENT MCR TO TOGGLE CLK - OR SD_CLK ; SET CLK - OUT (SIO_MCR),A ; SEND IT - - NOP - - IN A,(SIO_MSR) ; MSR:5 HAS DATA BIT - RLA ; ROTATE DATA BIT TO A:6 - RLA ; ROTATE DATA BIT TO A:7 - RLA ; ROTATE DATA BIT TO CF - RL C ; NOW ROTATE CF INTO C:0 - - IN A,(SIO_MCR) ; GET CURRENT MCR TO TOGGLE CLK - AND ~SD_CLK ; CLEAR CLK - OUT (SIO_MCR),A ; SEND IT - - DJNZ SD_GET1 ; REPEAT FOR ALL 8 BITS - LD A,C ; GET BYTE RECEIVED INTO A - XOR $FF ; INVERT FOR S2ISD INTERFACE -; CALL PC_PERIOD ; *DEBUG* -; CALL PRTHEXBYTE ; *DEBUG* - RET - #ELSE - #IF (!SDCSIO) - LD B,8 ; RECEIVE 8 BITS (LOOP 8 TIMES) -SD_GET1: - IN A,(RTC) ; GET RTC BITS - RLA ; ROTATE RTC:6 (SD_IN) INTO CF - RLA - RL C ; ROTATE CF INTO C:0 - LD A,SD_CS | SD_DOUT | SD_CLK - OUT (RTC),A ; CLOCK HIGH (ACK BIT RECEIVED) - AND ~SD_CLK ; RESET CLOCK BIT - OUT (RTC),A ; CLOCK LOW (READY FOR NEXT BIT) - DJNZ SD_GET1 ; REPEAT FOR ALL 8 BITS - LD A,C ; GET BYTE RECEIVED INTO A -; CALL PRTHEXBYTE ; *DEBUG* - RET - #ELSE - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - IN0 A,(CPU_CNTR) ; get CSIO status - SET 5,A ; start receiver - OUT0 (CPU_CNTR),A - CALL SD_WAITRX - IN0 A,(CPU_TRDR) ; get received byte - CALL MIRROR ; MSB<-->LSB mirror bits - LD A,C ; keep result - RET - #ENDIF - #ENDIF -#ENDIF - -#IF (SDCSIO) -MIRROR: ; MSB<-->LSB mirror bits in A, result in C - #IF (!SDCSIOFAST) ; slow speed, least code space - LD B,8 ; bit counter -MIRROR1: - RLA ; rotate bit 7 into carry - RR C ; rotate carry into result - DJNZ MIRROR1 ; do all 8 bits - RET - #ELSE ; fastest but uses most code space - LD BC,MIRTAB ; 256 byte mirror table - ADD A,C ; add offset - LD C,A - JR NC,MIRROR2 - INC B -MIRROR2: - LD A,(BC) ; get result - LD C,A ; return result in C - RET - #ENDIF -#ENDIF - -; -; SELECT CARD AND WAIT FOR IT TO BE READY ($FF) -; -SD_WAITRDY: -#IF (PPISD) - LD A,21H ;/CS ACTIVE (PC4), DOUT=1 (PC0) - OUT (PPIC),A -#ELSE - #IF (S2ISD) - IN A,(SIO_MCR) - AND ~SD_CS ; ASSERT CS (1) - OUT (SIO_MCR),A - #ELSE - IN A,(RTC) - #IF (!SDCSIO) - OR SD_CS | SD_DOUT ; SET SD_CS (CHIP SELECT) - #ELSE - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - OR SD_CS ; SET SD_CS (CHIP SELECT) - #ENDIF - OUT (RTC),A - #ENDIF -#ENDIF - LD DE,0 ; LOOP MAX (TIMEOUT) -SD_WAITRDY1: -; CALL PC_SPACE ; *DEBUG* - CALL SD_GET -; CALL PRTHEXBYTE ; *DEBUG* -; XOR A ; *DEBUG* TO SIMULATE READY TIMEOUT - INC A ; $FF -> $00 - RET Z ; IF READY, RETURN - DEC DE - LD A,D - OR E - JR NZ,SD_WAITRDY1 ; KEEP TRYING UNTIL TIMEOUT - LD A,$FF ; SIGNAL TIMEOUT ERROR - OR A ; SET FLAGS - RET ; TIMEOUT -; -; SD_GETDATA -; -SD_GETDATA: - PUSH BC ; SAVE LENGTH TO RECEIVE - LD DE,$7FFF ; LOOP MAX (TIMEOUT) -SD_GETDATA1: - CALL SD_GET - CP $FF ; WANT BYTE != $FF - JR NZ,SD_GETDATA2 ; NOT $FF, MOVE ON - DEC DE - BIT 7,D - JR Z,SD_GETDATA1 ; KEEP TRYING UNTIL TIMEOUT -SD_GETDATA2: - LD (SD_TOK),A - POP DE ; RESTORE LENGTH TO RECEIVE - CP $FE ; PACKET START? - JR NZ,SD_GETDATA4 ; NOPE, ABORT, A HAS ERROR CODE - LD HL,(DIOBUF) ; RECEIVE BUFFER -SD_GETDATA3: - CALL SD_GET ; GET NEXT BYTE - LD (HL),A ; SAVE IT - INC HL - DEC DE - LD A,D - OR E - JR NZ,SD_GETDATA3 ; LOOP FOR ALL BYTES - CALL SD_GET ; DISCARD CRC BYTE 1 - CALL SD_GET ; DISCARD CRC BYTE 2 - XOR A ; RESULT IS ZERO -SD_GETDATA4: - RET -; -; SD_PUTDATA -; -SD_PUTDATA: - PUSH BC ; SAVE LENGTH TO SEND - - LD A,$FE ; PACKET START - CALL SD_PUT ; SEND IT - - POP DE ; RESTORE LENGTH TO SEND - LD HL,(DIOBUF) ; RECEIVE BUFFER -SD_PUTDATA1: - LD A,(HL) ; GET NEXT BYTE TO SEND - CALL SD_PUT ; SEND IF - INC HL - DEC DE - LD A,D - OR E - JR NZ,SD_PUTDATA1 ; LOOP FOR ALL BYTES - LD A,$FF ; DUMMY CRC BYTE - CALL SD_PUT - LD A,$FF ; DUMMY CRC BYTE - CALL SD_PUT - LD DE,$7FFF ; LOOP MAX (TIMEOUT) -SD_PUTDATA2: - CALL SD_GET - CP $FF ; WANT BYTE != $FF - JR NZ,SD_PUTDATA3 ; NOT $FF, MOVE ON - DEC DE - BIT 7,D - JR Z,SD_PUTDATA2 ; KEEP TRYING UNTIL TIMEOUT -SD_PUTDATA3: - AND $1F - LD (SD_TOK),A - CP $05 - RET NZ - XOR A - RET -; -; SETUP COMMAND BUFFER -; -SD_SETCMD0: ; NO PARMS - LD HL,SD_CMDBUF - LD (HL),A - INC HL - XOR A - LD (HL),A - INC HL - LD (HL),A - INC HL - LD (HL),A - INC HL - LD (HL),A - INC HL - LD A,$FF - LD (HL),A - RET -; -SD_SETCMDP: ; W/ PARMS IN BC & DE - CALL SD_SETCMD0 - LD HL,SD_CMDP0 - LD (HL),B - INC HL - LD (HL),C - INC HL - LD (HL),D - INC HL - LD (HL),E - RET -; -; EXECUTE A SD CARD COMMAND -; -SD_EXEC: - XOR A - LD (SD_RC),A - LD (SD_TOK),A - LD HL,SD_CMDBUF - LD E,6 ; COMMANDS ARE 6 BYTES -SD_EXEC1: -#IF (SDCSIO) - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - IN A,(RTC) - OR SD_CS ; SET CS - OUT (RTC),A -#ENDIF -#IF (S2ISD) - IN A,(SIO_MCR) - AND ~SD_CS ; ASSERT = LO = 0 - OUT (SIO_MCR),A -#ENDIF - LD A,(HL) - CALL SD_PUT - INC HL - DEC E - JR NZ,SD_EXEC1 - LD DE,$100 ; LOOP MAX (TIMEOUT) -SD_EXEC2: - CALL SD_GET - OR A ; SET FLAGS - JP P,SD_EXEC3 ; IF HIGH BIT IS 0, WE HAVE RESULT - DEC DE - BIT 7,D - JR Z,SD_EXEC2 -SD_EXEC3: - LD (SD_RC),A -#IF (SDTRACE >= 2) - CALL SD_PRTTRN -#ENDIF -#IF (DSKYENABLE) - CALL SD_DSKY -#ENDIF - RET -; -SD_EXECCMD0: ; EXEC COMMAND, NO PARMS - CALL SD_SETCMD0 - JR SD_EXEC -; -SD_EXECCMDP: ; EXEC CMD W/ PARMS IN BC/DE - CALL SD_SETCMDP - JR SD_EXEC -; -; PUT CARD IN IDLE STATE -; -SD_GOIDLE: - ; SMALL DELAY HERE HELPS SOME CARDS - LD DE,200 ; 5 MILISECONDS - CALL VDELAY - - ; PUT CARD IN IDLE STATE - LD A,SD_CMD0 ; CMD0 = ENTER IDLE STATE - CALL SD_SETCMD0 - LD A,$95 - LD (SD_CMDBUF+5),A ; SET CRC=$95 - CALL SD_EXEC ; EXEC CMD - CP $01 ; IN IDLE STATE? - CALL SD_DONE - RET -; -; INIT CARD -; -SD_INITCARD: -#IF (PPISD) - LD A,82H ; PPI PORT A=OUT, B=IN, C=OUT - OUT (PPIX),A - LD A,30H ; PC4,5 /CS HIGH - OUT (PPIC),A -#ENDIF - LD A,20H ; PUT RTC LATCH TO IDLE - OUT (RTC),A - -#IF (SDCSIO) - ; CSIO SETUP -; LD A,02 ; 18MHz/20 <= 400kHz - LD A,06 ; ??? - OUT0 (CPU_CNTR),A -#ENDIF - CALL SD_DONE ; SEEMS TO HELP SOME CARDS... - -#IF (!SDCSIO) - #IF (PPISD) - LD A,21H ; /CS=0, DOUT=1, CLK=0 - OUT (PPIC),A - LD B,07FH ; 127 CLOCKS (255 TRANSITIONS STARTING WITH LO) - #ELSE - #IF (S2ISD) - IN A,(SIO_MCR) - OR SD_CS ; DEASSERT CS = HI = 1 - AND ~SD_DIN ; ASSERT DIN = HI = 0 - AND ~SD_CLK ; DEASSERT CLK = HI = 0 - LD B,0FFH ; 127 CLOCKS (255 TRANSITIONS STARTING WITH LO) - #ELSE - LD A,SD_CS | SD_DOUT ; CS=HI, DOUT=HI - LD B,0FFH ; 127 CLOCKS (255 TRANSITIONS STARTING WITH LO) - #ENDIF - #ENDIF -#ELSE - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - IN A,(RTC) - OR SD_CS ; SET CS - OUT (RTC),A - LD B,16 -#ENDIF - CALL SD_SENDCLKS ; INIT DELAY + GO SPI MODE - - ; WAIT FOR CARD TO BE READY FOR A COMMAND - CALL SD_WAITRDY - JP NZ,SD_ERRRDYTO - - ; PUT CARD IN IDLE STATE - CALL SD_GOIDLE - CALL NZ,SD_GOIDLE ; SOME CARDS REQUIRE A SECOND ATTEMPT - JP NZ,SD_ERRCMD ; GIVE UP - -SD_INITCARD00: - LD A,SD_TYPESDSC ; ASSUME SDSC CARD TYPE - LD (SD_TYPE),A ; SAVE IT - - ; CMD8 IS REQUIRED FOR V2 CARDS. FAILURE HERE IS OK AND - ; JUST MEANS THAT IT IS A V1.X CARD - LD A,SD_CMD8 - - LD BC,0 - LD D,1 ; VHS=1, 2.7-3.6V - LD E,$AA ; CHECK PATTERN - CALL SD_SETCMDP - LD A,$87 - LD (SD_CMDBUF+5),A ; SET CRC=$87 - CALL SD_EXEC ; EXEC CMD - AND ~$01 - JR NZ,SD_INITCARD0 - - ; CMD8 WORKED, SO THIS IS V2 CARD - ; NEED TO CONSUME EXTRA CMD8 RESPONSE BYTES (4) - CALL SD_GET - CALL SD_GET - CALL SD_GET - CALL SD_GET - -SD_INITCARD0: - CALL SD_DONE - - LD B,0 ; LOOP LIMIT (TIMEOUT) -SD_INITCARD1: - ; CALL SD_APP_OP_COND UNTIL CARD IS READY (NOT IDLE) - LD DE,200 ; 5 MILLISECONDS - CALL VDELAY - LD A,SD_CMD55 ; APP CMD IS NEXT - PUSH BC - CALL SD_EXECCMD0 - POP BC - AND ~$01 ; ONLY 0 (OK) OR 1 (IDLE) ARE OK - CALL SD_DONE - JP NZ,SD_ERRCMD - LD A,SD_ACMD41 ; SD_APP_OP_COND - PUSH BC - LD BC,$4000 ; INDICATE WE SUPPORT HC - LD DE,$0000 - CALL SD_EXECCMDP - POP BC - PUSH AF - AND ~$01 - CALL SD_DONE - POP AF -; LD A,$01 ; *DEBUG* TO SIMULATE INIT TIMEOUT ERROR - CP $00 ; INIT DONE? - JR Z,SD_INITCARD2 ; YUP, MOVE ON - CP $01 ; IDLE? - JP NZ,SD_ERRCMD ; NOPE, MUST BE CMD ERROR, ABORT - DJNZ SD_INITCARD1 ; KEEP CHECKING - LD A,$FF ; SIGNAL TIMEOUT - OR A - JP SD_ERRINITTO - -SD_INITCARD2: - ; CMD58 RETURNS THE 32 BIT OCR REGISTER, WE WANT TO CHECK - ; BIT 30, IF SET THIS IS SDHC/XC CARD - LD A,SD_CMD58 - CALL SD_EXECCMD0 - CALL NZ,SD_DONE - JP NZ,SD_ERRCMD - - ; CMD58 WORKED, GET OCR DATA AND SET CARD TYPE - CALL SD_GET ; BITS 31-24 - AND $40 ; ISOLATE BIT 30 (CCS) - JR Z,SD_INITCARD21 ; NOT HC/XC, BYPASS - LD A,SD_TYPESDHC ; CARD TYPE = SDHC - LD (SD_TYPE),A ; SAVE IT -SD_INITCARD21: - CALL SD_GET ; BITS 23-16, DISCARD - CALL SD_GET ; BITS 15-8, DISCARD - CALL SD_GET ; BITS 7-0, DISCARD - CALL SD_DONE - - ; SET OUR DESIRED BLOCK LENGTH (512 BYTES) - LD A,SD_CMD16 ; SET_BLOCK_LEN - LD BC,0 - LD DE,512 - CALL SD_EXECCMDP - CALL SD_DONE - JP NZ,SD_ERRCMD - -#IF (SDTRACE >= 2) - CALL NEWLINE - LD DE,SDSTR_SDTYPE - CALL WRITESTR - LD A,(SD_TYPE) - CALL PRTHEXBYTE -#ENDIF - -; RET NZ ; IF ERROR, ABORT NOW WITH A SET CORRECTLY - -#IF (SDCSIO) - CALL SD_WAITTX ; MAKE SURE WE ARE DONE SENDING - XOR A ; NOW SET CSIO PORT TO FULL SPEED - OUT (CPU_CNTR),A -#ENDIF - - XOR A ; A = 0 (STATUS = OK) - LD (SD_STAT),A ; SAVE IT - RET ; RETURN WITH A=0, AND Z SET -;; -;; GET AND PRINT CSD, CID -;; -;SD_CARDINFO: -; LD A,SD_CMD9 ; SEND_CSD -; CALL SD_EXECCMD0 -; CALL SD_DONE -; JP NZ,SD_ERRCMD ; ABORT IF PROBLEM -; LD BC,16 ; 16 BYTES OF CSD -; CALL SD_GETDATA -; CALL SD_DONE -; -; LD DE,SDSTR_CSD -; CALL WRITESTR -; LD DE,SECBUF -; LD A,16 -; CALL PRTHEXBUF -; -; LD A,SD_CMD10 ; SEND_CID -; CALL SD_EXECCMD0 -; CALL SD_DONE -; JP NZ,SD_ERRCMD ; ABORT IF PROBLEM -; LD BC,16 ; 16 BYTES OF CID -; CALL SD_GETDATA -; CALL SD_DONE -; -; LD DE,SDSTR_CID -; CALL WRITESTR -; LD DE,SECBUF -; LD A,16 -; CALL PRTHEXBUF -; -; RET -; -; READ ONE SECTOR -; - -; -; CHECK THE SD CARD, ATTEMPT TO REINITIALIZE IF NEEDED -; -SD_CHKCARD: - LD A,(SD_STAT) ; GET STATUS - OR A ; SET FLAGS - CALL NZ,SD_INITCARD ; INIT CARD IF NOT READY - RET ; RETURN WITH STATUS IN A - -SD_RDSEC: - CALL SD_CHKCARD ; CHECK / REINIT CARD AS NEEDED - RET NZ - - CALL SD_WAITRDY ; WAIT FOR CARD TO BE READY FOR A COMMAND - JP NZ,SD_ERRRDYTO ; HANDLE NOT READY TIMEOUT ERROR - - CALL SD_SETADDR ; SETUP BLOCK ADDRESS - - LD A,SD_CMD17 ; READ_SINGLE_BLOCK - CALL SD_EXECCMDP ; EXEC CMD WITH BLOCK ADDRESS AS PARM - CALL NZ,SD_DONE ; TRANSACTION DONE IF ERROR OCCURRED - JP NZ,SD_ERRCMD ; ABORT ON ERROR - - LD BC,512 ; LENGTH TO READ - CALL SD_GETDATA ; GET THE BLOCK - CALL SD_DONE - JP NZ,SD_ERRDATA ; DATA XFER ERROR - RET -; -; WRITE ONE SECTOR -; -SD_WRSEC: - CALL SD_CHKCARD ; CHECK / REINIT CARD AS NEEDED - RET NZ - - CALL SD_WAITRDY ; WAIT FOR CARD TO BE READY FOR A COMMAND - JP NZ,SD_ERRRDYTO ; HANDLE NOT READY TIMEOUT ERROR - - CALL SD_SETADDR ; SETUP BLOCK ADDRESS - - LD A,SD_CMD24 ; WRITE_BLOCK - CALL SD_EXECCMDP ; EXEC CMD WITH BLOCK ADDRESS AS PARM - CALL NZ,SD_DONE ; TRANSACTION DONE IF ERROR OCCURRED - JP NZ,SD_ERRCMD ; ABORT ON ERROR - - LD BC,512 ; LENGTH TO WRITE - CALL SD_PUTDATA ; PUT THE BLOCK - CALL SD_DONE - JP NZ,SD_ERRDATA ; DATA XFER ERROR - RET -; -; -; -SD_SETADDR: - LD A,(SD_TYPE) - CP SD_TYPESDSC - JR Z,SD_SETADDRSDSC - CP SD_TYPESDHC - JR Z,SD_SETADDRSDHC - CALL PANIC - -SD_SETADDRSDSC: - LD HL,(HSTSEC) - LD E,0 - LD D,L - LD HL,(HSTTRK) - LD C,L - LD B,H - XOR A - RL D - RL C - RL B - RET - -SD_SETADDRSDHC: - LD A,(HSTSEC) ; GET SECTOR (LSB ONLY) - LD E,A ; PUT IN E - LD HL,(HSTTRK) ; GET TRACK - LD D,L ; TRACK LSB -> D - LD C,H ; TRACK MSB -> C - LD B,0 ; B ALWAYS ZERO - RET -; -; HANDLE READY TIMEOUT ERROR -; -SD_ERRRDYTO: -#IF (SDTRACE >= 1) - CALL SD_PRTPREFIX - LD DE,SDSTR_ERRRDYTO -#ENDIF - JR SD_CARDERR -; -; HANDLE INIT TIMEOUT ERROR -; -SD_ERRINITTO: -#IF (SDTRACE >= 1) - CALL SD_PRTPREFIX - LD DE,SDSTR_ERRINITTO -#ENDIF - JR SD_CARDERR -; -; HANDLE COMMAND ERROR -; -SD_ERRCMD: -#IF (SDTRACE == 1) - CALL SD_PRTTRN -#ENDIF -#IF (SDTRACE >= 1) - LD DE,SDSTR_ERRCMD -#ENDIF - JR SD_CARDERR -; -; HANDLE COMMAND ERROR -; -SD_ERRDATA: -#IF (SDTRACE == 1) - CALL SD_PRTTRN -#ENDIF -#IF (SDTRACE >= 1) - LD DE,SDSTR_ERRDATA -#ENDIF - JR SD_CARDERR -; -; GENERIC ERROR HANDLER, DE POINTS TO ERROR STRING -; -SD_CARDERR: - PUSH AF - XOR A - DEC A - LD A,FALSE - LD (SD_STAT),A -#IF (SDTRACE >= 1) - CALL PC_SPACE - CALL PC_LBKT - CALL WRITESTR - CALL PC_RBKT -#ENDIF - POP AF - LD (SD_STAT),A - RET -; -; PRINT DIAGNONSTIC PREFIX -; -SD_PRTPREFIX: - CALL NEWLINE - LD DE,SDSTR_PREFIX - CALL WRITESTR - RET -; -; PRT COMMAND TRACE -; -SD_PRTTRN: - PUSH AF - - CALL SD_PRTPREFIX - - LD DE,SD_CMDBUF - LD A,6 - CALL PRTHEXBUF - CALL PC_SPACE - LD DE,SDSTR_ARROW - CALL WRITESTR - CALL PC_SPACE - - LD DE,SDSTR_RC - CALL WRITESTR - LD A,(SD_RC) - CALL PRTHEXBYTE - CALL PC_SPACE - - LD DE,SDSTR_TOK - CALL WRITESTR - LD A,(SD_TOK) - CALL PRTHEXBYTE - - POP AF - RET - -; -; DISPLAY COMMAND, LOW ORDER WORD OF PARMS, AND RC -; -#IF (DSKYENABLE) -SD_DSKY: - PUSH AF - LD HL,DSKY_HEXBUF - LD A,(SD_CMD) - LD (HL),A - INC HL - LD A,(SD_CMDP2) - LD (HL),A - INC HL - LD A,(SD_CMDP3) - LD (HL),A - INC HL - LD A,(SD_RC) - CALL DSKY_HEXOUT - POP AF - RET -#ENDIF -; -; -; -#IF (SDCSIOFAST) -MIRTAB: .DB 00H, 80H, 40H, 0C0H, 20H, 0A0H, 60H, 0E0H, 10H, 90H, 50H, 0D0H, 30H, 0B0H, 70H, 0F0H - .DB 08H, 88H, 48H, 0C8H, 28H, 0A8H, 68H, 0E8H, 18H, 98H, 58H, 0D8H, 38H, 0B8H, 78H, 0F8H - .DB 04H, 84H, 44H, 0C4H, 24H, 0A4H, 64H, 0E4H, 14H, 94H, 54H, 0D4H, 34H, 0B4H, 74H, 0F4H - .DB 0CH, 8CH, 4CH, 0CCH, 2CH, 0ACH, 6CH, 0ECH, 1CH, 9CH, 5CH, 0DCH, 3CH, 0BCH, 7CH, 0FCH - .DB 02H, 82H, 42H, 0C2H, 22H, 0A2H, 62H, 0E2H, 12H, 92H, 52H, 0D2H, 32H, 0B2H, 72H, 0F2H - .DB 0AH, 8AH, 4AH, 0CAH, 2AH, 0AAH, 6AH, 0EAH, 1AH, 9AH, 5AH, 0DAH, 3AH, 0BAH, 7AH, 0FAH - .DB 06H, 86H, 46H, 0C6H, 26H, 0A6H, 66H, 0E6H, 16H, 96H, 56H, 0D6H, 36H, 0B6H, 76H, 0F6H - .DB 0EH, 8EH, 4EH, 0CEH, 2EH, 0AEH, 6EH, 0EEH, 1EH, 9EH, 5EH, 0DEH, 3EH, 0BEH, 7EH, 0FEH - .DB 01H, 81H, 41H, 0C1H, 21H, 0A1H, 61H, 0E1H, 11H, 91H, 51H, 0D1H, 31H, 0B1H, 71H, 0F1H - .DB 09H, 89H, 49H, 0C9H, 29H, 0A9H, 69H, 0E9H, 19H, 99H, 59H, 0D9H, 39H, 0B9H, 79H, 0F9H - .DB 05H, 85H, 45H, 0C5H, 25H, 0A5H, 65H, 0E5H, 15H, 95H, 55H, 0D5H, 35H, 0B5H, 75H, 0F5H - .DB 0DH, 8DH, 4DH, 0CDH, 2DH, 0ADH, 6DH, 0EDH, 1DH, 9DH, 5DH, 0DDH, 3DH, 0BDH, 7DH, 0FDH - .DB 03H, 83H, 43H, 0C3H, 23H, 0A3H, 63H, 0E3H, 13H, 93H, 53H, 0D3H, 33H, 0B3H, 73H, 0F3H - .DB 0BH, 8BH, 4BH, 0CBH, 2BH, 0ABH, 6BH, 0EBH, 1BH, 9BH, 5BH, 0DBH, 3BH, 0BBH, 7BH, 0FBH - .DB 07H, 87H, 47H, 0C7H, 27H, 0A7H, 67H, 0E7H, 17H, 97H, 57H, 0D7H, 37H, 0B7H, 77H, 0F7H - .DB 0FH, 8FH, 4FH, 0CFH, 2FH, 0AFH, 6FH, 0EFH, 1FH, 9FH, 5FH, 0DFH, 3FH, 0BFH, 7FH, 0FFH -#ENDIF -; -; -; -SDSTR_PREFIX .TEXT "SD:$" -SDSTR_ARROW .TEXT "-->$" -SDSTR_RC .TEXT "RC=$" -SDSTR_TOK .TEXT "TOK=$" -SDSTR_OK .TEXT "OK$" -SDSTR_ERR .TEXT "ERR$" -SDSTR_ERRRDYTO .TEXT "READY TIMEOUT$" -SDSTR_ERRINITTO .TEXT "INIT TIMEOUT$" -SDSTR_ERRCMD .TEXT "CMD ERR$" -SDSTR_ERRDATA .TEXT "DATA ERR$" -SDSTR_SDTYPE .TEXT "SD CARD TYPE: $" -; -;================================================================================================== -; SD DISK DRIVER - DATA -;================================================================================================== -; -SD_STAT .DB 0 -SD_TYPE .DB 0 -SD_RC .DB 0 -SD_TOK .DB 0 -SD_CMDBUF .EQU $ -SD_CMD .DB 0 -SD_CMDP0 .DB 0 -SD_CMDP1 .DB 0 -SD_CMDP2 .DB 0 -SD_CMDP3 .DB 0 -SD_CMDCRC .DB 0 diff --git a/branches/s100/Source/sd_data.asm b/branches/s100/Source/sd_data.asm deleted file mode 100644 index 0a6e665e..00000000 --- a/branches/s100/Source/sd_data.asm +++ /dev/null @@ -1,61 +0,0 @@ -; -;================================================================================================== -; IDE DISK DRIVER - DATA -;================================================================================================== -; -SD_SLICETRKS .EQU 65 ; TRACKS PER SLICE -SD_TRKSIZE .EQU 128 ; SIZE OF TRACK (IN KB) -SD_SLICESIZE .EQU ((SD_SLICETRKS * SD_TRKSIZE) + 1023) / 1024 ; SIZE OF EACH SLICE (IN MB) -SD_NUMSLICES .EQU SDCAPACITY / SD_SLICESIZE ; TOTAL SLICES IN DEVICE -SD0_SLICEDEF .EQU 0 ; DEFAULT SLICE FOR UNIT 0 -SD1_SLICEDEF .EQU 1 ; DEFAULT SLICE FOR UNIT 1 -SD2_SLICEDEF .EQU 2 ; DEFAULT SLICE FOR UNIT 0 -SD3_SLICEDEF .EQU 3 ; DEFAULT SLICE FOR UNIT 1 -; - .DB DIODEV_SD + 0 -SDDPH0 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW SDCSV0,SDALV0 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -SD0_SLICE .DW SD0_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW SD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_SD + 0 -SDDPH1 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW SDCSV1,SDALV1 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -SD1_SLICE .DW SD1_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW SD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_SD + 0 -SDDPH2 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW SDCSV2,SDALV2 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -SD2_SLICE .DW SD2_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW SD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; - .DB DIODEV_SD + 0 -SDDPH3 .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPB_HD - .DW SDCSV3,SDALV3 - .DB "LU" ; LOGICAL UNIT ENHANCEMENT SIGNATURE -SD3_SLICE .DW SD3_SLICEDEF ; CURRENTLY ACTIVE SLICE - .DW SD_NUMSLICES ; NUMBER OF SLICES AVAILABLE -; -SDCKS .EQU 0 ; CKS: 0 FOR NON-REMOVABLE MEDIA -SDALS .EQU 256 ; ALS: BLKS / 8 = 2048 / 8 = 256 (ROUNDED UP) -; -SDCSV0: .FILL SDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -SDALV0: .FILL SDALS ; MAX OF 2048 DATA BLOCKS -SDCSV1: .FILL SDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -SDALV1: .FILL SDALS ; MAX OF 2048 DATA BLOCKS -SDCSV2: .FILL SDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -SDALV2: .FILL SDALS ; MAX OF 2048 DATA BLOCKS -SDCSV3: .FILL SDCKS ; NO DIRECTORY CHECKSUM, NON-REMOVABLE DRIVE -SDALV3: .FILL SDALS ; MAX OF 2048 DATA BLOCKS diff --git a/branches/s100/Source/std-n8vem.inc b/branches/s100/Source/std-n8vem.inc deleted file mode 100644 index 769b2aea..00000000 --- a/branches/s100/Source/std-n8vem.inc +++ /dev/null @@ -1,34 +0,0 @@ -; -; CHARACTER DEVICES -; -CIODEV_UART .EQU $00 -CIODEV_ASCI .EQU $10 -CIODEV_VDU .EQU $20 -CIODEV_CVDU .EQU $30 -CIODEV_UPD7220 .EQU $40 -CIODEV_N8V .EQU $50 -CIODEV_PRPCON .EQU $60 -CIODEV_PPPCON .EQU $70 -CIODEV_CRT .EQU $D0 -CIODEV_BAT .EQU $E0 -CIODEV_NUL .EQU $F0 -; -; DISK DEVICES (ONLY FIRST NIBBLE RELEVANT, SECOND NIBBLE RESERVED FOR UNIT) -; -DIODEV_MD .EQU $00 -DIODEV_FD .EQU $10 -DIODEV_IDE .EQU $20 -DIODEV_ATAPI .EQU $30 -DIODEV_PPIDE .EQU $40 -DIODEV_SD .EQU $50 -DIODEV_PRPSD .EQU $60 -DIODEV_PPPSD .EQU $70 -DIODEV_HDSK .EQU $80 -; -; VDA DEVICES (VIDEO DISPLAY ADAPTER) -; -VDADEV_NONE .EQU $00 ; NO VDA DEVICE -VDADEV_VDU .EQU $10 ; ECB VDU - 6545 CHIP -VDADEV_CVDU .EQU $20 ; ECB COLOR VDU - 8563 CHIP (NOT IMP) -VDADEV_UPD7220 .EQU $30 ; ECB uP7220 (NOT IMPLEMENTED) -VDADEV_N8V .EQU $40 ; N8 ONBOARD VDA SUBSYSTEM diff --git a/branches/s100/Source/std-s100.inc b/branches/s100/Source/std-s100.inc deleted file mode 100644 index cfbe3c37..00000000 --- a/branches/s100/Source/std-s100.inc +++ /dev/null @@ -1,37 +0,0 @@ -; std-s100.inc 1/19/2013 dwg - -; -;=============================================================================== -; -; CHARACTER DEVICES -; -CIODEV_UART .EQU $00 -CIODEV_N8V .EQU $50 -CIODEV_PRPCON .EQU $60 -CIODEV_PPPCON .EQU $70 -CIODEV_CRT .EQU $D0 -CIODEV_BAT .EQU $E0 -CIODEV_NUL .EQU $F0 -; -; DISK DEVICES (ONLY FIRST NIBBLE RELEVANT, SECOND NIBBLE RESERVED FOR UNIT) -; -DIODEV_MD .EQU $00 -DIODEV_FD .EQU $10 -DIODEV_IDE .EQU $20 -DIODEV_ATAPI .EQU $30 -DIODEV_PPIDE .EQU $40 -DIODEV_SD .EQU $50 -DIODEV_PRPSD .EQU $60 -DIODEV_PPPSD .EQU $70 -DIODEV_HDSK .EQU $80 -; -; VDA DEVICES (VIDEO DISPLAY ADAPTER) -; -VDADEV_NONE .EQU $00 ; NO VDA DEVICE -VDADEV_VDU .EQU $10 ; ECB VDU - 6545 CHIP -VDADEV_CVDU .EQU $20 ; ECB COLOR VDU - 8563 CHIP (NOT IMP) -VDADEV_UPD7220 .EQU $30 ; ECB uP7220 (NOT IMPLEMENTED) -VDADEV_N8V .EQU $40 ; N8 ONBOARD VDA SUBSYSTEM - -;;;;;;;;;;;;;;;;;;;;;; -; eof - std-s100.inc ; -;;;;;;;;;;;;;;;;;;;;;; diff --git a/branches/s100/Source/std.asm b/branches/s100/Source/std.asm deleted file mode 100644 index cd14fe07..00000000 --- a/branches/s100/Source/std.asm +++ /dev/null @@ -1,376 +0,0 @@ -; ~/RomWBW/branches/s100/Source/std.asm 1/19/2013 dwg - -; - -; The purpose of this file is to define generic symbols and to include -; the appropriate std-*.inc file to bring in platform specifics. - -; There are four classes of systems supported by N8VEM. -; 1. N8VEM Platforms that include ECB interface -; 2. ZETA Genrally N8VEM-like, but no ECB -; 3. N8 Generally N8VEM-like bt 180 and extra embedded devices -; 4. S100 Assumes Z80 Master CPU Card - -; All the classes require certain generic definitions, and these are -; defined here prior to the inclusion of platform specific .inc files. - -; It is unfortunate, but all the possible config items must be defined -; here because the config gets read before the specific std-*.inc's - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -TRUE .EQU 1 -FALSE .EQU 0 -; -; DEPRECATED STUFF!!! -; -DIOPLT .EQU 0 ; DEPRECATED!!! -VDUMODE .EQU 0 ; DEPRECATED!!! -BIOSSIZE .EQU 0100H ; DEPRECATED!!! -; -; PRIMARY HARDWARE PLATFORMS -; -PLT_N8VEM .EQU 1 ; N8VEM ECB Z80 SBC -PLT_ZETA .EQU 2 ; ZETA Z80 SBC -PLT_N8 .EQU 3 ; N8 (HOME COMPUTER) Z180 SBC -PLT_S2I .EQU 4 ; SCSI2IDE -PLT_S100 .EQU 5 ; S100COMPUTERS Z80 based system -; -; BOOT STYLE -; -BT_MENU .EQU 1 ; WAIT FOR MENU SELECTION AT LOADER PROMPT -BT_AUTO .EQU 2 ; AUTO SELECT BOOT_DEFAULT AFTER BOOT_TIMEOUT -; -; RAM DISK INITIALIZATION OPTIONS -; -CLR_NEVER .EQU 0 ; NEVER CLEAR RAM DISK -CLR_AUTO .EQU 1 ; CLEAR RAM DISK IF INVALID DIR ENTRIES -CLR_ALWAYS .EQU 2 ; ALWAYS CLEAR RAM DISK -; -; DISK MAP SELECTION OPTIONS -; -DM_ROM .EQU 1 ; ROM DRIVE PRIORITY -DM_RAM .EQU 2 ; RAM DRIVE PRIORITY -DM_FD .EQU 3 ; FLOPPY DRIVE PRIORITY -DM_IDE .EQU 4 ; IDE DRIVE PRIORITY -DM_PPIDE .EQU 5 ; PPIDE DRIVE PRIORITY -DM_SD .EQU 6 ; SD DRIVE PRIORITY -DM_PRPSD .EQU 7 ; PROPIO SD DRIVE PRIORITY -DM_PPPSD .EQU 8 ; PROPIO SD DRIVE PRIORITY -DM_HDSK .EQU 9 ; SIMH HARD DISK DRIVE PRIORITY -; -; FLOPPY DISK MEDIA SELECTIONS (ID'S MUST BE INDEX OF ENTRY IN FCD_TBL) -; -FDM720 .EQU 0 ; 3.5" FLOPPY, 720KB, 2 SIDES, 80 TRKS, 9 SECTORS -FDM144 .EQU 1 ; 3.5" FLOPPY, 1.44MB, 2 SIDES, 80 TRKS, 18 SECTORS -FDM360 .EQU 2 ; 5.25" FLOPPY, 360KB, 2 SIDES, 40 TRKS, 9 SECTORS -FDM120 .EQU 3 ; 5.25" FLOPPY, 1.2MB, 2 SIDES, 80 TRKS, 15 SECTORS -FDM111 .EQU 4 ; 8" FLOPPY, 1.11MB, 2 SIDES, 74 TRKS, 15 SECTORS -; -; MEDIA ID VALUES -; -MID_NONE .EQU 0 -MID_MDROM .EQU 1 -MID_MDRAM .EQU 2 -MID_HD .EQU 3 -MID_FD720 .EQU 4 -MID_FD144 .EQU 5 -MID_FD360 .EQU 6 -MID_FD120 .EQU 7 -MID_FD111 .EQU 8 -; -; FD MODE SELECTIONS -; -FDMODE_NONE .equ 0 ; FD modes defined in std-*.inc -FDMODE_DIO .EQU 1 ; DISKIO V1 -FDMODE_ZETA .EQU 2 ; ZETA -FDMODE_DIDE .EQU 3 ; DUAL IDE -FDMODE_N8 .EQU 4 ; N8 -FDMODE_DIO3 .EQU 5 ; DISKIO V3 -; -; IDE MODE SELECTIONS -; -IDEMODE_NONE .EQU 0 -IDEMODE_DIO .EQU 1 ; DISKIO V1 -IDEMODE_DIDE .EQU 2 ; DUAL IDE -; -; PPIDE MODE SELECTIONS -; -PPIDEMODE_NONE .EQU 0 -PPIDEMODE_STD .EQU 1 ; STANDARD N8VEM PARALLEL PORT -PPIDEMODE_DIO3 .EQU 2 ; DISKIO V3 PARALLEL PORT -; -; CONSOLE TERMINAL TYPE CHOICES -; -TERM_TTY .EQU 0 -TERM_ANSI .EQU 1 -TERM_WYSE .EQU 2 -TERM_VT52 .EQU 3 -; -; EMULATION TYPES -; -EMUTYP_NONE .EQU 0 -EMUTYP_TTY .EQU 1 -EMUTYP_ANSI .EQU 2 -; -; SCSI DEVICE PERSONALITY CHOICES -; -S2I_PER_N8VEM .EQU 1 -S2I_PER_ST125N .EQU 2 -; -; SYSTEM GENERATION SETTINGS -; -SYS_CPM .EQU 1 ; CPM (IMPLIES BDOS + CCP) -SYS_ZSYS .EQU 2 ; ZSYSTEM OS (IMPLIES ZSDOS + ZCPR) -; -DOS_BDOS .EQU 1 ; BDOS -DOS_ZDDOS .EQU 2 ; ZDDOS VARIANT OF ZSDOS -DOS_ZSDOS .EQU 3 ; ZSDOS -; -CP_CCP .EQU 1 ; CCP COMMAND PROCESSOR -CP_ZCPR .EQU 2 ; ZCPR COMMAND PROCESSOR -; -; CONFIGURE DOS (DOS) AND COMMAND PROCESSOR (CP) BASED ON SYSTEM SETTING (SYS) -; -#IFNDEF BLD_SYS -SYS .EQU SYS_CPM -#ELSE -SYS .EQU BLD_SYS -#ENDIF -; -#IF (SYS == SYS_CPM) -DOS .EQU DOS_BDOS -CP .EQU CP_CCP -#DEFINE OSLBL "CP/M-80 2.2" -#ENDIF -; -#IF (SYS == SYS_ZSYS) -DOS .EQU DOS_ZSDOS -CP .EQU CP_ZCPR -#DEFINE OSLBL "ZSDOS 1.1" -#ENDIF -; -; INCLUDE VERSION AND BUILD SETTINGS -; -#INCLUDE "ver.inc" ; ADD BIOSVER -; -#INCLUDE "build.inc" ; INCLUDE USER CONFIG, ADD VARIANT, TIMESTAMP, & ROMSIZE -; -; INCLUDE PLATFORM SPECIFIC HARDWARE DEFINITIONS -; -#IF ((PLATFORM == PLT_N8VEM) | (PLATFORM == PLT_ZETA)) -#INCLUDE "n8vem.inc" -#ENDIF -; -#IF (PLATFORM == PLT_S2I) -#INCLUDE "s2i.inc" -#ENDIF -; -#IF (PLATFORM == PLT_N8) -#INCLUDE "n8.inc" -#ENDIF -; -#IF (PLATFORM == PLT_S100) -; -#DEFINE S100_IOB ; WBW: FORCED ON TO MAKE BUILD WORK! -; -#IFDEF S100_CPU -#INCLUDE "S100CPU.INC" -#ENDIF -; -#IFDEF S100_IOB -#INCLUDE "S100IOB.INC" -#ENDIF -; -#IFDEF S100_RRF -#INCLUDE "S100RRF.INC" -#ENDIF -; -#IFDEF S100_DIDE -#INCLUDE "S100DIDE.INC" -#ENDIF -; -#ENDIF -; -; CHARACTER DEVICE FUNCTIONS -; -CF_INIT .EQU 0 -CF_IN .EQU 1 -CF_IST .EQU 2 -CF_OUT .EQU 3 -CF_OST .EQU 4 -; -; DISK OPERATIONS -; -DOP_READ .EQU 0 ; READ OPERATION -DOP_WRITE .EQU 1 ; WRITE OPERATION -DOP_FORMAT .EQU 2 ; FORMAT OPERATION -DOP_READID .EQU 3 ; READ ID OPERATION -; -; DISK DRIVER FUNCTIONS -; -DF_READY .EQU 1 -DF_SELECT .EQU 2 -DF_READ .EQU 3 -DF_WRITE .EQU 4 -DF_FORMAT .EQU 5 -; -; BIOS FUNCTIONS -; -BF_CIO .EQU $00 -BF_CIOIN .EQU BF_CIO + 0 ; CHARACTER INPUT -BF_CIOOUT .EQU BF_CIO + 1 ; CHARACTER OUTPUT -BF_CIOIST .EQU BF_CIO + 2 ; CHARACTER INPUT STATUS -BF_CIOOST .EQU BF_CIO + 3 ; CHARACTER OUTPUT STATUS -BF_CIOCFG .EQU BF_CIO + 4 ; CHARACTER I/O CONFIG -; -BF_DIO .EQU $10 -BF_DIORD .EQU BF_DIO + 0 ; DISK READ -BF_DIOWR .EQU BF_DIO + 1 ; DISK WRITE -BF_DIOST .EQU BF_DIO + 2 ; DISK STATUS -BF_DIOMED .EQU BF_DIO + 3 ; DISK MEDIA -BF_DIOID .EQU BF_DIO + 4 ; DISK IDENTIFY -BF_DIOGETBUF .EQU BF_DIO + 8 ; DISK GET BUFFER ADR -BF_DIOSETBUF .EQU BF_DIO + 9 ; DISK SET BUFFER ADR -; -BF_RTC .EQU $20 -BF_RTCGETTIM .EQU BF_RTC + 0 ; GET TIME -BF_RTCSETTIM .EQU BF_RTC + 1 ; SET TIME -BF_RTCGETBYT .EQU BF_RTC + 2 ; GET NVRAM BYTE BY INDEX -BF_RTCSETBYT .EQU BF_RTC + 3 ; SET NVRAM BYTE BY INDEX -BF_RTCGETBLK .EQU BF_RTC + 4 ; GET NVRAM DATA BLOCK -BF_RTCSETBLK .EQU BF_RTC + 5 ; SET NVRAM DATA BLOCK -; -BF_EMU .EQU $30 -BF_EMUIN .EQU BF_EMU + 0 ; EMULATOR CHARACTER INPUT -BF_EMUOUT .EQU BF_EMU + 1 ; EMULATOR CHARACTER OUTPUT -BF_EMUIST .EQU BF_EMU + 2 ; EMULATOR CHARACTER INPUT STATUS -BF_EMUOST .EQU BF_EMU + 3 ; EMULATOR CHARACTER OUTPUT STATUS -BF_EMUCFG .EQU BF_EMU + 4 ; EMULATOR CHARACTER I/O CONFIG -BF_EMUINI .EQU BF_EMU + 8 ; INITIALIZE EMULATION -BF_EMUQRY .EQU BF_EMU + 9 ; QUERY EMULATION STATUS -; -BF_VDA .EQU $40 -BF_VDAINI .EQU BF_VDA + 0 ; INITIALIZE VDU -BF_VDAQRY .EQU BF_VDA + 1 ; QUERY VDU STATUS -BF_VDARES .EQU BF_VDA + 2 ; SOFT RESET VDU -BF_VDASCS .EQU BF_VDA + 3 ; SET CURSOR STYLE -BF_VDASCP .EQU BF_VDA + 4 ; SET CURSOR POSITION -BF_VDASAT .EQU BF_VDA + 5 ; SET CHARACTER ATTRIBUTE -BF_VDASCO .EQU BF_VDA + 6 ; SET CHARACTER COLOR -BF_VDAWRC .EQU BF_VDA + 7 ; WRITE CHARACTER -BF_VDAFIL .EQU BF_VDA + 8 ; FILL -BF_VDACPY .EQU BF_VDA + 9 ; COPY -BF_VDASCR .EQU BF_VDA + 10 ; SCROLL -BF_VDAKST .EQU BF_VDA + 11 ; GET KEYBOARD STATUS -BF_VDAKFL .EQU BF_VDA + 12 ; FLUSH KEYBOARD BUFFER -BF_VDAKRD .EQU BF_VDA + 13 ; READ KEYBOARD -; -BF_SYS .EQU $F0 -BF_SYSGETCFG .EQU BF_SYS + 0 ; GET CONFIGURATION DATA BLOCK -BF_SYSSETCFG .EQU BF_SYS + 1 ; SET CONFIGURATION DATA BLOCK -BF_SYSBNKCPY .EQU BF_SYS + 2 ; COPY TO/FROM RAM/ROM MEMORY BANK -BF_SYSGETVER .EQU BF_SYS + 3 ; GET VERSION OF HBIOS -; -; MEMORY LAYOUT -; -CPM_LOC .EQU 0D000H ; CONFIGURABLE: LOCATION OF CPM FOR RUNNING SYSTEM -CPM_SIZ .EQU 2F00H ; SIZE OF CPM IMAGE (CCP + BDOS + CBIOS (INCLUDING DATA)) -CPM_END .EQU CPM_LOC + CPM_SIZ -; -CCP_LOC .EQU CPM_LOC ; START OF COMMAND PROCESSOR -CCP_SIZ .EQU 800H -CCP_END .EQU CCP_LOC + CCP_SIZ -; -BDOS_LOC .EQU CCP_END ; START OF BDOS -BDOS_SIZ .EQU 0E00H -BDOS_END .EQU BDOS_LOC + BDOS_SIZ -; -CBIOS_LOC .EQU BDOS_END -CBIOS_SIZ .EQU CPM_END - CBIOS_LOC -CBIOS_END .EQU CBIOS_LOC + CBIOS_SIZ -; -CPM_ENT .EQU CBIOS_LOC -; -HB_LOC .EQU CPM_END -HB_SIZ .EQU 100H -HB_END .EQU HB_LOC + HB_SIZ -; -MON_LOC .EQU 0C000H ; LOCATION OF MONITOR FOR RUNNING SYSTEM -MON_SIZ .EQU 01000H ; SIZE OF MONITOR BINARY IMAGE -MON_END .EQU MON_LOC + MON_SIZ -MON_DSKY .EQU MON_LOC ; MONITOR ENTRY (DSKY) -MON_UART .EQU MON_LOC + 3 ; MONITOR ENTRY (UART) -; -CBIOS_BOOT .EQU CBIOS_LOC + 0 -CBIOS_WBOOT .EQU CBIOS_LOC + 3 -CBIOS_CONST .EQU CBIOS_LOC + 6 -CBIOS_CONIN .EQU CBIOS_LOC + 9 -CBIOS_CONOUT .EQU CBIOS_LOC + 12 -CBIOS_LIST .EQU CBIOS_LOC + 15 -CBIOS_PUNCH .EQU CBIOS_LOC + 18 -CBIOS_READER .EQU CBIOS_LOC + 21 -CBIOS_HOME .EQU CBIOS_LOC + 24 -CBIOS_SELDSK .EQU CBIOS_LOC + 27 -CBIOS_SETTRK .EQU CBIOS_LOC + 30 -CBIOS_SETSEC .EQU CBIOS_LOC + 33 -CBIOS_SETDMA .EQU CBIOS_LOC + 36 -CBIOS_READ .EQU CBIOS_LOC + 39 -CBIOS_WRITE .EQU CBIOS_LOC + 42 -CBIOS_LISTST .EQU CBIOS_LOC + 45 -CBIOS_SECTRN .EQU CBIOS_LOC + 48 -; -; EXTENDED CBIOS FUNCTIONS -; -CBIOS_BNKSEL .EQU CBIOS_LOC + 51 -CBIOS_GETDSK .EQU CBIOS_LOC + 54 -CBIOS_SETDSK .EQU CBIOS_LOC + 57 -CBIOS_GETINFO .EQU CBIOS_LOC + 60 -; -; PLACEHOLDERS FOR FUTURE CBIOS EXTENSIONS -; -CBIOS_RSVD1 .EQU CBIOS_LOC + 63 -CBIOS_RSVD2 .EQU CBIOS_LOC + 76 -CBIOS_RSVD3 .EQU CBIOS_LOC + 69 -CBIOS_RSVD4 .EQU CBIOS_LOC + 72 -; -CDISK: .EQU 00004H ; LOC IN PAGE 0 OF CURRENT DISK NUMBER 0=A,...,15=P -IOBYTE: .EQU 00003H ; LOC IN PAGE 0 OF I/O DEFINITION BYTE. -; -; MEMORY CONFIGURATION -; -MSIZE .EQU 59 ; CP/M VERSION MEMORY SIZE IN KILOBYTES -; -; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS -; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT) -; -BIAS: .EQU (MSIZE-20)*1024 -CCP: .EQU 3400H+BIAS ; BASE OF CCP -BDOS: .EQU CCP+806H ; BASE OF BDOS -BIOS: .EQU CCP+1600H ; BASE OF BIOS -CCPSIZ: .EQU 00800H -; -#IF (PLATFORM == PLT_N8VEM) - #DEFINE PLATFORM_NAME "N8VEM Z80" -#ENDIF -#IF (PLATFORM == PLT_ZETA) - #DEFINE PLATFORM_NAME "ZETA Z80" -#ENDIF -#IF (PLATFORM == PLT_N8) - #DEFINE PLATFORM_NAME "N8 Z180" -#ENDIF -#IF (PLATFORM == PLT_S2I) - #DEFINE PLATFORM_NAME "SCSI2IDE Z80" -#ENDIF -#IF (PLATFORM == PLT_S100) - #DEFINE PLATFORM_NAME "S100" -#ENDIF -; -; HELPER MACROS -; -#DEFINE PRTC(C) CALL PRTCH \ .DB C ; PRINT CHARACTER C TO CONSOLE - PRTC('X') -#DEFINE PRTS(S) CALL PRTSTRD \ .DB S ; PRINT STRING S TO CONSOLE - PRTD("HELLO") -#DEFINE PRTX(X) CALL PRTSTRI \ .DW X ; PRINT STRING AT ADDRESS X TO CONSOLE - PRTI(STR_HELLO) -; -#DEFINE XIO_PRTC(C) CALL XIO_PRTCH \ .DB C ; PRINT CHARACTER C TO CONSOLE - PRTC('X') -#DEFINE XIO_PRTS(S) CALL XIO_PRTSTRD \ .DB S ; PRINT STRING S TO CONSOLE - PRTD("HELLO") -#DEFINE XIO_PRTX(X) CALL XIO_PRTSTRI \ .DW X ; PRINT STRING AT ADDRESS X TO CONSOLE - PRTI(STR_HELLO) diff --git a/branches/s100/Source/syscfg.asm b/branches/s100/Source/syscfg.asm deleted file mode 100644 index d0102776..00000000 --- a/branches/s100/Source/syscfg.asm +++ /dev/null @@ -1,34 +0,0 @@ -;___SYSCFG_____________________________________________________________________________________________________________ -; -; syscfg.asm 3/04/2012 2.0.0.0 dwg - added required configuration information -; -; Include standard BIOS definitions -; -#INCLUDE "std.asm" -; - .ORG 0000H ; ALL ADDRESSES GENERATED WILL BE ZERO BASED -; - JP 0000H ; DUMMY JP INSTRUCTION FOR COMPATIBILITY -; -; Reserved for Configuration Information -; - .DW cnf_loc - .DW tst_loc1 - .DW var_loc1 -; -; BIOS configuration data -; -cnf_loc: -#INCLUDE "cnfgdata.inc" -; -; Build information strings -; -tst_loc1 .DB TIMESTAMP -var_loc1 .DB VARIANT - .DB '$' ; provide terminator for variable length field -; - .EXPORT DISKBOOT,BOOTDEVICE,BOOTLU -; - .FILL 200H - $,$FF -; - .END diff --git a/branches/s100/Source/tty.asm b/branches/s100/Source/tty.asm deleted file mode 100644 index a4f348e1..00000000 --- a/branches/s100/Source/tty.asm +++ /dev/null @@ -1,162 +0,0 @@ -; -; tty_dochar - added setup in HL of position data before call to write -;================================================================================================== -; TTY EMULATION MODULE -;================================================================================================== -; -; TODO: -; - SOME FUNCTIONS ARE NOT IMPLEMENTED!!! -; -TTY_INIT: - PRTS("TTY: RESET$") -; - JR TTY_INI ; REUSE THE INI FUNCTION BELOW -; -; -; -TTY_DISPATCH: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,TTY_IN ; $30 - DEC A - JR Z,TTY_OUT ; $31 - DEC A - JR Z,TTY_IST ; $32 - DEC A - JR Z,TTY_OST ; $33 - DEC A - JR Z,TTY_CFG ; $34 - CP 8 - JR Z,TTY_INI ; $38 - CP 9 - JR Z,TTY_QRY ; $39 - CALL PANIC -; -; -; -TTY_IN: - LD B,BF_VDAKRD ; SET FUNCTION TO KEYBOARD READ - JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER -; -; -; -TTY_OUT: - CALL TTY_DOCHAR ; HANDLE THE CHARACTER (EMULATION ENGINE) - XOR A ; SIGNAL SUCCESS - RET -; -; -; -TTY_IST: - LD B,BF_VDAKST ; SET FUNCTION TO KEYBOARD STATUS - JP EMU_VDADISP ; CHAIN TO VDA DISPATCHER -; -; -; -TTY_OST: - XOR A ; ZERO ACCUM - INC A ; A := $FF TO SIGNAL OUTPUT BUFFER READY - RET -; -; -; -TTY_CFG: - XOR A ; SIGNAL SUCCESS - RET -; -; -; -TTY_INI: - LD B,BF_VDAQRY ; FUNCTION IS QUERY - LD HL,0 ; WE DO NOT WANT A COPY OF THE CHARACTER BITMAP DATA - CALL EMU_VDADISP ; PERFORM THE QUERY FUNCTION - LD (TTY_DIM),DE ; SAVE THE SCREEN DIMENSIONS RETURNED - LD DE,0 ; DE := 0, CURSOR TO HOME POSITION 0,0 - LD (TTY_POS),DE ; SAVE CURSOR POSITION - LD B,BF_VDARES ; SET FUNCTION TO RESET - JP EMU_VDADISP ; RESET VDA AND RETURN -; -; -; -TTY_QRY: - XOR A ; SIGNAL SUCCESS - RET -; -; -; -TTY_DOCHAR: - LD A,E ; CHARACTER TO PROCESS - CP 8 ; BACKSPACE - JR Z,TTY_BS - CP 12 ; FORMFEED - JR Z,TTY_FF - CP 13 ; CARRIAGE RETURN - JR Z,TTY_CR - CP 10 ; LINEFEED - JR Z,TTY_LF - CP 32 ; COMPARE TO SPACE (FIRST PRINTABLE CHARACTER) - RET C ; SWALLOW OTHER CONTROL CHARACTERS - LD B,BF_VDAWRC - CALL EMU_VDADISP ; SPIT OUT THE RAW CHARACTER - LD A,(TTY_COL) ; GET CUR COL - INC A ; INCREMENT - LD (TTY_COL),A ; SAVE IT - LD DE,(TTY_DIM) ; GET SCREEN DIMENSIONS - CP E ; COMPARE TO COLS IN LINE - RET C ; NOT PAST END OF LINE, ALL DONE - CALL TTY_CR ; CARRIAGE RETURN - JR TTY_LF ; LINEFEED AND RETURN -; -TTY_FF: - LD DE,0 ; PREPARE TO HOME CURSOR - LD (TTY_POS),DE ; SAVE NEW CURSOR POSITION - CALL TTY_XY ; EXECUTE - LD DE,(TTY_DIM) ; GET SCREEN DIMENSIONS - LD H,D ; SET UP TO MULTIPLY ROWS BY COLS - CALL MULT8 ; HL := H * E TO GET TOTAL SCREEN POSITIONS - LD E,' ' ; FILL SCREEN WITH BLANKS - LD B,BF_VDAFIL ; SET FUNCTION TO FILL - CALL EMU_VDADISP ; PERFORM FILL - JR TTY_XY ; HOME CURSOR AND RETURN -; -TTY_BS: - LD A,(TTY_COL) ; GET CURRENT COLUMN - DEC A ; BACK IT UP BY ONE - RET C ; IF CARRY, MARGIN EXCEEDED, ABORT - LD (TTY_COL),A ; SAVE NEW COLUMN - JP TTY_XY ; UDPATE CUSROR AND RETURN -; -TTY_CR: - XOR A ; ZERO ACCUM - LD (TTY_COL),A ; COL := 0 - JR TTY_XY ; REPOSITION CURSOR AND RETURN -; -TTY_LF: ; LINEFEED (FORWARD INDEX) - LD A,(TTY_ROW) ; GET CURRENT ROW - LD DE,(TTY_DIM) ; GET SCREEN DIMENSIONS - DEC D ; D := MAX ROW NUM - CP D ; >= LAST ROW? - JR NC,TTY_LF1 ; IF SO, NEED TO SCROLL - INC A ; BUMP TO NEXT ROW - LD (TTY_ROW),A ; SAVE IT - JP TTY_XY ; UPDATE CURSOR AND RETURN -; -TTY_LF1: ; SCROLL - LD E,1 ; SCROLL FORWARD 1 LINE - LD B,BF_VDASCR ; SET FUNCTION TO SCROLL - JP EMU_VDADISP ; DO THE SCROLLING AND RETURN -; -TTY_XY: - LD DE,(TTY_POS) ; GET THE DESIRED CURSOR POSITION - LD B,BF_VDASCP ; SET FUNCTIONT TO SET CURSOR POSITION - JP EMU_VDADISP ; REPOSITION CURSOR -; -; -; -TTY_POS: -TTY_COL .DB 0 ; CURRENT COLUMN - 0 BASED -TTY_ROW .DB 0 ; CURRENT ROW - 0 BASED -; -TTY_DIM: -TTY_COLS .DB 80 ; NUMBER OF COLUMNS ON SCREEN -TTY_ROWS .DB 24 ; NUMBER OF ROWS ON SCREEN \ No newline at end of file diff --git a/branches/s100/Source/uart.asm b/branches/s100/Source/uart.asm deleted file mode 100644 index 4768013b..00000000 --- a/branches/s100/Source/uart.asm +++ /dev/null @@ -1,284 +0,0 @@ -; -;================================================================================================== -; UART DRIVER (SERIAL PORT) -;================================================================================================== -; -#IF (PLATFORM != PLT_N8) -UART0_DIV .EQU (1843200 / (16 * BAUDRATE)) -#ENDIF -; -; CHARACTER DEVICE DRIVER ENTRY -; A: RESULT (OUT), CF=ERR -; B: FUNCTION (IN) -; C: CHARACTER (IN/OUT) -; E: DEVICE/UNIT (IN) -; -; -UART_DISPATCH: -#IF (PLATFORM == PLT_N8) - LD A,C ; GET DEVICE/UNIT - AND $0F ; ISOLATE UNIT - JP Z,UART0 - DEC A - JP Z,UART1 - CALL PANIC -#ENDIF -; -UART0: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JP Z,UART0_IN - DEC A - JP Z,UART0_OUT - DEC A - JP Z,UART0_IST - DEC A - JP Z,UART0_OST - CALL PANIC -; -; -; -UART_INIT: -#IF (PLATFORM == PLT_N8) - ; ASCI0 - PRTS("ASCI0: IO=0x$") - LD A,CPU_TDR0 - CALL PRTHEXBYTE - CALL PC_COMMA - LD A,CPU_RDR0 - CALL PRTHEXBYTE - PRTS(" BAUD=$") -#IF ((BAUDRATE / 100) > 0) - LD HL,BAUDRATE / 100 - CALL PRTDEC -#ENDIF -#IF ((BAUDRATE % 100) < 10) - PRTC("0") -#ENDIF - LD HL,BAUDRATE % 100 - CALL PRTDEC - - LD A,66H - OUT0 (CPU_ASEXT0),A - LD A,64H - OUT0 (CPU_CNTLA0),A - LD A,Z180_CNTLB0 - OUT0 (CPU_CNTLB0),A - - ; ASCI1 - CALL NEWLINE - PRTS("ASCI1: IO=0x$") - LD A,CPU_TDR1 - CALL PRTHEXBYTE - CALL PC_COMMA - LD A,CPU_RDR1 - CALL PRTHEXBYTE - PRTS(" BAUD=$") -#IF ((BAUDRATE / 100) > 0) - LD HL,BAUDRATE / 100 - CALL PRTDEC -#ENDIF -#IF ((BAUDRATE % 100) < 10) - PRTC("0") -#ENDIF - LD HL,BAUDRATE % 100 - CALL PRTDEC - - LD A,66H - OUT0 (CPU_ASEXT1),A - LD A,64H - OUT0 (CPU_CNTLA1),A - LD A,Z180_CNTLB1 - OUT0 (CPU_CNTLB1),A -#ELSE - PRTS("UART0: IO=0x$") - LD A,SIO_BASE - CALL PRTHEXBYTE - PRTS(" BAUD=$") -#IF ((BAUDRATE / 100) > 0) - LD HL,BAUDRATE / 100 - CALL PRTDEC -#ENDIF -#IF ((BAUDRATE % 100) < 10) - PRTC("0") -#ENDIF - LD HL,BAUDRATE % 100 - CALL PRTDEC - - CALL PC_SPACE - - LD A,80H - OUT (SIO_LCR),A ; DLAB ON - LD A,UART0_DIV - OUT (SIO_DLL),A ; SET DIVISOR (LS) - LD A,00H - OUT (SIO_DLM),A ; SET DIVISOR (MS) - - LD B,03H ; B = DEFAULT SETTING FOR MCR (DTR + RTS) - -#IF (UARTAFC) - PRTS(" AFC$") - LD A,$55 ; TEST VALUE - OUT (SIO_SCR),A ; SET SCRATCH REG TO TEST VALUE - LD A,0BFH - OUT (SIO_LCR),A ; SET LCR=$BF TO ATTEMPT TO ACCESS EFR - IN A,(SIO_SCR) ; READ SCRATCH REGISTER - CP $55 ; IF $55, NO EFR - JR NZ,UART_AFC1 ; NZ, HAVE EFR, DO IT - SET 5,B ; ENABLE AUTO FLOW CONTROL - JR UART_AFC2 -UART_AFC1: - LD A,0C0H ; ENABLE CTS/RTS FLOW CONTROL - OUT (SIO_EFR),A ; SAVE IT -UART_AFC2: -#ENDIF - - LD A,03H - OUT (SIO_LCR),A ; DLAB OFF, 8 DATA, 1 STOP, NO PARITY - - LD A,B ; LOAD MCR VALUE TO SET - OUT (SIO_MCR),A ; SAVE IT - -#IF (UARTFIFO) -; LD A,07H ; ENABLE AND RESET FIFOS - LD A,01H ; ENABLE AND RESET FIFOS - OUT (SIO_FCR),A ; ENABLE FIFOS - PRTS(" FIFO$") -#ENDIF - -#ENDIF - RET -; -; -; -UART0_IN: - CALL UART0_IST - OR A - JR Z,UART0_IN -#IF (PLATFORM == PLT_N8) - IN0 A,(CPU_RDR0) ; READ THE CHAR FROM THE UART -#ELSE - IN A,(SIO_RBR) ; READ THE CHAR FROM THE UART -#ENDIF - LD E,A - RET -; -; -; -UART0_IST: -#IF (PLATFORM == PLT_N8) - ; CHECK FOR ERROR FLAGS - IN0 A,(CPU_STAT0) - AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR - JR Z,UART0_IST1 ; ALL IS WELL, CHECK FOR DATA - - ; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!! - IN0 A,(CPU_CNTLA0) - RES 3,A ; CLEAR EFR (ERROR FLAG RESET) - OUT0 (CPU_CNTLA0),A - -UART0_IST1: ; CHECK FOR STAT0.RDRF (DATA READY) - IN0 A,(CPU_STAT0) ; READ LINE STATUS REGISTER - AND $80 ; TEST IF DATA IN RECEIVE BUFFER -#ELSE - IN A,(SIO_LSR) ; READ LINE STATUS REGISTER - AND $01 ; TEST IF DATA IN RECEIVE BUFFER -#ENDIF - JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN - XOR A - INC A ; SIGNAL CHAR READY, A = 1 - RET -; -; -; -UART0_OUT: - CALL UART0_OST - OR A - JR Z,UART0_OUT - LD A,E -#IF (PLATFORM == PLT_N8) - OUT0 (CPU_TDR0),A -#ELSE - OUT (SIO_THR),A ; THEN WRITE THE CHAR TO UART -#ENDIF - RET -; -UART0_OST: -#IF (PLATFORM == PLT_N8) - IN0 A,(CPU_STAT0) - AND $02 -#ELSE - IN A,(SIO_LSR) ; READ LINE STATUS REGISTER - AND $20 -#ENDIF - JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN - XOR A - INC A ; SIGNAL BUFFER EMPTY, A = 1 - RET -; -; -; -#IF (PLATFORM == PLT_N8) -; -UART1: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,UART0_IN - DEC A - JR Z,UART0_OUT - DEC A - JR Z,UART0_IST - DEC A - JR Z,UART0_OST - CALL PANIC -; -; -; -UART1_IN: - CALL UART1_IST - OR A - JR Z,UART1_IN - IN0 A,(CPU_RDR1) ; READ THE CHAR FROM THE UART - LD E,A - RET -; -; -; -UART1_IST: - ; CHECK FOR ERROR FLAGS - IN0 A,(CPU_STAT1) - AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR - JR Z,UART1_IST1 ; ALL IS WELL, CHECK FOR DATA - - ; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!! - IN0 A,(CPU_CNTLA1) - RES 3,A ; CLEAR EFR (ERROR FLAG RESET) - OUT0 (CPU_CNTLA1),A - -UART1_IST1: ; CHECK FOR STAT0.RDRF (DATA READY) - IN0 A,(CPU_STAT1) ; READ LINE STATUS REGISTER - AND $80 ; TEST IF DATA IN RECEIVE BUFFER - JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN - XOR A - INC A ; SIGNAL CHAR READY, A = 1 - RET -; -; -; -UART1_OUT: - CALL UART1_OST - OR A - JR Z,UART1_OUT - LD A,E - OUT0 (CPU_TDR1),A - RET -; -UART1_OST: - IN0 A,(CPU_STAT1) - AND $02 - JR Z,UART1_OST - JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN - XOR A - INC A ; SIGNAL BUFFER EMPTY, A = 1 - RET -#ENDIF diff --git a/branches/s100/Source/util.asm b/branches/s100/Source/util.asm deleted file mode 100644 index 83a487ee..00000000 --- a/branches/s100/Source/util.asm +++ /dev/null @@ -1,786 +0,0 @@ -; -;================================================================================================== -; UTILITY FUNCTIONS -;================================================================================================== -; -; -CHR_CR .EQU 0DH -CHR_LF .EQU 0AH -CHR_BS .EQU 08H -CHR_ESC .EQU 1BH -; -;__________________________________________________________________________________________________ -; -; UTILITY PROCS TO PRINT SINGLE CHARACTERS WITHOUT TRASHING ANY REGISTERS -; -PC_SPACE: - PUSH AF - LD A,' ' - JR PC_PRTCHR - -PC_PERIOD: - PUSH AF - LD A,'.' - JR PC_PRTCHR - -PC_COLON: - PUSH AF - LD A,':' - JR PC_PRTCHR - -PC_COMMA: - PUSH AF - LD A,',' - JR PC_PRTCHR - -PC_LBKT: - PUSH AF - LD A,'[' - JR PC_PRTCHR - -PC_RBKT: - PUSH AF - LD A,']' - JR PC_PRTCHR - -PC_LT: - PUSH AF - LD A,'<' - JR PC_PRTCHR - -PC_GT: - PUSH AF - LD A,'>' - JR PC_PRTCHR - -PC_LPAREN: - PUSH AF - LD A,'(' - JR PC_PRTCHR - -PC_RPAREN: - PUSH AF - LD A,')' - JR PC_PRTCHR - -PC_ASTERISK: - PUSH AF - LD A,'*' - JR PC_PRTCHR - -PC_CR: - PUSH AF - LD A,CHR_CR - JR PC_PRTCHR - -PC_LF: - PUSH AF - LD A,CHR_LF - JR PC_PRTCHR - -PC_PRTCHR: - CALL COUT - POP AF - RET - -NEWLINE: - CALL PC_CR - CALL PC_LF - RET -; -; PRINT A CHARACTER REFERENCED BY POINTER AT TOP OF STACK -; USAGE: -; CALL PRTCH -; .DB 'X' -; -PRTCH: - EX (SP),HL - PUSH AF - LD A,(HL) - CALL COUT - POP AF - INC HL - EX (SP),HL - RET -; -; PRINT A STRING AT ADDRESS SPECIFIED IN HL -; STRING MUST BE TERMINATED BY '$' -; USAGE: -; LD HL,MYSTR -; CALL PRTSTR -; ... -; MYSTR: .DB "HELLO$" -; -PRTSTR: - LD A,(HL) - INC HL - CP '$' - RET Z - CALL COUT - JR PRTSTR -; -; PRINT A STRING DIRECT: REFERENCED BY POINTER AT TOP OF STACK -; STRING MUST BE TERMINATED BY '$' -; USAGE: -; CALL PRTSTR -; .DB "HELLO$" -; ... -; -PRTSTRD: - EX (SP),HL - PUSH AF - CALL PRTSTR - POP AF - EX (SP),HL - RET -; -; PRINT A STRING INDIRECT: REFERENCED BY INDIRECT POINTER AT TOP OF STACK -; STRING MUST BE TERMINATED BY '$' -; USAGE: -; CALL PRTSTRI(MYSTRING) -; MYSTRING .DB "HELLO$" -; -PRTSTRI: - EX (SP),HL - PUSH AF - LD A,(HL) - INC HL - PUSH HL - LD H,(HL) - LD L,A - CALL PRTSTR - POP HL - INC HL - POP AF - EX (SP),HL - RET -; -; PRINT THE HEX BYTE VALUE IN A -; -PRTHEXBYTE: - PUSH AF - PUSH DE - CALL HEXASCII - LD A,D - CALL COUT - LD A,E - CALL COUT - POP DE - POP AF - RET -; -; PRINT THE HEX WORD VALUE IN BC -; -PRTHEXWORD: - PUSH AF - LD A,B - CALL PRTHEXBYTE - LD A,C - CALL PRTHEXBYTE - POP AF - RET -; -; CONVERT BINARY VALUE IN A TO ASCII HEX CHARACTERS IN DE -; -HEXASCII: - LD D,A - CALL HEXCONV - LD E,A - LD A,D - RLCA - RLCA - RLCA - RLCA - CALL HEXCONV - LD D,A - RET -; -; CONVERT LOW NIBBLE OF A TO ASCII HEX -; -HEXCONV: - AND 0FH ;LOW NIBBLE ONLY - ADD A,90H - DAA - ADC A,40H - DAA - RET -; -; PRINT A BYTE BUFFER IN HEX POINTED TO BY DE -; REGISTER A HAS SIZE OF BUFFER -; -PRTHEXBUF: - CP 0 ; EMPTY BUFFER? - JP Z,PRTHEXBUF2 - - LD B,A -PRTHEXBUF1: - CALL PC_SPACE - LD A,(DE) - CALL PRTHEXBYTE - INC DE - DJNZ PRTHEXBUF1 - JP PRTHEXBUFX - -PRTHEXBUF2: - CALL PC_SPACE - LD DE,STR_EMPTY - CALL WRITESTR - -PRTHEXBUFX: - RET -; -; OUTPUT A '$' TERMINATED STRING -; -WRITESTR: - PUSH AF -WRITESTR1: - LD A,(DE) - CP '$' ; TEST FOR STRING TERMINATOR - JP Z,WRITESTR2 - CALL COUT - INC DE - JP WRITESTR1 -WRITESTR2: - POP AF - RET -; -; PANIC: TRY TO DUMP MACHINE STATE AND HALT -; -PANIC: - PUSH HL - PUSH DE - PUSH BC - PUSH AF - LD DE,STR_PANIC - CALL WRITESTR - LD DE,STR_AF - CALL WRITESTR - POP BC ; AF - CALL PRTHEXWORD - LD DE,STR_BC - CALL WRITESTR - POP BC ; BC - CALL PRTHEXWORD - LD DE,STR_DE - CALL WRITESTR - POP BC ; DE - CALL PRTHEXWORD - LD DE,STR_HL - CALL WRITESTR - POP BC ; HL - CALL PRTHEXWORD - LD DE,STR_PC - CALL WRITESTR - POP BC ; PC - CALL PRTHEXWORD - LD DE,STR_SP - CALL WRITESTR - LD HL,0 - ADD HL,SP ; SP - LD B,H - LD C,L - CALL PRTHEXWORD - - RST 38 - - JP 0 -; -;================================================================================================== -; CONSOLE CHARACTER I/O HELPER ROUTINES (REGISTERS PRESERVED) -;================================================================================================== -; -; OUTPUT CHARACTER FROM A -COUT: - PUSH AF - PUSH BC - PUSH DE - PUSH HL -#IFDEF CIOMODE_CONSOLE - #DEFINE CIOMODE_NONDOS - LD E,A - LD A,(CONDEV) - LD C,A - LD B,BF_CIOOUT - CALL BIOS_DISPATCH -#ENDIF -#IFDEF CIOMODE_HBIOS - #DEFINE CIOMODE_NONDOS - LD E,A - LD A,DEFCON - LD C,A - LD B,BF_CIOOUT - RST 08 -#ENDIF -#IFDEF CIOMODE_CBIOS - #DEFINE CIOMODE_NONDOS - LD C,A - CALL CBIOS_CONOUT -#ENDIF -#IFNDEF CIOMODE_NONDOS - LD E,A - LD C,03H - CALL 0005H -#ENDIF - POP HL - POP DE - POP BC - POP AF - RET -; -; INPUT CHARACTER TO A -; -CIN: - PUSH BC - PUSH DE - PUSH HL -#IFDEF CIOMODE_CONSOLE - #DEFINE CIOMODE_NONDOS - LD A,(CONDEV) - LD C,A - LD B,BF_CIOIN - CALL BIOS_DISPATCH - LD A,E -#ENDIF -#IFDEF CIOMODE_HBIOS - #DEFINE CIOMODE_NONDOS - LD A,DEFCON - LD C,A - LD B,BF_CIOIN - RST 08 - LD A,E -#ENDIF -#IFDEF CIOMODE_CBIOS - #DEFINE CIOMODE_NONDOS - CALL CBIOS_CONIN -#ENDIF -#IFNDEF CIOMODE_NONDOS - LD C,01H - CALL 0005H -#ENDIF - POP HL - POP DE - POP BC - RET -; -; RETURN INPUT STATUS IN A (0 = NO CHAR, !=0 CHAR WAITING) -; -CST: - PUSH BC - PUSH DE - PUSH HL -#IFDEF CIOMODE_CONSOLE - #DEFINE CIOMODE_NONDOS - LD B,BF_CIOIST - LD A,(CONDEV) - LD C,A - CALL BIOS_DISPATCH -#ENDIF -#IFDEF CIOMODE_HBIOS - #DEFINE CIOMODE_NONDOS - LD B,BF_CIOIST - LD A,DEFCON - LD C,A - RST 08 -#ENDIF -#IFDEF CIOMODE_CBIOS - #DEFINE CIOMODE_NONDOS - CALL CBIOS_CONST -#ENDIF -#IFNDEF CIOMODE_NONDOS - LD C,0BH - CALL 0005H -#ENDIF - POP HL - POP DE - POP BC - RET -; -STR_PANIC .DB "\r\n\r\n>>> FATAL ERROR:$" -STR_AF .DB " AF=$" -STR_BC .DB " BC=$" -STR_DE .DB " DE=$" -STR_HL .DB " HL=$" -STR_PC .DB " PC=$" -STR_SP .DB " SP=$" -; -; INDIRECT JUMP TO ADDRESS IN HL -; -; MOSTLY USEFUL TO PERFORM AN INDIRECT CALL LIKE: -; LD HL,xxxx -; CALL JPHL -; -JPHL: JP (HL) -; -; DELAY ABOUT 25us (100 TSTATES INCLUDING CALL AND RET) -; -; TOTAL T STATES = ((B*13) + 51) -; 4MHZ CPU, B=4, 103 T STATES = 25.75us -; 8MHZ CPU, B=12, 207 TSTATES = 25.875us -; B = ((2 * FREQ) - 4) -; -DELAY: ; 17 T STATES (FOR CALL) - PUSH BC ; 11 T STATES - LD B,((CPUFREQ * 2) - 4) ; 8 T STATES - DJNZ $ ; (B*13) - 5 T STATES - POP BC ; 10 T STATES - RET ; 10 T STATES -; -; DELAY 25us * VALUE IN DE (VARIABLE DELAY) -; -VDELAY: - CALL DELAY - DEC DE - LD A,D - OR E - JP NZ,VDELAY - RET -; -; DELAY ABOUT 0.5 SECONDS = 25us * 20,000 -; -LDELAY: - PUSH DE - LD DE,20000 - CALL VDELAY - POP DE - RET -; -; MULTIPLY 8-BIT VALUES -; IN: MULTIPLY H BY E -; OUT: HL = RESULT, E = 0, B = 0 -; -MULT8: - LD D,0 - LD L,D - LD B,8 -MULT8_LOOP: - ADD HL,HL - JR NC,MULT8_NOADD - ADD HL,DE -MULT8_NOADD: - DJNZ MULT8_LOOP - RET - - -; -; SET A BIT IN BYTE ARRAY AT HL, INDEX IN A -; -BITSET: - CALL BITLOC ; LOCATE THE BIT - OR (HL) ; SET THE SPECIFIED BIT - LD (HL),A ; SAVE IT - RET ; RETURN -; -; CLEAR A BIT IN BYTE ARRAY AT HL, INDEX IN A -; -BITCLR: - CALL BITLOC ; LOCATE THE BIT - CPL ; INVERT ALL BITS - AND (HL) ; CLEAR SPECIFIED BIT - LD (HL),A ; SAVE IT - RET ; RETURN -; -; GET VALUE OF A BIT IN BYTE ARRAY AT HL, INDEX IN A -; -BITTST: - CALL BITLOC ; LOCATE THE BIT - AND (HL) ; SET Z FLAG BASED ON BIT - RET ; RETURN -; -; LOCATE A BIT IN BYTE ARRAY AT HL, INDEX IN A -; RETURN WITH HL POINTING TO BYTE AND A WITH MASK FOR SPECIFIC BIT -; -BITLOC: - PUSH AF ; SAVE BIT INDEX - SRL A ; DIVIDE BY 8 TO GET BYTE INDEX - SRL A ; " - SRL A ; " - LD C,A ; MOVE TO BC - LD B,0 ; " - ADD HL,BC ; HL NOW POINTS TO BYTE CONTAINING BIT - POP AF ; RECOVER A (INDEX) - AND $07 ; ISOLATE REMAINDER, Z SET IF ZERO - LD B,A ; SETUP SHIFT COUNTER - LD A,1 ; SETUP A WITH MASK - RET Z ; DONE IF ZERO -BITLOC1: - SLA A ; SHIFT - DJNZ BITLOC1 ; LOOP AS NEEDED - RET ; DONE -; -; PRINT VALUE OF HL IN DECIMAL WITH LEADING ZERO SUPPRESSION -; -PRTDEC: - LD E,'0' - LD BC,-10000 - CALL PRTDEC1 - LD BC,-1000 - CALL PRTDEC1 - LD BC,-100 - CALL PRTDEC1 - LD C,-10 - CALL PRTDEC1 - LD E,0 - LD C,-1 -PRTDEC1: - LD A,'0' - 1 -PRTDEC2: - INC A - ADD HL,BC - JR C,PRTDEC2 - SBC HL,BC - CP E - RET Z - LD E,0 - CALL COUT - RET -; -;================================================================================================== -; DSKY KEYBOARD ROUTINES -;================================================================================================== -; -#IF (DSKYENABLE) -; -; _____C0______C1______C2______C3__ -;B5 | $20 D $60 E $A0 F $E0 BO -;B4 | $10 A $50 B $90 C $D0 GO -;B3 | $08 7 $48 8 $88 9 $C8 EX -;B2 | $04 4 $44 5 $84 6 $C4 DE -;B1 | $02 1 $42 2 $82 3 $C2 EN -;B0 | $01 FW $41 0 $81 BK $C1 CL -; -KY_0 .EQU 000H -KY_1 .EQU 001H -KY_2 .EQU 002H -KY_3 .EQU 003H -KY_4 .EQU 004H -KY_5 .EQU 005H -KY_6 .EQU 006H -KY_7 .EQU 007H -KY_8 .EQU 008H -KY_9 .EQU 009H -KY_A .EQU 00AH -KY_B .EQU 00BH -KY_C .EQU 00CH -KY_D .EQU 00DH -KY_E .EQU 00EH -KY_F .EQU 00FH -KY_FW .EQU 010H ; FORWARD -KY_BK .EQU 011H ; BACKWARD -KY_CL .EQU 012H ; CLEAR -KY_EN .EQU 013H ; ENTER -KY_DE .EQU 014H ; DEPOSIT -KY_EX .EQU 015H ; EXAMINE -KY_GO .EQU 016H ; GO -KY_BO .EQU 017H ; BOOT -; -;__DSKY_INIT_________________________________________________________________________________________ -; -; CHECK FOR KEY PRESS, SAVE RAW VALUE, RETURN STATUS -;____________________________________________________________________________________________________ -; -DSKY_INIT: - LD A,82H - OUT (PPIX),A - LD A,30H ;disable /CS on PPISD card(s) - OUT (PPIC),A - XOR A - LD (KY_BUF),A - RET -#IFDEF DSKY_KBD -; -;__KY_STAT___________________________________________________________________________________________ -; -; CHECK FOR KEY PRESS, SAVE RAW VALUE, RETURN STATUS -;____________________________________________________________________________________________________ -; -KY_STAT: - ; IF WE ALREADY HAVE A KEY, RETURN WITH NZ - LD A,(KY_BUF) - OR A - RET NZ - ; SCAN FOR A KEYPRESS, A=0 NO DATA OR A=RAW BYTE - CALL KY_SCAN ; SCAN KB ONCE - OR A ; SET FLAGS - RET Z ; NOTHING FOUND, GET OUT - LD (KY_BUF),A ; SAVE RAW KEYCODE - RET ; RETURN -; -;__KY_GET____________________________________________________________________________________________ -; -; GET A SINGLE KEY (WAIT FOR ONE IF NECESSARY) -;____________________________________________________________________________________________________ -; -KY_GET: - ; SEE IF WE ALREADY HAVE A KEY SAVED, GO TO DECODE IF SO - LD A,(KY_BUF) - OR A - JR NZ,KY_DECODE - ; NO KEY SAVED, WAIT FOR ONE -KY_STATLOOP: - CALL KY_STAT - OR A - JR Z,KY_STATLOOP - ; DECODE THE RAW VALUE -KY_DECODE: - LD D,00H - LD HL,KY_KEYMAP ; POINT TO BEGINNING OF TABLE -KY_GET_LOOP: - CP (HL) ; MATCH? - JR Z,KY_GET_DONE ; FOUND, DONE - INC HL - INC D ; D + 1 - JR NZ,KY_GET_LOOP ; NOT FOUND, LOOP UNTIL EOT -KY_GET_DONE: - ; CLEAR OUT KEY_BUF - XOR A - LD (KY_BUF),A - ; RETURN THE INDEX POSITION WHERE THE RAW VALUE WAS FOUND - LD A,D - RET -; -;__KY_SCAN____________________________________________________________________________________________ -; -; SCAN KEYBOARD MATRIX FOR AN INPUT -;____________________________________________________________________________________________________ -; -KY_SCAN: - LD C,0000H - LD A,41H | 30H ; SCAN COL ONE - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL DELAY ; DEBOUNCE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KY_SCAN_FOUND ; YES, EXIT - - LD C,0040H - LD A,42H | 30H ; SCAN COL TWO - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL DELAY ; DEBOUNCE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KY_SCAN_FOUND ; YES, EXIT - - LD C,0080H - LD A,44H | 30H ; SCAN COL THREE - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL DELAY ; DEBOUNCE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KY_SCAN_FOUND ; YES, EXIT - - LD C,00C0H ; - LD A,48H | 30H ; SCAN COL FOUR - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL DELAY ; DEBOUNCE - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KY_SCAN_FOUND ; YES, EXIT - - LD A,040H | 30H ; TURN OFF ALL COLUMNS - OUT (PPIC),A ; SEND TO COLUMN LINES - LD A,00H ; RETURN NULL - RET ; EXIT - -KY_SCAN_FOUND: - AND 3FH ; CLEAR TOP TWO BITS - OR C ; ADD IN ROW BITS - LD C,A ; STORE VALUE - - ; WAIT FOR KEY TO BE RELEASED - LD A,4FH | 30H ; SCAN ALL COL LINES - OUT (PPIC),A ; SEND TO COLUMN LINES - CALL DELAY ; DEBOUNCE -KY_CLEAR_LOOP: ; WAIT FOR KEY TO CLEAR - IN A,(PPIB) ; GET ROWS - AND 7FH ;ignore PB7 for PPISD - CP 00H ; ANYTHING PRESSED? - JR NZ,KY_CLEAR_LOOP ; YES, LOOP UNTIL KEY RELEASED - - LD A,040H | 30H ; TURN OFF ALL COLUMNS - OUT (PPIC),A ; SEND TO COLUMN LINES - - LD A,C ; RESTORE VALUE - RET -; -;_KEYMAP_TABLE_____________________________________________________________________________________________________________ -; -KY_KEYMAP: -; 0 1 2 3 4 5 6 7 - .DB 041H,002H,042H,082H,004H,044H,084H,008H -; 8 9 A B C D E F - .DB 048H,088H,010H,050H,090H,020H,060H,0A0H -; FW BK CL EN DE EX GO BO - .DB 001H,081H,0C1H,0C2H,0C4H,0C8H,0D0H,0E0H -#ENDIF ; DSKY_KBD -; -;================================================================================================== -; DSKY HEX DISPLAY -;================================================================================================== -; -DSKY_HEXOUT: - LD B,DSKY_HEXBUFLEN - LD HL,DSKY_BUF - LD DE,DSKY_HEXBUF -DSKY_HEXOUT1: - LD A,(DE) ; FIRST NIBBLE - SRL A - SRL A - SRL A - SRL A - LD (HL),A - INC HL - LD A,(DE) ; SECOND NIBBLE - AND 0FH - LD (HL),A - INC HL - INC DE ; NEXT BYTE - DJNZ DSKY_HEXOUT1 - - LD A,82H ; SETUP PPI - OUT (PPIX),A - CALL DSKY_COFF - LD A,0D0H ; 7218 -> (DATA COMING, HEXA DECODE) - OUT (PPIA),A - CALL DSKY_STROBEC - - LD HL,DSKY_BUF ; POINT TO START OF BUF - LD B,DSKY_BUFLEN ; NUMBER OF DIGITS - LD C,PPIA -DSKY_HEXOUT2: - OUTI - JP Z,DSKY_STROBE ; DO FINAL STROBE AND RETURN - CALL DSKY_STROBE - JR DSKY_HEXOUT2 - -DSKY_STROBEC: - LD A,80H | 30H - JP DSKY_STROBE0 - -DSKY_STROBE: - LD A,00H | 30H ; SET WRITE STROBE - -DSKY_STROBE0: - OUT (PPIC),A ; OUT TO PORTC - CALL DELAY ; DELAY -DSKY_COFF - LD A,40H | 30H ; SET CONTROL PORT OFF - OUT (PPIC),A ; OUT TO PORTC - CALL DELAY ; WAIT - RET -#ENDIF -; -;================================================================================================== -; DATA -;================================================================================================== -; -STR_EMPTY .TEXT "$" -; -KY_BUF .DB 0 -DSKY_BUF: .FILL 8,0 -DSKY_BUFLEN .EQU $ - DSKY_BUF -DSKY_HEXBUF .FILL 4,0 -DSKY_HEXBUFLEN .EQU $ - DSKY_HEXBUF diff --git a/branches/s100/Source/vdu.asm b/branches/s100/Source/vdu.asm deleted file mode 100644 index ebd7aab7..00000000 --- a/branches/s100/Source/vdu.asm +++ /dev/null @@ -1,509 +0,0 @@ -;====================================================================== -; VDU DRIVER FOR N8VEM PROJECT -; -; ORIGINALLY WRITTEN BY: ANDREW LYNCH -; REVISED/ENHANCED BY DAN WERNER -- 11/7/2009 -; ROMWBW ADAPTATION BY: WAYNE WARTHEN -- 11/9/2012 -;====================================================================== -; -; TODO: -; - ADD REMAINING REGISTERS TO INIT -; - TRY 25 ROW MODE? -; - IMPLEMENT CONSTANTS FOR SCREEN DIMENSIONS -; - IMPLEMENT SET CURSOR STYLE (VDASCS) FUNCTION -; - IMPLEMENT ALTERNATE DISPLAY MODES? -; -;====================================================================== -; CVDU DRIVER - CONSTANTS -;====================================================================== -; -VDU_RAMRD .EQU 0F0h ; READ VDU -VDU_RAMWR .EQU 0F1h ; WRITE VDU -VDU_STAT .EQU 0F2h ; VDU STATUS/REGISTER -VDU_REG .EQU 0F2h ; VDU STATUS/REGISTER -VDU_DATA .EQU 0F3h ; VDU DATA REGISTER -; -;====================================================================== -; VDU DRIVER - INITIALIZATION -;====================================================================== -; -VDU_INIT: - PRTS("VDU: IO=0x$") - LD A,VDU_RAMRD - CALL PRTHEXBYTE -; - CALL VDU_CRTINIT ; INIT SY6845 VDU CHIP - -VDU_RESET: - LD DE,0 - LD (VDU_OFFSET),DE - CALL VDU_XY - LD A,' ' - LD DE,1024*16 - CALL VDU_FILL - XOR A - RET -; -;====================================================================== -; VDU DRIVER - CHARACTER I/O (CIO) DISPATCHER AND FUNCTIONS -;====================================================================== -; -VDU_DISPCIO: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - JR Z,VDU_CIOIN ; $00 - DEC A - JR Z,VDU_CIOOUT ; $01 - DEC A - JR Z,VDU_CIOIST ; $02 - DEC A - JR Z,VDU_CIOOST ; $03 - CALL PANIC -; -VDU_CIOIN: - JP PPK_READ ; CHAIN TO KEYBOARD DRIVER -; -VDU_CIOIST: - JP PPK_STAT ; CHAIN TO KEYBOARD DRIVER -; -VDU_CIOOUT: - JP VDU_VDAWRC ; WRITE CHARACTER -; -VDU_CIOOST: - XOR A ; A := 0 - INC A ; A := 1, SIGNAL OUTPUT BUFFER READY - RET -; -;====================================================================== -; VDU DRIVER - VIDEO DISPLAY ADAPTER (VDA) DISPATCHER AND FUNCTIONS -;====================================================================== -; -VDU_DISPVDA: - LD A,B ; GET REQUESTED FUNCTION - AND $0F ; ISOLATE SUB-FUNCTION - - JR Z,VDU_VDAINI ; $40 - DEC A - JR Z,VDU_VDAQRY ; $41 - DEC A - JR Z,VDU_VDARES ; $42 - DEC A - JR Z,VDU_VDASCS ; $43 - DEC A - JR Z,VDU_VDASCP ; $44 - DEC A - JR Z,VDU_VDASAT ; $45 - DEC A - JR Z,VDU_VDASCO ; $46 - DEC A - JR Z,VDU_VDAWRC ; $47 - DEC A - JR Z,VDU_VDAFIL ; $48 - DEC A - JR Z,VDU_VDACPY ; $49 - DEC A - JR Z,VDU_VDASCR ; $4A - DEC A - JP Z,PPK_STAT ; $4B - DEC A - JP Z,PPK_FLUSH ; $4C - DEC A - JP Z,PPK_READ ; $4D - CALL PANIC - -VDU_VDAINI: - JR VDU_INIT ; INITIALIZE - -VDU_VDAQRY: - LD C,$00 ; MODE ZERO IS ALL WE KNOW - LD DE,$1850 ; 24 ROWS ($18), 80 COLS ($50) - LD HL,0 ; EXTRACTION OF CURRENT BITMAP DATA NOT SUPPORTED - XOR A ; SIGNAL SUCCESS - RET - -VDU_VDARES: - JR VDU_RESET ; DO THE RESET - -VDU_VDASCS: - CALL PANIC ; NOT IMPLEMENTED (YET) - -VDU_VDASCP: - CALL VDU_XY - XOR A - RET - -VDU_VDASAT: - XOR A - RET - -VDU_VDASCO: - XOR A - RET - -VDU_VDAWRC: - LD A,E - CALL VDU_PUTCHAR - XOR A - RET - -VDU_VDAFIL: - LD A,E ; FILL CHARACTER GOES IN A - EX DE,HL ; FILL LENGTH GOES IN DE - CALL VDU_FILL ; DO THE FILL - XOR A ; SIGNAL SUCCESS - RET - -VDU_VDACPY: - ; LENGTH IN HL, SOURCE ROW/COL IN DE, DEST IS CVDU_POS - PUSH HL ; SAVE LENGTH - CALL VDU_XY2IDX ; ROW/COL IN DE -> SOURCE ADR IN HL - POP BC ; RECOVER LENGTH IN BC - LD DE,(VDU_POS) ; PUT DEST IN DE - JP VDU_BLKCPY ; DO A BLOCK COPY - - RET - -VDU_VDASCR: - LD A,E ; LOAD E INTO A - OR A ; SET FLAGS - RET Z ; IF ZERO, WE ARE DONE - PUSH DE ; SAVE E - JP M,VDU_VDASCR1 ; E IS NEGATIVE, REVERSE SCROLL - CALL VDU_SCROLL ; SCROLL FORWARD ONE LINE - POP DE ; RECOVER E - DEC E ; DECREMENT IT - JR VDU_VDASCR ; LOOP -VDU_VDASCR1: - CALL VDU_RSCROLL ; SCROLL REVERSE ONE LINE - POP DE ; RECOVER E - INC E ; INCREMENT IT - JR VDU_VDASCR ; LOOP -; -;====================================================================== -; CVDU DRIVER - PRIVATE DRIVER FUNCTIONS -;====================================================================== -; -;---------------------------------------------------------------------- -; WAIT FOR VDU TO BE READY FOR A DATA READ/WRITE -;---------------------------------------------------------------------- -; -VDU_WAITRDY: - IN A,(VDU_STAT) ; READ STATUS - OR A ; SET FLAGS - RET M ; IF BIT 7 SET, THEN READY! - JR VDU_WAITRDY ; KEEP CHECKING -; -;---------------------------------------------------------------------- -; UPDATE SY6845 REGISTERS -; VDU_WRREG WRITES VALUE IN A TO VDU REGISTER SPECIFIED IN C -; VDU_WRREGX WRITES VALUE IN DE TO VDU REGISTER PAIR IN C, C+1 -;---------------------------------------------------------------------- -; -VDU_WRREG: - PUSH AF ; SAVE VALUE TO WRITE - LD A,C ; SET A TO CVDU REGISTER TO SELECT - OUT (VDU_REG),A ; WRITE IT TO SELECT THE REGISTER - POP AF ; RECOVER VALUE TO WRITE - OUT (VDU_DATA),A ; WRITE IT - RET -; -VDU_WRREGX: - LD A,H ; SETUP MSB TO WRITE - CALL VDU_WRREG ; DO IT - INC C ; NEXT CVDU REGISTER - LD A,L ; SETUP LSB TO WRITE - JR VDU_WRREG ; DO IT & RETURN -; -;---------------------------------------------------------------------- -; READ SY6845 REGISTERS -; VDU_RDREG READS VDU REGISTER SPECIFIED IN C AND RETURNS VALUE IN A -; VDU_RDREGX READS VDU REGISTER PAIR SPECIFIED BY C, C+1 -; AND RETURNS VALUE IN HL -;---------------------------------------------------------------------- -; -VDU_RDREG: - LD A,C ; SET A TO CVDU REGISTER TO SELECT - OUT (VDU_REG),A ; WRITE IT TO SELECT THE REGISTER - IN A,(VDU_DATA) ; READ IT - RET -; -VDU_RDREGX: - CALL VDU_RDREG ; GET VALUE FROM REGISTER IN C - LD H,A ; SAVE IN H - INC C ; BUMP TO NEXT REGISTER OF PAIR - CALL VDU_RDREG ; READ THE VALUE - LD L,A ; SAVE IT IN L - RET -; -;---------------------------------------------------------------------- -; SY6845 DISPLAY CONTROLLER CHIP INITIALIZATION -;---------------------------------------------------------------------- -; -VDU_CRTINIT: - LD C,0 ; START WITH REGISTER 0 - LD B,16 ; INIT 16 REGISTERS - LD HL,VDU_INIT6845 ; HL = POINTER TO THE DEFAULT VALUES -VDU_CRTINIT1: - LD A,(HL) ; GET VALUE - CALL VDU_WRREG ; WRITE IT - INC HL ; POINT TO NEXT VALUE - INC C ; POINT TO NEXT REGISTER - DJNZ VDU_CRTINIT1 ; LOOP - RET -; -;---------------------------------------------------------------------- -; CONVERT XY COORDINATES IN DE INTO LINEAR INDEX IN HL -; D=ROW, E=COL -;---------------------------------------------------------------------- -; -VDU_XY2IDX: - LD A,E ; SAVE COLUMN NUMBER IN A - LD H,D ; SET H TO ROW NUMBER - LD E,80 ; SET E TO ROW LENGTH - CALL MULT8 ; MULTIPLY TO GET ROW OFFSET - LD E,A ; GET COLUMN BACK - ADD HL,DE ; ADD IT IN - RET ; RETURN -; -;---------------------------------------------------------------------- -; SET CURSOR POSITION TO ROW IN D AND COLUMN IN E -;---------------------------------------------------------------------- -; -VDU_XY: - LD A,E ; SAVE COLUMN NUMBER IN A - LD H,D ; SET H TO ROW NUMBER - LD E,80 ; SET E TO ROW LENGTH - CALL MULT8 ; MULTIPLY TO GET ROW OFFSET - LD E,A ; GET COLUMN BACK - ADD HL,DE ; ADD IT IN - LD (VDU_POS),HL ; SAVE THE RESULT (DISPLAY POSITION) - LD DE,(VDU_OFFSET) ; NOW GET THE BUFFER OFFSET - ADD HL,DE ; AND ADD THAT IN - LD C,14 ; CURSOR POSITION REGISTER PAIR - JP VDU_WRREGX ; DO IT AND RETURN -; -;---------------------------------------------------------------------- -; WRITE VALULE IN A TO CURRENT VDU BUFFER POSTION, ADVANCE CURSOR -;---------------------------------------------------------------------- -; -VDU_PUTCHAR: - LD B,A ; SAVE THE CHARACTER - - ; SET BUFFER WRITE POSITION - LD HL,(VDU_OFFSET) - LD DE,(VDU_POS) - ADD HL,DE - INC DE ; INC - LD (VDU_POS),DE ; SAVE NEW SCREEN POSITION - LD C,18 ; UPDATE ADDRESS REGISTER PAIR - CALL VDU_WRREGX ; DO IT - INC HL ; NEW CURSOR POSITION - LD C,14 ; CURSOR POSITION REGISTER PAIR - CALL VDU_WRREGX ; DO IT - - LD A,31 ; PREP VDU FOR DATA R/W - OUT (VDU_REG),A - CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY - LD A,B - OUT (VDU_RAMWR),A ; OUTPUT CHAR TO VDU - - RET -; -;---------------------------------------------------------------------- -; FILL AREA IN BUFFER WITH SPECIFIED CHARACTER AND CURRENT COLOR/ATTRIBUTE -; STARTING AT THE CURRENT FRAME BUFFER POSITION -; A: FILL CHARACTER -; DE: NUMBER OF CHARACTERS TO FILL -;---------------------------------------------------------------------- -; -VDU_FILL: - LD B,A ; SAVE THE FILL CHARACTER - - ; SET FILL START POSITION - PUSH DE - LD HL,(VDU_OFFSET) - LD DE,(VDU_POS) - ADD HL,DE - LD C,18 - CALL VDU_WRREGX - POP DE - - ; FILL LOOP - LD A,31 ; PREP VDU FOR DATA R/W - OUT (VDU_REG),A -VDU_FILL1: - LD A,D ; CHECK NUMBER OF FILL CHARS LEFT - OR E - RET Z ; ALL DONE, RETURN - CALL VDU_WAITRDY ; WAIT FOR VDU TO BE READY - LD A,B - OUT (VDU_RAMWR),A ; OUTPUT CHAR TO VDU - DEC DE ; DECREMENT COUNT - JR VDU_FILL1 ; LOOP -; -;---------------------------------------------------------------------- -; COPY A BLOCK (UP TO 255 BYTES) FROM HL TO FRAME BUFFER POSITION -; BC: NUMBER OF BYTES TO COPY -; HL: SOURCE POSITION -; DE: DESTINATION POSITION -;---------------------------------------------------------------------- -; -VDU_BLKCPY: - ; SETUP TO COPY FROM VDU SOURCE TO WORK BUFFER - PUSH DE ; SAVE VDU DESTINATION ADR - PUSH HL ; SAVE VDU SOURCE ADDRESS - LD HL,(VDU_OFFSET) ; GET THE CURRENT OFFSET - POP DE ; RECOVER SOURCE ADDRESS - ADD HL,DE ; HL HAS TRUE SOURCE ADR OF VIDEO BUF W/ OFFSET - LD DE,VDU_BUF ; POINT DE TO WORK BUFFER - PUSH BC ; SAVE COPY LENGTH FOR LATER - LD B,C ; NOW USE B FOR LENGTH (MAX COPY IS 255) - LD C,18 ; SET SOURCE ADDRESS IN VDU (HL) - CALL VDU_WRREGX ; DO IT - LD A,31 ; PREP VDU FOR DATA R/W - OUT (VDU_REG),A ; DO IT - LD HL,VDU_BUF ; HL POINTS TO WORK BUFFER -; LD C,VDU_RAMWR ; LOAD C WITH VDU WRITE REGISTER - -VDU_BLKCPY1: ; VIDEO RAM -> BUFFER COPY LOOP - CALL VDU_WAITRDY ; WAIT FOR VDU -;;;;;;;;;;;;;;;;; -; INI IS NOT WORKING FOR ME, GARBAGE DATA READS, NO IDEA WHY -; INI ; READ BYTE, DEC B, INC HL -; IN A,(VDU_DATA) ; BOGUS READ TO INCREMENT VDU RAM ADDRESS!!! -; JR NZ,VDU_BLKCPY1 ; LOOP TILL DONE -;;;;;;;;;;;;;;;;; - IN A,(VDU_RAMRD) ; READ DATA BYTE - LD (HL),A ; SAVE IN BUFFER - INC HL ; BUMP SOURCE ADDRESS - IN A,(VDU_DATA) ; BOGUS READ TO INCREMENT VDU RAM ADDRESS!!! - DJNZ VDU_BLKCPY1 ; LOOP TILL DONE - - ; SETUP TO COPY FROM WORK BUFFER TO VDU DEST - POP BC ; RECOVER THE COPY LENGTH - LD HL,(VDU_OFFSET) ; GET THE CURRENT VDU OFFSET - POP DE ; RECOVER THE DEST ADDRESS - ADD HL,DE ; HL HAS TRUE DEST ADR OF VIDEO BUF W/ OFFSET - LD B,C ; NOW USE B FOR LENGTH (MAX COPY IS 255) - LD C,18 ; SET DEST ADDRESS IN VDU (HL) - CALL VDU_WRREGX ; DO IT - LD A,31 ; PREP VDU FOR DATA R/W - OUT (VDU_REG),A ; DO IT - LD HL,VDU_BUF ; HL POINTS TO WORK BUFFER - LD C,VDU_RAMWR ; LOAD C WITH VDU WRITE REGISTER - -VDU_BLKCPY2: ; BUFFER -> VIDEO RAM COPY LOOP - CALL VDU_WAITRDY ; WAIT FOR VDU - OUTI ; WRITE BYTE, DEC B, INC HL - JR NZ,VDU_BLKCPY2 ; LOOP TILL DONE -; - RET ; RETURN -; -;---------------------------------------------------------------------- -; SCROLL ENTIRE SCREEN FORWARD BY ONE LINE (CURSOR POSITION UNCHANGED) -;---------------------------------------------------------------------- -; -VDU_SCROLL: - ; SCROLL FORWARD BY ADDING ONE ROW TO DISPLAY START ADDRESS - LD HL,(VDU_OFFSET) - LD DE,80 - ADD HL,DE - LD (VDU_OFFSET),HL - LD C,12 - CALL VDU_WRREGX - - ; FILL EXPOSED LINE - LD HL,(VDU_POS) - PUSH HL - LD HL,23*80 - LD (VDU_POS),HL - LD DE,80 - LD A,' ' - CALL VDU_FILL - POP HL - LD (VDU_POS),HL - - ; ADJUST CURSOR POSITION AND RETURN - LD HL,(VDU_OFFSET) - LD DE,(VDU_POS) - ADD HL,DE - LD C,14 - JP VDU_WRREGX -; -;---------------------------------------------------------------------- -; REVERSE SCROLL ENTIRE SCREEN BY ONE LINE (CURSOR POSITION UNCHANGED) -;---------------------------------------------------------------------- -; -VDU_RSCROLL: - ; SCROLL BACKWARD BY SUBTRACTING ONE ROW FROM DISPLAY START ADDRESS - LD HL,(VDU_OFFSET) - LD DE,-80 - ADD HL,DE - LD (VDU_OFFSET),HL - LD C,12 - CALL VDU_WRREGX - - ; FILL EXPOSED LINE - LD HL,(VDU_POS) - PUSH HL - LD HL,0 - LD (VDU_POS),HL - LD DE,80 - LD A,' ' - CALL VDU_FILL - POP HL - LD (VDU_POS),HL - - ; ADJUST CURSOR POSITION AND RETURN - LD HL,(VDU_OFFSET) - LD DE,(VDU_POS) - ADD HL,DE - LD C,14 - JP VDU_WRREGX -; -;================================================================================================== -; VDU DRIVER - DATA -;================================================================================================== -; -VDU_POS .DW 0 ; CURRENT DISPLAY POSITION -VDU_OFFSET .DW 0 ; CURRENT DISPLAY POSITION -VDU_BUF .FILL 256,0 ; COPY BUFFER -; -;================================================================================================== -; VDU DRIVER - SY6845 REGISTER INITIALIZATION -;================================================================================================== -; -VDU_INIT6845: -; DB 07FH, 50H, 60H, 7CH, 19H, 1FH, 19H, 1AH, 78H, 09H, 60H, 09H, 00H, 00H, 00H, 00H -; - ; CCIR 625/50 VERSION (USED IN MOST OF THE WORLD) - ; JUMPER K1 2-3, K2 1-2 FOR 2MHz CHAR CLOCK - .DB 07FH ; R0 TOTAL NUMBER OF HORIZONTAL CHARACTERS (DETERMINES HSYNC) - .DB 050H ; R1 NUMBER OF HORIZONTAL CHARACTERS DISPLAYED (80 COLUMNS) - .DB 060H ; R2 HORIZONTAL SYNC POSITION - .DB 00CH ; R3 SYNC WIDTHS - .DB 01EH ; R4 VERTICAL TOTAL (TOTAL CHARS IN A FRAME -1) - .DB 002H ; R5 VERTICAL TOTAL ADJUST ( - .DB 018H ; R6 VERTICAL DISPLAYED (24 ROWS) - .DB 01AH ; R7 VERTICAL SYNC - .DB 078H ; R8 MODE B7=0 TRANSPARENT UPDATE DURING BLANKING - ; B6=1 PIN 34 IS UPDATE STROBE - ; B5=1 DELAY CURSOR 1 CHARACTER - ; B4=1 DELAY DISPLAY ENABLE 1 CHARACTER - ; B3=1 TRANSPARENT MEMORY ADDRESSING - ; B2=0 RAM STRAIGHT BINARY ADDRESSING - ; B1,B0=0 NON-INTERLACE - .DB 009H ; R9 SCAN LINE (LINES PER CHAR AND SPACING -1) - .DB 060H ; R10 CURSOR START RASTER - .DB 009H ; R11 CURSOR END RASTER - .DB 00H ; R12 START ADDRESS HI - .DB 00H ; R13 START ADDRESS LO - .DB 00H ; R14 CURSOR ADDRESS HI - .DB 00H ; R15 CURSOR ADDRESS LO -; -; THE CCIR 625/50 TELEVISION STANDARD HAS 625 LINES INTERLACED AT 50 FIELDS PER SECOND. THIS WORKS -; OUT AS 50 FIELDS OF 312.5 LINES PER SECOND NON-INTERLACED AS USED HERE. -; HORIZONTAL LINE WIDTH IS 64uS. FOR A 2 MHz CHARACTER CLOCK (R0+1)/2000000 = 64uS -; NEAREST NUMBER OF LINES IS 312 = (R4+1) * (R9+1) + R5. -; 15625 / 312 = 50.08 FIELDS PER SECOND (NEAR ENOUGH-DGG) -; diff --git a/branches/s100/Source/ver.inc b/branches/s100/Source/ver.inc deleted file mode 100644 index 0d281b7e..00000000 --- a/branches/s100/Source/ver.inc +++ /dev/null @@ -1,6 +0,0 @@ -#DEFINE RMJ 2 -#DEFINE RMN 5 -#DEFINE RUP 0 -#DEFINE RTP 1 -#DEFINE BIOSVER "2.5 - Prerelease" -#DEFINE REVISION 248 diff --git a/branches/s100/Source/xio.asm b/branches/s100/Source/xio.asm deleted file mode 100644 index 2777e678..00000000 --- a/branches/s100/Source/xio.asm +++ /dev/null @@ -1,76 +0,0 @@ -;___XIO________________________________________________________________________________________________________________ -; -; DIRECT SERIAL I/O -; -; PROVIDES INTERFACE TO PLATFORM BASE SERIAL I/O DEVICE -; ALLOWS USER MESSAGING/INTERACTION PRIOR TO AND DURING HBIOS INIT -;______________________________________________________________________________________________________________________ -; -XIO_INIT: ; MINIMAL UART INIT -#IF (PLATFORM == PLT_N8) - ; ASCI0 - LD A,66H - OUT0 (CPU_ASEXT0),A - LD A,64H - OUT0 (CPU_CNTLA0),A - LD A,Z180_CNTLB0 - OUT0 (CPU_CNTLB0),A - RET -#ELSE -XIO_DIV .EQU (1843200 / (16 * BAUDRATE)) - - LD A,$80 ; LCR := DLAB ON - OUT (SIO_LCR),A ; SET LCR - LD A,XIO_DIV ; BAUD RATE DIVISOR (LSB) - OUT (SIO_DLL),A ; SET DIVISOR (LSB) - XOR A ; BAUD RATE DIVISOR (MSB), ALWAYS 0 - OUT (SIO_DLM),A ; SET DIVISOR (MSB) - LD A,03H ; VALUE FOR LCR AND MCR - OUT (SIO_LCR),A ; LCR := 3, DLAB OFF, 8 DATA, 1 STOP, NO PARITY - OUT (SIO_MCR),A ; MCR := 3, DTR ON, RTS ON - LD A,6 ; DISABLE & RESET FIFO'S - OUT (SIO_FCR),A ; DO IT - RET -#ENDIF -; -XIO_CRLF: ; OUTPUT A NEWLINE - LD A,13 ; A = CR - CALL XIO_OUTC ; WRITE IT - LD A,10 ; A = LF - JR XIO_OUTC ; WRITE IT -; -XIO_SPACE: ; OUTPUT A SPACE CHARACTER - LD A,' ' - JR XIO_OUTC -; -XIO_DOT: ; OUTPUT A DOT (MARK PROGRESS) - LD A,'.' -; -XIO_OUTC: ; OUTPUT BYTE IN A -#IF (PLATFORM == PLT_N8) - PUSH AF ; SAVE INCOMING BYTE -XIO_OUTC1: - IN0 A,(CPU_STAT0) - AND $02 - JR Z,XIO_OUTC1 - POP AF - OUT0 (CPU_TDR0),A - RET -#ELSE - PUSH AF ; SAVE INCOMING BYTE -XIO_OUTC1: - IN A,(SIO_LSR) ; READ LINE STATUS REGISTER - AND $20 ; ISOLATE THRE - JR Z,XIO_OUTC1 ; LOOP TILL READY (EMPTY) - POP AF ; RECOVER BYTE TO WRITE - OUT (SIO_THR),A ; WRITE THE CHAR TO UART - RET -#ENDIF -; -XIO_OUTS: ; OUTPUT '$' TERMINATED STRING AT ADDRESS IN HL - LD A,(HL) ; GET NEXT BYTE - CP '$' ; END OF STRING? - RET Z ; YES, GET OUT - CALL XIO_OUTC ; OTHERWISE, WRITE IT - INC HL ; POINT TO NEXT BYTE - JR XIO_OUTS ; AND LOOP diff --git a/branches/s100/Source/zcpr.asm b/branches/s100/Source/zcpr.asm deleted file mode 100644 index bf989674..00000000 --- a/branches/s100/Source/zcpr.asm +++ /dev/null @@ -1,2050 +0,0 @@ -; WW - TASM adaptation (requires wrapper!) -; WW - Globally replaced squote -> dquote for all strings -; WW - Globally updated conditional expressions to use TASM operators -; WW - Commented out all of the Z80 macros (see wrapper) -; - TITLE "ZCPR Version 1.0" -; -; CP/M Z80 Command Processor Replacement (CPR) Version 1.0 -; CCPZ CREATED AND CUSTOMIZED FOR ARIES-II BY RLC -; FURTHER MODIFIED BY RGF AS V2.0 -; FURTHER MODIFIED BY RLC AS V2.1 -; FURTHER MODIFIED BY KBP AS V2.2 -; FURTHER MODIFIED BY RLC AS V2.4 (V2.3 skipped) -; FURTHER MODIFIED BY RLC AS V2.5 -; FURTHER MODIFIED BY RLC AS V2.6 -; FURTHUR MODIFIED BY SBB AS V2.7 -; FURTHER MODIFIED BY RLC AS V2.8 -; FURTHER MODIFIED BY RLC AS V2.9 -; FURTHER MODIFIED BY RLC AS V3.0 -; FURTHER MODIFIED BY RLC AS V3.1 -; FURTHER MODIFIED BY RLC AS V4.0 -; ZCPR VERSION 1.0 CREATED FROM CCPZ VERSION 4.0 BY RLC IN -; A COORDINATED EFFORT WITH CCP-GROUP -; -; ZCPR is a group effort by CCP-GROUP, whose active membership involved -; in this project consists of the following: -; RLC - Richard Conn -; RGF - Ron Fowler -; KBP - Keith Peterson -; FJW - Frank Wancho -; The following individual also provided a contribution: -; SBB - Steve Bogolub -; -; -;******** Structure Notes ******** -; -; This CPR is divided into a number of major sections. The following -; is an outline of these sections and the names of the major routines -; located therein. -; -; Section Function/Routines -; ------- ----------------- -; -; -- Opening Comments, Equates, and Macro Definitions -; -; 0 JMP Table into CPR -; -; 1 Buffers -; -; 2 CPR Starting Modules -; CPR1 CPR RESTRT RSTCPR RCPRNL -; PRNNF -; -; 3 Utilities -; CRLF CONOUT CONIN LCOUT LSTOUT -; READF READ BDOSB PRINTC PRINT -; GETDRV DEFDMA DMASET RESET BDOSJP -; LOGIN OPENF OPEN GRBDOS CLOSE -; SEARF SEAR1 SEARN SUBKIL DELETE -; RESETUSR GETUSR SETUSR -; -; 4 CPR Utilities -; SETUD SETU0D UCASE REDBUF CNVBUF -; BREAK USRNUM ERROR SDELM ADVAN -; SBLANK ADDAH NUMBER NUMERR HEXNUM -; DIRPTR SLOGIN DLOGIN COMLOG SCANER -; CMDSER -; -; 5 CPR-Resident Commands and Functions -; 5A DIR DIRPR FILLQ -; 5B ERA -; 5C LIST -; 5D TYPE PAGER -; 5E SAVE -; 5F REN -; 5G USER -; 5H DFU -; 5I JUMP -; 5J GO -; 5K COM CALLPROG ERRLOG ERRJMP -; 5L GET MEMLOAD PRNLE -; -; -FALSE EQU 0 -TRUE EQU ~FALSE -; -; CUSTOMIZATION EQUATES -; -; The following equates may be used to customize this CPR for the user's -; system and integration technique. The following constants are provided: -; -; REL - TRUE if integration is to be done via MOVCPM -; - FALSE if integration is to be done via DDT and SYSGEN -; -; BASE - Base Address of user's CP/M system (normally 0 for DR version) -; This equate allows easy modification by non-standard CP/M (eg,H89) -; -; CPRLOC - Base Page Address of CPR; this value can be obtained by running -; the BDOSLOC program on your system, or by setting the -; MSIZE and BIOSEX equates to the system memory size in -; K-bytes and the "extra" memory required by your BIOS -; in K-bytes. BIOSEX is zero if your BIOS is normal size, -; and can be negative if your BIOS is in PROM or in -; non-contiguous memory. -; -; RAS - Remote-Access System; setting this equate to TRUE disables -; certain CPR commands that are considered harmful in a Remote- -; Access environment; use under Remote-Access Systems (RBBS) for -; security purposes -; -REL EQU FALSE ;SET TO TRUE FOR MOVCPM INTEGRATION -; -BASE EQU 0 ;BASE OF CP/M SYSTEM (SET FOR STANDARD CP/M) -; - IF REL -CPRLOC EQU 0 ;MOVCPM IMAGE - ELSE -; -; If REL is FALSE, the value of CPRLOC may be set in one -; of two ways. The first way is to set MSIZE and BIOSEX -; as described above using the following three lines: -; -;MSIZE EQU 56 ;SIZE OF MEM IN K-BYTES -;BIOSEX EQU 0 ;EXTRA # K-BYTES IN BIOS -;CPRLOC EQU 3400H+(MSIZE-20-BIOSEX)*1024 ;CPR ORIGIN -; -; The second way is to obtain the origin of your current -; CPR using BDSLOC or its equivalent, then merely set CPRLOC -; to that value as as in the following line: -; -CPRLOC EQU 0D000H ;FILL IN WITH BDOSLOC SUPPLIED VALUE -; -; Note that you should only use one method or the other. -; Do NOT define CPRLOC twice! -; -; The following gives the required offset to load the CPR into the -; CP/M SYSGEN Image through DDT (the Roffset command); Note that this -; value conforms with the standard value presented in the CP/M reference -; manuals, but it may not necessarily conform with the location of the -; CPR in YOUR CP/M system; several systems (Morrow Designs, P&T, Heath -; Org-0 to name a few) have the CPR located at a non-standard address in -; the SYSGEN Image -; -;CPRR EQU 0980H-CPRLOC ;DDT LOAD OFFSET -CPRR EQU 1100H-CPRLOC ;DDT LOAD OFFSET FOR MORROW DESIGNS - ENDIF -; -RAS EQU FALSE ;SET TO TRUE IF CPR IS FOR A REMOTE-ACCESS SYSTEM -; -; The following is presented as an option, but is not generally user-customiz- -; able. A basic design choice had to be made in the design of ZCPR concerning -; the execution of SUBMIT files. The original CCP had a problem in this sense -; in that it ALWAYS looked for the SUBMIT file from drive A: and the SUBMIT -; program itself (SUBMIT.COM) would place the $$$.SUB file on the currently -; logged-in drive, so when the user was logged into B: and he issued a SUBMIT -; command, the $$$.SUB was placed on B: and did not execute because the CCP -; looked for it on A: and never found it. -; After much debate it was decided to have ZCPR perform the same type of -; function as CCP (look for the $$$.SUB file on A:), but the problem with -; SUBMIT.COM still exists. Hence, RGF designed SuperSUB and RLC took his -; SuperSUB and designed SUB from it; both programs are set up to allow the -; selection at assembly time of creating the $$$.SUB on the logged-in drive -; or on drive A:. -; A final definition of the Indirect Command File ($$$.SUB or SUBMIT -; File) is presented as follows: -; "An Indirect Command File is one which contains -; a series of commands exactly as they would be -; entered from a CP/M Console. The SUBMIT Command -; (or SUB Command) reads this files and transforms -; it for processing by the ZCPR (the $$$.SUB File). -; ZCPR will then execute the commands indicated -; EXACTLY as if they were typed at the Console." -; Hence, to permit this to happen, the $$$.SUB file must always -; be present on a specific drive, and A: is the choice for said drive. -; With this facility engaged as such, Indirect Command Files like: -; DIR -; A: -; DIR -; can be executed, even though the currently logged-in drive is changed -; during execution. If the $$$.SUB file was present on the currently -; logged-in drive, the above series of commands would not work since the -; ZCPR would be looking for $$$.SUB on the logged-in drive, and switching -; logged-in drives without moving the $$$.SUB file as well would cause -; processing to abort. -; -SUBA equ TRUE ; Set to TRUE to have $$$.SUB always on A: - ; Set to FALSE to have $$$.SUB on the logged-in drive -; -; The following flag enables extended processing for user-program supplied -; command lines. This is for Command Level 3 of ZCPR. Under the CCPZ Version -; 4.0 philosophy, three command levels exist: -; (1) that command issued by the user from his console at the '>' prompt -; (2) that command issued by a $$$.SUB file at the '$' prompt -; (3) that command issued by a user program by placing the command into -; CIBUFF and setting the character count in CBUFF -; Setting CLEVEL3 to TRUE enables extended processing of the third level of -; ZCPR command. All the user program need do is to store the command line and -; set the character count; ZCPR will initialize the pointers properly, store -; the ending zero properly, and capitalize the command line for processing. -; Once the command line is properly stored, the user executes the command line -; by reentering the ZCPR through CPRLOC [NOTE: The C register MUST contain -; a valid User/Disk Flag (see location 4) at this time.] -; -CLEVEL3 equ TRUE ;ENABLE COMMAND LEVEL 3 PROCESSING -; -; -;*** TERMINAL AND 'TYPE' CUSTOMIZATION EQUATES -; -NLINES EQU 24 ;NUMBER OF LINES ON CRT SCREEN -WIDE EQU TRUE ;TRUE IF WIDE DIR DISPLAY -FENCE EQU '|' ;SEP CHAR BETWEEN DIR FILES -; -PGDFLT EQU TRUE ;SET TO FALSE TO DISABLE PAGING BY DEFAULT -PGDFLG EQU 'P' ;FOR TYPE COMMAND: PAGE OR NOT (DEP ON PGDFLT) - ; THIS FLAG REVERSES THE DEFAULT EFFECT -; -MAXUSR EQU 15 ;MAXIMUM USER NUMBER ACCESSABLE -; -SYSFLG EQU 'A' ;FOR DIR COMMAND: LIST $SYS AND $DIR -; -SOFLG EQU 'S' ;FOR DIR COMMAND: LIST $SYS FILES ONLY -; -SUPRES EQU TRUE ;SUPRESSES USER # REPORT FOR USER 0 -; -DEFUSR EQU 0 ;DEFAULT USER NUMBER FOR COM FILES -; -SPRMPT EQU '$' ;CPR PROMPT INDICATING SUBMIT COMMAND -CPRMPT EQU '>' ;CPR PROMPT INDICATING USER COMMAND -; -NUMBASE EQU 'H' ;CHARACTER USED TO SWITCH FROM DEFAULT - ; NUMBER BASE -; -SECTFLG EQU 'S' ;OPTION CHAR FOR SAVE COMMAND TO SAVE SECTORS -; -; END OF CUSTOMIZATION SECTION -; -CR EQU 0DH -LF EQU 0AH -TAB EQU 09H -; -WBOOT EQU BASE+0000H ;CP/M WARM BOOT ADDRESS -UDFLAG EQU BASE+0004H ;USER NUM IN HIGH NYBBLE, DISK IN LOW -BDOS EQU BASE+0005H ;BDOS FUNCTION CALL ENTRY PT -TFCB EQU BASE+005CH ;DEFAULT FCB BUFFER -TBUFF EQU BASE+0080H ;DEFAULT DISK I/O BUFFER -TPA EQU BASE+0100H ;BASE OF TPA -; -; WW - MOVED MACROS BELOW TO ADDINSTR'S IN WRAPPER -; -;; -;; -;; MACROS TO PROVIDE Z80 EXTENSIONS -;; MACROS INCLUDE: -;; -;$-MACRO ;FIRST TURN OFF THE EXPANSIONS -;; -;; JR - JUMP RELATIVE -;; JRC - JUMP RELATIVE IF CARRY -;; JRNC - JUMP RELATIVE IF NO CARRY -;; JRZ - JUMP RELATIVE IF ZERO -;; JRNZ - JUMP RELATIVE IF NO ZERO -;; DJNZ - DECREMENT B AND JUMP RELATIVE IF NO ZERO -;; LDIR - MOV @HL TO @DE FOR COUNT IN BC -;; LXXD - LOAD DOUBLE REG DIRECT -;; SXXD - STORE DOUBLE REG DIRECT -;; -;; -;; -;; @GENDD MACRO USED FOR CHECKING AND GENERATING -;; 8-BIT JUMP RELATIVE DISPLACEMENTS -;; -;@GENDD MACRO ?DD ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS -; IF (?DD GT 7FH) AND (?DD LT 0FF80H) -; DB 100H ;Displacement Range Error on Jump Relative -; ELSE -; DB ?DD -; ENDIF -; ENDM -;; -;; -;; Z80 MACRO EXTENSIONS -;; -;JR MACRO ?N ;;JUMP RELATIVE -; DB 18H -; @GENDD ?N-$-1 -; ENDM -;; -;JRC MACRO ?N ;;JUMP RELATIVE ON CARRY -; DB 38H -; @GENDD ?N-$-1 -; ENDM -;; -;JRNC MACRO ?N ;;JUMP RELATIVE ON NO CARRY -; DB 30H -; @GENDD ?N-$-1 -; ENDM -;; -;JRZ MACRO ?N ;;JUMP RELATIVE ON ZERO -; DB 28H -; @GENDD ?N-$-1 -; ENDM -;; -;JRNZ MACRO ?N ;;JUMP RELATIVE ON NO ZERO -; DB 20H -; @GENDD ?N-$-1 -; ENDM -;; -;DJNZ MACRO ?N ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO -; DB 10H -; @GENDD ?N-$-1 -; ENDM -;; -;LDIR MACRO ;;LDIR -; DB 0EDH,0B0H -; ENDM -;; -;LDED MACRO ?N ;;LOAD DE DIRECT -; DB 0EDH,05BH -; DW ?N -; ENDM -;; -;LBCD MACRO ?N ;;LOAD BC DIRECT -; DB 0EDH,4BH -; DW ?N -; ENDM -;; -;SDED MACRO ?N ;;STORE DE DIRECT -; DB 0EDH,53H -; DW ?N -; ENDM -;; -;SBCD MACRO ?N ;;STORE BC DIRECT -; DB 0EDH,43H -; DW ?N -; ENDM -;; -;; END OF Z80 MACRO EXTENSIONS -; -; -;**** Section 0 **** -; - ORG CPRLOC -; -; ENTRY POINTS INTO ZCPR -; If the ZCPR is entered at location CPRLOC (at the JMP to CPR), then -; the default command in CIBUFF will be processed. If the ZCPR is entered -; at location CPRLOC+3 (at the JMP to CPR1), then the default command in -; CIBUFF will NOT be processed. -; NOTE: Entry into ZCPR in this way is permitted under ZCPR Version 4.0, -; but in order for this to work, CIBUFF and CBUFF MUST be initialized properly -; AND the C register MUST contain a valid User/Disk Flag (see Location 4: the -; most significant nybble contains the User Number and the least significant -; nybble contains the Disk Number). -; Some user programs (such as SYNONYM3) attempt to use the default -; command facility. Under the original CPR, it was necessary to initialize -; the pointer after the reserved space for the command buffer to point to -; the first byte of the command buffer. Under Version 4.x of ZCPR, this is -; no longer the case. The CIBPTR (Command Input Buffer PoinTeR) is located -; to be compatable with such programs (provided they determine the buffer -; length from the byte at MBUFF [CPRLOC + 6]), but under Version 4.x of ZCPR -; this is no longer necessary. ZCPR Version 4.x automatically initializes -; this buffer pointer in all cases. -; -ENTRY: - JMP CPR ; Process potential default command - JMP CPR1 ; Do NOT process potential default command -; -;**** Section 1 **** -; BUFFERS ET AL -; -; INPUT COMMAND LINE AND DEFAULT COMMAND -; The command line to be executed is stored here. This command line -; is generated in one of three ways: -; (1) by the user entering it through the BDOS READLN function at -; the du> prompt [user input from keyboard] -; (2) by the SUBMIT File Facility placing it there from a $$$.SUB -; file -; (3) by an external program or user placing the required command -; into this buffer -; In all cases, the command line is placed into the buffer starting at -; CIBUFF. This command line is terminated by the last character (NOT Carriage -; Return), and a character count of all characters in the command line -; up to and including the last character is placed into location CBUFF -; (immediately before the command line at CIBUFF). The placed command line -; is then parsed, interpreted, and the indicated command is executed. -; If CLEVEL3 is permitted, a terminating zero is placed after the command -; (otherwise the user program has to place this zero) and the CIBPTR is -; properly initialized (otherwise the user program has to init this ptr). -; If the command is placed by a user program, entering at CPRLOC is enough -; to have the command processed. Again, under CCPZ Version 4.0, it is not -; necessary to store the pointer to CIBUFF in CIBPTR; ZCPR will do this for -; the calling program if CLEVEL3 is made TRUE. -; WARNING: The command line must NOT exceed BUFLEN characters in length. -; For user programs which load this command, the value of BUFLEN can be -; obtained by examining the byte at MBUFF (CPRLOC + 6). -; -BUFLEN EQU 80 ;MAXIMUM BUFFER LENGTH -MBUFF: - DB BUFLEN ;MAXIMUM BUFFER LENGTH -CBUFF: - DB 0 ;NUMBER OF VALID CHARS IN COMMAND LINE -CIBUFF: - DB " " ;DEFAULT (COLD BOOT) COMMAND -CIBUF: - DB 0 ;COMMAND STRING TERMINATOR - DS BUFLEN-($-CIBUFF)+1 ;TOTAL IS 'BUFLEN' BYTES -; -CIBPTR: - DW CIBUFF ;POINTER TO COMMAND INPUT BUFFER -CIPTR: - DW CIBUF ;CURRENT POINTER -; - DS 26 ;STACK AREA -STACK EQU $ ;TOP OF STACK -; -; FILE TYPE FOR COMMAND -; -COMMSG: - DB "COM" -; -; SUBMIT FILE CONTROL BLOCK -; -SUBFCB: - IF SUBA ;IF $$$.SUB ON A: - DB 1 ;DISK NAME SET TO DEFAULT TO DRIVE A: - ENDIF -; - IF ~SUBA ;IF $$$.SUB ON CURRENT DRIVE - DB 0 ;DISK NAME SET TO DEFAULT TO CURRENT DRIVE - ENDIF -; - DB "$$$" ;FILE NAME - DB " " - DB "SUB" ;FILE TYPE - DB 0 ;EXTENT NUMBER - DB 0 ;S1 -SUBFS2: - DS 1 ;S2 -SUBFRC: - DS 1 ;RECORD COUNT - DS 16 ;DISK GROUP MAP -SUBFCR: - DS 1 ;CURRENT RECORD NUMBER -; -; COMMAND FILE CONTROL BLOCK -; -FCBDN: - DS 1 ;DISK NAME -FCBFN: - DS 8 ;FILE NAME -FCBFT: - DS 3 ;FILE TYPE - DS 1 ;EXTENT NUMBER - DS 2 ;S1 AND S2 - DS 1 ;RECORD COUNT -FCBDM: - DS 16 ;DISK GROUP MAP -FCBCR: - DS 1 ;CURRENT RECORD NUMBER -; -; OTHER BUFFERS -; -PAGCNT: - DB NLINES-2 ;LINES LEFT ON PAGE -CHRCNT: - DB 0 ;CHAR COUNT FOR TYPE -QMCNT: - DB 0 ;QUESTION MARK COUNT FOR FCB TOKEN SCANNER -; -; CPR BUILT-IN COMMAND TABLE -; -NCHARS EQU 4 ;NUMBER OF CHARS/COMMAND -; -; CPR COMMAND NAME TABLE -; EACH TABLE ENTRY IS COMPOSED OF THE 4-BYTE COMMAND AND 2-BYTE ADDRESS -; -CMDTBL: - DB "DIR " - DW DIR - DB "LIST" - DW LIST - DB "TYPE" - DW TYPE - DB "USER" - DW USER - DB "DFU " - DW DFU -; - IF ~RAS ;FOR NON-RAS - DB "GO " - DW GO - DB "ERA " - DW ERA - DB "SAVE" - DW SAVE - DB "REN " - DW REN - DB "GET " - DW GET - DB "JUMP" - DW JUMP - ENDIF -; -NCMNDS EQU ($-CMDTBL)/(NCHARS+2) -; -; -;**** Section 2 **** -; CPR STARTING POINTS -; -; START CPR AND DON'T PROCESS DEFAULT COMMAND STORED -; -CPR1: - XRA A ;SET NO DEFAULT COMMAND - STA CBUFF -; -; START CPR AND POSSIBLY PROCESS DEFAULT COMMAND -; -; NOTE ON MODIFICATION BY RGF: BDOS RETURNS 0FFH IN -; ACCUMULATOR WHENEVER IT LOGS IN A DIRECTORY, IF ANY -; FILE NAME CONTAINS A '$' IN IT. THIS IS NOW USED AS -; A CLUE TO DETERMINE WHETHER OR NOT TO DO A SEARCH -; FOR SUBMIT FILE, IN ORDER TO ELIMINATE WASTEFUL SEARCHES. -; -CPR: - LXI SP,STACK ;RESET STACK - PUSH B - MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4) - RAR ;EXTRACT USER NUMBER - RAR - RAR - RAR - ANI 0FH - MOV E,A ;SET USER NUMBER - CALL SETUSR - CALL RESET ;RESET DISK SYSTEM - STA RNGSUB ;SAVE SUBMIT CLUE FROM DRIVE A: - POP B - MOV A,C ;C=USER/DISK NUMBER (SEE LOC 4) - ANI 0FH ;EXTRACT DEFAULT DISK DRIVE - STA TDRIVE ;SET IT - JRZ NOLOG ;SKIP IF 0...ALREADY LOGGED - CALL LOGIN ;LOG IN DEFAULT DISK -; - IF ~SUBA ;IF $$$.SUB IS ON CURRENT DRIVE - STA RNGSUB ;BDOS '$' CLUE - ENDIF -; -NOLOG: - LXI D,SUBFCB ;CHECK FOR $$$.SUB ON CURRENT DISK -RNGSUB EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION - MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE RNGSUB FLAG - ORA A ;SET FLAGS ON CLUE - CMA ;PREPARE FOR COMING 'CMA' - CNZ SEAR1 - CMA ;0FFH IS RETURNED IF NO $$$.SUB, SO COMPLEMENT - STA RNGSUB ;SET FLAG (0=NO $$$.SUB) - LDA CBUFF ;EXECUTE DEFAULT COMMAND? - ORA A ;0=NO - JRNZ RS1 -; -; PROMPT USER AND INPUT COMMAND LINE FROM HIM -; -RESTRT: - LXI SP,STACK ;RESET STACK -; -; PRINT PROMPT (DU>) -; - CALL CRLF ;PRINT PROMPT - CALL GETDRV ;CURRENT DRIVE IS PART OF PROMPT - ADI 'A' ;CONVERT TO ASCII A-P - CALL CONOUT - CALL GETUSR ;GET USER NUMBER -; - IF SUPRES ;IF SUPPRESSING USR # REPORT FOR USR 0 - ORA A - JRZ RS000 - ENDIF -; - CPI 10 ;USER < 10? - JRC RS00 - SUI 10 ;SUBTRACT 10 FROM IT - PUSH PSW ;SAVE IT - MVI A,'1' ;OUTPUT 10'S DIGIT - CALL CONOUT - POP PSW -RS00: - ADI '0' ;OUTPUT 1'S DIGIT (CONVERT TO ASCII) - CALL CONOUT -; -; READ INPUT LINE FROM USER OR $$$.SUB -; -RS000: - CALL REDBUF ;INPUT COMMAND LINE FROM USER (OR $$$.SUB) -; -; PROCESS INPUT LINE -; -RS1: -; - IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED - CALL CNVBUF ;CAPITALIZE COMMAND LINE, PLACE ENDING 0, - ; AND SET CIBPTR VALUE - ENDIF -; - CALL DEFDMA ;SET TBUFF TO DMA ADDRESS - CALL GETDRV ;GET DEFAULT DRIVE NUMBER - STA TDRIVE ;SET IT - CALL SCANER ;PARSE COMMAND NAME FROM COMMAND LINE - CNZ ERROR ;ERROR IF COMMAND NAME CONTAINS A '?' - LXI D,RSTCPR ;PUT RETURN ADDRESS OF COMMAND - PUSH D ;ON THE STACK - LDA TEMPDR ;IS COMMAND OF FORM 'D:COMMAND'? - ORA A ;NZ=YES - JNZ COM ; IMMEDIATELY - CALL CMDSER ;SCAN FOR CPR-RESIDENT COMMAND - JNZ COM ;NOT CPR-RESIDENT - MOV A,M ;FOUND IT: GET LOW-ORDER PART - INX H ;GET HIGH-ORDER PART - MOV H,M ;STORE HIGH - MOV L,A ;STORE LOW - PCHL ;EXECUTE CPR ROUTINE -; -; ENTRY POINT FOR RESTARTING CPR AND LOGGING IN DEFAULT DRIVE -; -RSTCPR: - CALL DLOGIN ;LOG IN DEFAULT DRIVE -; -; ENTRY POINT FOR RESTARTING CPR WITHOUT LOGGING IN DEFAULT DRIVE -; -RCPRNL: - CALL SCANER ;EXTRACT NEXT TOKEN FROM COMMAND LINE - LDA FCBFN ;GET FIRST CHAR OF TOKEN - SUI ' ' ;ANY CHAR? - LXI H,TEMPDR - ORA M - JNZ ERROR - JR RESTRT -; -; No File Error Message -; -PRNNF: - CALL PRINTC ;NO FILE MESSAGE - DB "No Fil",'e'+80H - RET -; -;**** Section 3 **** -; I/O UTILITIES -; -; OUTPUT CHAR IN REG A TO CONSOLE AND DON'T CHANGE BC -; -; -; OUTPUT -; -CRLF: - MVI A,CR - CALL CONOUT - MVI A,LF ;FALL THRU TO CONOUT -; -CONOUT: - PUSH B - MVI C,02H -OUTPUT: - MOV E,A - PUSH H - CALL BDOS - POP H - POP B - RET -; -CONIN: - MVI C,01H ;GET CHAR FROM CON: WITH ECHO - CALL BDOSB - JMP UCASE ;CAPITALIZE -; -LCOUT: - PUSH PSW ;OUTPUT CHAR TO CON: OR LST: DEP ON PRFLG -PRFLG EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION - MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS THE PRINT FLAG - ORA A ;0=TYPE - JRZ LC1 - POP PSW ;GET CHAR -; -; OUTPUT CHAR IN REG A TO LIST DEVICE -; -LSTOUT: - PUSH B - MVI C,05H - JR OUTPUT -LC1: - POP PSW ;GET CHAR - PUSH PSW - CALL CONOUT ;OUTPUT TO CON: - POP PSW - CPI LF ;CHECK FOR PAGING - JZ PAGER - RET -; -READF: - LXI D,FCBDN ;FALL THRU TO READ -READ: - MVI C,14H ;FALL THRU TO BDOSB -; -; CALL BDOS AND SAVE BC -; -BDOSB: - PUSH B - CALL BDOS - POP B - ORA A - RET -; -; PRINT STRING (ENDING IN 0) PTED TO BY RET ADR;START WITH -; -PRINTC: - PUSH PSW ;SAVE FLAGS - CALL CRLF ;NEW LINE - POP PSW -; -PRINT: - XTHL ;GET PTR TO STRING - PUSH PSW ;SAVE FLAGS - CALL PRIN1 ;PRINT STRING - POP PSW ;GET FLAGS - XTHL ;RESTORE HL AND RET ADR - RET -; -; PRINT STRING (ENDING IN 0) PTED TO BY HL -; -PRIN1: - MOV A,M ;GET NEXT BYTE - ANI 7FH ;WW - CLEAR MSB - CALL CONOUT ;PRINT CHAR - MOV A,M ;GET NEXT BYTE AGAIN FOR TEST - INX H ;PT TO NEXT BYTE - ORA A ;SET FLAGS - RZ ;DONE IF ZERO - RM ;DONE IF MSB SET - JR PRIN1 -; -; BDOS FUNCTION ROUTINES -; -; -; RETURN NUMBER OF CURRENT DISK IN A -; -GETDRV: - MVI C,19H - JR BDOSJP -; -; SET 80H AS DMA ADDRESS -; -DEFDMA: - LXI D,TBUFF ;80H=TBUFF -DMASET: - MVI C,1AH - JR BDOSJP -; -RESET: - MVI C,0DH -BDOSJP: - JMP BDOS -; -LOGIN: - MOV E,A - MVI C,0EH - JR BDOSJP ;SAVE SOME CODE SPACE -; -OPENF: - XRA A - STA FCBCR - LXI D,FCBDN ;FALL THRU TO OPEN -; -OPEN: - MVI C,0FH ;FALL THRU TO GRBDOS -; -GRBDOS: - CALL BDOS - INR A ;SET ZERO FLAG FOR ERROR RETURN - RET -; -CLOSE: - MVI C,10H - JR GRBDOS -; -SEARF: - LXI D,FCBDN ;SPECIFY FCB -SEAR1: - MVI C,11H - JR GRBDOS -; -SEARN: - MVI C,12H - JR GRBDOS -; -; CHECK FOR SUBMIT FILE IN EXECUTION AND ABORT IT IF SO -; -SUBKIL: - LXI H,RNGSUB ;CHECK FOR SUBMIT FILE IN EXECUTION - MOV A,M - ORA A ;0=NO - RZ - MVI M,0 ;ABORT SUBMIT FILE - LXI D,SUBFCB ;DELETE $$$.SUB -; -DELETE: - MVI C,13H - JR BDOSJP ;SAVE MORE SPACE -; -; RESET USER NUMBER IF CHANGED -; -RESETUSR: -TMPUSR EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION - MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TMPUSR - MOV E,A ;PLACE IN E - JR SETUSR ;THEN GO SET USER -GETUSR: - MVI E,0FFH ;GET CURRENT USER NUMBER -SETUSR: - MVI C,20H ;SET USER NUMBER TO VALUE IN E (GET IF E=FFH) - JR BDOSJP ;MORE SPACE SAVING -; -; END OF BDOS FUNCTIONS -; -; -;**** Section 4 **** -; CPR UTILITIES -; -; SET USER/DISK FLAG TO CURRENT USER AND DEFAULT DISK -; -SETUD: - CALL GETUSR ;GET NUMBER OF CURRENT USER - ADD A ;PLACE IT IN HIGH NYBBLE - ADD A - ADD A - ADD A - LXI H,TDRIVE ;MASK IN DEFAULT DRIVE NUMBER (LOW NYBBLE) - ORA M ;MASK IN - STA UDFLAG ;SET USER/DISK NUMBER - RET -; -; SET USER/DISK FLAG TO USER 0 AND DEFAULT DISK -; -SETU0D: -TDRIVE EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION - MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TDRIVE - STA UDFLAG ;SET USER/DISK NUMBER - RET -; -; CONVERT CHAR IN A TO UPPER CASE -; -UCASE: - CPI 61H ;LOWER-CASE A - RC - CPI 7BH ;GREATER THAN LOWER-CASE Z? - RNC - ANI 5FH ;CAPITALIZE - RET -; -; INPUT NEXT COMMAND TO CPR -; This routine determines if a SUBMIT file is being processed -; and extracts the command line from it if so or from the user's console -; -REDBUF: - LDA RNGSUB ;SUBMIT FILE CURRENTLY IN EXECUTION? - ORA A ;0=NO - JRZ RB1 ;GET LINE FROM CONSOLE IF NOT - LXI D,SUBFCB ;OPEN $$$.SUB - PUSH D ;SAVE DE - CALL OPEN - POP D ;RESTORE DE - JRZ RB1 ;ERASE $$$.SUB IF END OF FILE AND GET CMND - LDA SUBFRC ;GET VALUE OF LAST RECORD IN FILE - DCR A ;PT TO NEXT TO LAST RECORD - STA SUBFCR ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB - CALL READ ;DE=SUBFCB - JRNZ RB1 ;ABORT $$$.SUB IF ERROR IN READING LAST REC - LXI D,CBUFF ;COPY LAST RECORD (NEXT SUBMIT CMND) TO CBUFF - LXI H,TBUFF ; FROM TBUFF - LXI B,BUFLEN ;NUMBER OF BYTES - LDIR - LXI H,SUBFS2 ;PT TO S2 OF $$$.SUB FCB - MVI M,0 ;SET S2 TO ZERO - INX H ;PT TO RECORD COUNT - DCR M ;DECREMENT RECORD COUNT OF $$$.SUB - LXI D,SUBFCB ;CLOSE $$$.SUB - CALL CLOSE - JRZ RB1 ;ABORT $$$.SUB IF ERROR - MVI A,SPRMPT ;PRINT SUBMIT PROMPT - CALL CONOUT - LXI H,CIBUFF ;PRINT COMMAND LINE FROM $$$.SUB - CALL PRIN1 - CALL BREAK ;CHECK FOR ABORT (ANY CHAR) -; - IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED - RZ ;IF (NO ABORT), RETURN TO CALLER AND RUN - ENDIF -; - IF ~CLEVEL3 ;IF THIRD COMMAND LEVEL IS NOT PERMITTED - JRZ CNVBUF ;IF (NO ABORT), CAPITALIZE COMMAND - ENDIF -; - CALL SUBKIL ;KILL $$$.SUB IF ABORT - JMP RESTRT ;RESTART CPR -; -; INPUT COMMAND LINE FROM USER CONSOLE -; -RB1: - CALL SUBKIL ;ERASE $$$.SUB IF PRESENT - CALL SETUD ;SET USER AND DISK - MVI A,CPRMPT ;PRINT PROMPT - CALL CONOUT - MVI C,0AH ;READ COMMAND LINE FROM USER - LXI D,MBUFF - CALL BDOS -; - IF CLEVEL3 ;IF THIRD COMMAND LEVEL IS PERMITTED - JMP SETU0D ;SET CURRENT DISK NUMBER IN LOWER PARAMS - ENDIF -; - IF ~CLEVEL3 ;IF THIRD COMMAND LEVEL IS NOT PERMITTED - CALL SETU0D ;SET CURRENT DISK NUMBER IF LOWER PARAMS - ; AND FALL THRU TO CNVBUF - ENDIF -; -; CAPITALIZE STRING (ENDING IN 0) IN CBUFF AND SET PTR FOR PARSING -; -CNVBUF: - LXI H,CBUFF ;PT TO USER'S COMMAND - MOV B,M ;CHAR COUNT IN B - INR B ;ADD 1 IN CASE OF ZERO -CB1: - INX H ;PT TO 1ST VALID CHAR - MOV A,M ;CAPITALIZE COMMAND CHAR - CALL UCASE - MOV M,A - DJNZ CB1 ;CONTINUE TO END OF COMMAND LINE -CB2: - MVI M,0 ;STORE ENDING - LXI H,CIBUFF ;SET COMMAND LINE PTR TO 1ST CHAR - SHLD CIBPTR - RET -; -; CHECK FOR ANY CHAR FROM USER CONSOLE;RET W/ZERO SET IF NONE -; -BREAK: - PUSH D ;SAVE DE - MVI C,11 ;CSTS CHECK - CALL BDOSB - CNZ CONIN ;GET INPUT CHAR -BRKBK: - POP D - RET -; -; GET THE REQUESTED USER NUMBER FROM THE COMMAND LINE AND VALIDATE IT. -; -USRNUM: - CALL NUMBER - CPI MAXUSR+1 - RC -; -; INVALID COMMAND -- PRINT IT -; -ERROR: - CALL CRLF ;NEW LINE - LHLD CIPTR ;PT TO BEGINNING OF COMMAND LINE -ERR2: - MOV A,M ;GET CHAR - CPI ' '+1 ;SIMPLE '?' IF OR LESS - JRC ERR1 - PUSH H ;SAVE PTR TO ERROR COMMAND CHAR - CALL CONOUT ;PRINT COMMAND CHAR - POP H ;GET PTR - INX H ;PT TO NEXT - JR ERR2 ;CONTINUE -ERR1: - CALL PRINT ;PRINT '?' - DB '?'+80H - CALL SUBKIL ;TERMINATE ACTIVE $$$.SUB IF ANY - JMP RESTRT ;RESTART CPR -; -; CHECK TO SEE IF DE PTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET -; -SDELM: - LDAX D - ORA A ;0=DELIMITER - RZ - CPI ' ' ;ERROR IF < - JRC ERROR - RZ ;=DELIMITER - CPI '=' ;'='=DELIMITER - RZ - CPI 5FH ;UNDERSCORE=DELIMITER - RZ - CPI '.' ;'.'=DELIMITER - RZ - CPI ':' ;':'=DELIMITER - RZ -;WW CPI ';' ;';'=DELIMITER - CPI 3BH ;';'=DELIMITER - RZ - CPI '<' ;'<'=DELIMITER - RZ - CPI '>' ;'>'=DELIMITER - RET -; -; ADVANCE INPUT PTR TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK -; -ADVAN: - LDED CIBPTR -; -; SKIP STRING PTED TO BY DE (STRING ENDS IN 0) UNTIL END OF STRING -; OR NON-BLANK ENCOUNTERED (BEGINNING OF TOKEN) -; -SBLANK: - LDAX D - ORA A - RZ - CPI ' ' - RNZ - INX D - JR SBLANK -; -; ADD A TO HL (HL=HL+A) -; -ADDAH: - ADD L - MOV L,A - RNC - INR H - RET -; -; EXTRACT DECIMAL NUMBER FROM COMMAND LINE -; RETURN WITH VALUE IN REG A;ALL REGISTERS MAY BE AFFECTED -; -NUMBER: - CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN - LXI H,FCBFN+10 ;PT TO END OF TOKEN FOR CONVERSION - MVI B,11 ;11 CHARS MAX -; -; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER -; -NUMS: - MOV A,M ;GET CHARS FROM END, SEARCHING FOR SUFFIX - DCX H ;BACK UP - CPI ' ' ;SPACE? - JRNZ NUMS1 ;CHECK FOR SUFFIX - DJNZ NUMS ;COUNT DOWN - JR NUM0 ;BY DEFAULT, PROCESS -NUMS1: - CPI NUMBASE ;CHECK AGAINST BASE SWITCH FLAG - JRZ HNUM0 -; -; PROCESS DECIMAL NUMBER -; -NUM0: - LXI H,FCBFN ;PT TO BEGINNING OF TOKEN - LXI B,1100H ;C=ACCUMULATED VALUE, B=CHAR COUNT - ; (C=0, B=11) -NUM1: - MOV A,M ;GET CHAR - CPI ' ' ;DONE IF - JRZ NUM2 - INX H ;PT TO NEXT CHAR - SUI '0' ;CONVERT TO BINARY (ASCII 0-9 TO BINARY) - CPI 10 ;ERROR IF >= 10 - JRNC NUMERR - MOV D,A ;DIGIT IN D - MOV A,C ;NEW VALUE = OLD VALUE * 10 - RLC - RLC - RLC - ADD C ;CHECK FOR RANGE ERROR - JRC NUMERR - ADD C ;CHECK FOR RANGE ERROR - JRC NUMERR - ADD D ;NEW VALUE = OLD VALUE * 10 + DIGIT - JRC NUMERR ;CHECK FOR RANGE ERROR - MOV C,A ;SET NEW VALUE - DJNZ NUM1 ;COUNT DOWN -; -; RETURN FROM NUMBER -; -NUM2: - MOV A,C ;GET ACCUMULATED VALUE - RET -; -; NUMBER ERROR ROUTINE FOR SPACE CONSERVATION -; -NUMERR: - JMP ERROR ;USE ERROR ROUTINE - THIS IS RELATIVE PT -; -; EXTRACT HEXADECIMAL NUMBER FROM COMMAND LINE -; RETURN WITH VALUE IN REG A; ALL REGISTERS MAY BE AFFECTED -; -HEXNUM: - CALL SCANER ;PARSE NUMBER AND PLACE IN FCBFN -HNUM0: - LXI H,FCBFN ;PT TO TOKEN FOR CONVERSION - LXI D,0 ;DE=ACCUMULATED VALUE - MVI B,11 ;B=CHAR COUNT -HNUM1: - MOV A,M ;GET CHAR - CPI ' ' ;DONE? - JRZ HNUM3 ;RETURN IF SO - CPI NUMBASE ;DONE IF NUMBASE SUFFIX - JRZ HNUM3 - SUI '0' ;CONVERT TO BINARY - JRC NUMERR ;RETURN AND DONE IF ERROR - CPI 10 ;0-9? - JRC HNUM2 - SUI 7 ;A-F? - CPI 10H ;ERROR? - JRNC NUMERR -HNUM2: - INX H ;PT TO NEXT CHAR - MOV C,A ;DIGIT IN C - MOV A,D ;GET ACCUMULATED VALUE - RLC ;EXCHANGE NYBBLES - RLC - RLC - RLC - ANI 0F0H ;MASK OUT LOW NYBBLE - MOV D,A - MOV A,E ;SWITCH LOW-ORDER NYBBLES - RLC - RLC - RLC - RLC - MOV E,A ;HIGH NYBBLE OF E=NEW HIGH OF E, - ; LOW NYBBLE OF E=NEW LOW OF D - ANI 0FH ;GET NEW LOW OF D - ORA D ;MASK IN HIGH OF D - MOV D,A ;NEW HIGH BYTE IN D - MOV A,E - ANI 0F0H ;MASK OUT LOW OF E - ORA C ;MASK IN NEW LOW - MOV E,A ;NEW LOW BYTE IN E - DJNZ HNUM1 ;COUNT DOWN -; -; RETURN FROM HEXNUM -; -HNUM3: - XCHG ;RETURNED VALUE IN HL - MOV A,L ;LOW-ORDER BYTE IN A - RET -; -; PT TO DIRECTORY ENTRY IN TBUFF WHOSE OFFSET IS SPECIFIED BY A AND C -; -DIRPTR: - LXI H,TBUFF ;PT TO TEMP BUFFER - ADD C ;PT TO 1ST BYTE OF DIR ENTRY - CALL ADDAH ;PT TO DESIRED BYTE IN DIR ENTRY - MOV A,M ;GET DESIRED BYTE - RET -; -; CHECK FOR SPECIFIED DRIVE AND LOG IT IN IF NOT DEFAULT -; -SLOGIN: - XRA A ;SET FCBDN FOR DEFAULT DRIVE - STA FCBDN - CALL COMLOG ;CHECK DRIVE - RZ - JR DLOG5 ;DO LOGIN OTHERWISE -; -; CHECK FOR SPECIFIED DRIVE AND LOG IN DEFAULT DRIVE IF SPECIFIED<>DEFAULT -; -DLOGIN: - CALL COMLOG ;CHECK DRIVE - RZ ;ABORT IF SAME - LDA TDRIVE ;LOG IN DEFAULT DRIVE -; -DLOG5: JMP LOGIN -; -; ROUTINE COMMON TO BOTH LOGIN ROUTINES; ON EXIT, Z SET MEANS ABORT -; -COMLOG: -TEMPDR EQU $+1 ;POINTER FOR IN-THE-CODE MODIFICATION - MVI A,0 ;2ND BYTE (IMMEDIATE ARG) IS TEMPDR - ORA A ;0=NO - RZ - DCR A ;COMPARE IT AGAINST DEFAULT - LXI H,TDRIVE - CMP M - RET ;ABORT IF SAME -; -; EXTRACT TOKEN FROM COMMAND LINE AND PLACE IT INTO FCBDN; -; FORMAT FCBDN FCB IF TOKEN RESEMBLES FILE NAME AND TYPE (FILENAME.TYP); -; ON INPUT, CIBPTR PTS TO CHAR AT WHICH TO START SCAN; -; ON OUTPUT, CIBPTR PTS TO CHAR AT WHICH TO CONTINUE AND ZERO FLAG IS RESET -; IF '?' IS IN TOKEN -; -; ENTRY POINTS: -; SCANER - LOAD TOKEN INTO FIRST FCB -; SCANX - LOAD TOKEN INTO FCB PTED TO BY HL -; -SCANER: - LXI H,FCBDN ;POINT TO FCBDN -SCANX: - XRA A ;SET TEMPORARY DRIVE NUMBER TO DEFAULT - STA TEMPDR - CALL ADVAN ;SKIP TO NON-BLANK OR END OF LINE - SDED CIPTR ;SET PTR TO NON-BLANK OR END OF LINE - LDAX D ;END OF LINE? - ORA A ;0=YES - JRZ SCAN2 - SBI 'A'-1 ;CONVERT POSSIBLE DRIVE SPEC TO NUMBER - MOV B,A ;STORE NUMBER (A:=0, B:=1, ETC) IN B - INX D ;PT TO NEXT CHAR - LDAX D ;SEE IF IT IS A COLON (:) - CPI ':' - JRZ SCAN3 ;YES, WE HAVE A DRIVE SPEC - DCX D ;NO, BACK UP PTR TO FIRST NON-BLANK CHAR -SCAN2: - LDA TDRIVE ;SET 1ST BYTE OF FCBDN AS DEFAULT DRIVE - MOV M,A - JR SCAN4 -SCAN3: - MOV A,B ;WE HAVE A DRIVE SPEC - STA TEMPDR ;SET TEMPORARY DRIVE - MOV M,B ;SET 1ST BYTE OF FCBDN AS SPECIFIED DRIVE - INX D ;PT TO BYTE AFTER ':' -; -; EXTRACT FILENAME FROM POSSIBLE FILENAME.TYP -; -SCAN4: - XRA A ;A=0 - STA QMCNT ;INIT COUNT OF NUMBER OF QUESTION MARKS IN FCB - MVI B,8 ;MAX OF 8 CHARS IN FILE NAME - CALL SCANF ;FILL FCB FILE NAME -; -; EXTRACT FILE TYPE FROM POSSIBLE FILENAME.TYP -; - MVI B,3 ;PREPARE TO EXTRACT TYPE - CPI '.' ;IF (DE) DELIMITER IS A '.', WE HAVE A TYPE - JRNZ SCAN15 ;FILL FILE TYPE BYTES WITH - INX D ;PT TO CHAR IN COMMAND LINE AFTER '.' - CALL SCANF ;FILL FCB FILE TYPE - JR SCAN16 ;SKIP TO NEXT PROCESSING -SCAN15: - CALL SCANF4 ;SPACE FILL -; -; FILL IN EX, S1, S2, AND RC WITH ZEROES -; -SCAN16: - MVI B,4 ;4 BYTES -SCAN17: - INX H ;PT TO NEXT BYTE IN FCBDN - MVI M,0 - DJNZ SCAN17 -; -; SCAN COMPLETE -- DE PTS TO DELIMITER BYTE AFTER TOKEN -; - SDED CIBPTR -; -; SET ZERO FLAG TO INDICATE PRESENCE OF '?' IN FILENAME.TYP -; - LDA QMCNT ;GET NUMBER OF QUESTION MARKS - ORA A ;SET ZERO FLAG TO INDICATE ANY '?' - RET -; -; SCANF -- SCAN TOKEN PTED TO BY DE FOR A MAX OF B BYTES; PLACE IT INTO -; FILE NAME FIELD PTED TO BY HL; EXPAND AND INTERPRET WILD CARDS OF -; '*' AND '?'; ON EXIT, DE PTS TO TERMINATING DELIMITER -; -SCANF: - CALL SDELM ;DONE IF DELIMITER ENCOUNTERED - FILL - JRZ SCANF4 - INX H ;PT TO NEXT BYTE IN FCBDN - CPI '*' ;IS (DE) A WILD CARD? - JRNZ SCANF1 ;CONTINUE IF NOT - MVI M,'?' ;PLACE '?' IN FCBDN AND DON'T ADVANCE DE IF SO - CALL SCQ ;SCANNER COUNT QUESTION MARKS - JR SCANF2 -SCANF1: - MOV M,A ;STORE FILENAME CHAR IN FCBDN - INX D ;PT TO NEXT CHAR IN COMMAND LINE - CPI '?' ;CHECK FOR QUESTION MARK (WILD) - CZ SCQ ;SCANNER COUNT QUESTION MARKS -SCANF2: - DJNZ SCANF ;DECREMENT CHAR COUNT UNTIL 8 ELAPSED -SCANF3: - CALL SDELM ;8 CHARS OR MORE - SKIP UNTIL DELIMITER - RZ ;ZERO FLAG SET IF DELIMITER FOUND - INX D ;PT TO NEXT CHAR IN COMMAND LINE - JR SCANF3 -; -; FILL MEMORY POINTED TO BY HL WITH SPACES FOR B BYTES -; -SCANF4: - INX H ;PT TO NEXT BYTE IN FCBDN - MVI M,' ' ;FILL FILENAME PART WITH - DJNZ SCANF4 - RET -; -; INCREMENT QUESTION MARK COUNT FOR SCANNER -; THIS ROUTINE INCREMENTS THE COUNT OF THE NUMBER OF QUESTION MARKS IN -; THE CURRENT FCB ENTRY -; -SCQ: - LDA QMCNT ;GET COUNT - INR A ;INCREMENT - STA QMCNT ;PUT COUNT - RET -; -; CMDTBL (COMMAND TABLE) SCANNER -; ON RETURN, HL PTS TO ADDRESS OF COMMAND IF CPR-RESIDENT -; ON RETURN, ZERO FLAG SET MEANS CPR-RESIDENT COMMAND -; -CMDSER: - LXI H,CMDTBL ;PT TO COMMAND TABLE - MVI C,NCMNDS ;SET COMMAND COUNTER -CMS1: - LXI D,FCBFN ;PT TO STORED COMMAND NAME - MVI B,NCHARS ;NUMBER OF CHARS/COMMAND (8 MAX) -CMS2: - LDAX D ;COMPARE AGAINST TABLE ENTRY - CMP M - JRNZ CMS3 ;NO MATCH - INX D ;PT TO NEXT CHAR - INX H - DJNZ CMS2 ;COUNT DOWN - LDAX D ;NEXT CHAR IN INPUT COMMAND MUST BE - CPI ' ' - JRNZ CMS4 - RET ;COMMAND IS CPR-RESIDENT (ZERO FLAG SET) -CMS3: - INX H ;SKIP TO NEXT COMMAND TABLE ENTRY - DJNZ CMS3 -CMS4: - INX H ;SKIP ADDRESS - INX H - DCR C ;DECREMENT TABLE ENTRY NUMBER - JRNZ CMS1 - INR C ;CLEAR ZERO FLAG - RET ;COMMAND IS DISK-RESIDENT (ZERO FLAG CLEAR) -; -;**** Section 5 **** -; CPR-Resident Commands -; -; -;Section 5A -;Command: DIR -;Function: To display a directory of the files on disk -;Forms: -; DIR Displays the DIR files -; DIR S Displays the SYS files -; DIR A Display both DIR and SYS files -; -DIR: - MVI A,80H ;SET SYSTEM BIT EXAMINATION - PUSH PSW - CALL SCANER ;EXTRACT POSSIBLE D:FILENAME.TYP TOKEN - CALL SLOGIN ;LOG IN DRIVE IF NECESSARY - LXI H,FCBFN ;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP - MOV A,M ;GET FIRST CHAR OF FILENAME.TYP - CPI ' ' ;IF , ALL WILD - CZ FILLQ - CALL ADVAN ;LOOK AT NEXT INPUT CHAR - MVI B,0 ;SYS TOKEN DEFAULT - JRZ DIR2 ;JUMP; THERE ISN'T ONE - CPI SYSFLG ;SYSTEM FLAG SPECIFIER? - JRZ GOTSYS ;GOT SYSTEM SPECIFIER - CPI SOFLG ;SYS ONLY? - JRNZ DIR2 - MVI B,80H ;FLAG SYS ONLY -GOTSYS: - INX D - SDED CIBPTR - CPI SOFLG ;SYS ONLY SPEC? - JRZ DIR2 ;THEN LEAVE BIT SPEC UNCHAGNED - POP PSW ;GET FLAG - XRA A ;SET NO SYSTEM BIT EXAMINATION - PUSH PSW -DIR2: - POP PSW ;GET FLAG -DIR2A: - ;DROP INTO DIRPR TO PRINT DIRECTORY - ; THEN RESTART CPR -; -; DIRECTORY PRINT ROUTINE; ON ENTRY, MSB OF A IS 1 (80H) IF SYSTEM FILES EXCL -; -DIRPR: - MOV D,A ;STORE SYSTEM FLAG IN D - MVI E,0 ;SET COLUMN COUNTER TO ZERO - PUSH D ;SAVE COLUMN COUNTER (E) AND SYSTEM FLAG (D) - MOV A,B ;SYS ONLY SPECIFIER - STA SYSTST - CALL SEARF ;SEARCH FOR SPECIFIED FILE (FIRST OCCURRANCE) - CZ PRNNF ;PRINT NO FILE MSG;REG A NOT CHANGED -; -; ENTRY SELECTION LOOP; ON ENTRY, A=OFFSET FROM SEARF OR SEARN -; -DIR3: - JRZ DIR11 ;DONE IF ZERO FLAG SET - DCR A ;ADJUST TO RETURNED VALUE - RRC ;CONVERT NUMBER TO OFFSET INTO TBUFF - RRC - RRC - ANI 60H - MOV C,A ;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY) - MVI A,10 ;ADD 10 TO PT TO SYSTEM FILE ATTRIBUTE BIT - CALL DIRPTR - POP D ;GET SYSTEM BIT MASK FROM D - PUSH D - ANA D ;MASK FOR SYSTEM BIT -SYSTST EQU $+1 ;POINTER TO IN-THE-CODE BUFFER SYSTST - CPI 0 - JRNZ DIR10 - POP D ;GET ENTRY COUNT (= COUNTER) - MOV A,E ;ADD 1 TO IT - INR E - PUSH D ;SAVE IT - ANI 03H ;OUTPUT IF 4 ENTRIES PRINTED IN LINE - PUSH PSW - JRNZ DIR4 - CALL CRLF ;NEW LINE - JR DIR5 -DIR4: - CALL PRINT -; - IF WIDE - DB " " ;2 SPACES - DB FENCE ;THEN FENCE CHAR - DB ' ',' '+80H ;THEN 2 MORE SPACES - ENDIF -; - IF ~WIDE - DB ' ' ;SPACE - DB FENCE ;THEN FENCE CHAR - DB ' '+80H ;THEN SPACE - ENDIF -; -DIR5: - MVI B,01H ;PT TO 1ST BYTE OF FILE NAME -DIR6: - MOV A,B ;A=OFFSET - CALL DIRPTR ;HL NOW PTS TO 1ST BYTE OF FILE NAME - ANI 7FH ;MASK OUT MSB - CPI ' ' ;NO FILE NAME? - JRNZ DIR8 ;PRINT FILE NAME IF PRESENT - POP PSW - PUSH PSW - CPI 03H - JRNZ DIR7 - MVI A,09H ;PT TO 1ST BYTE OF FILE TYPE - CALL DIRPTR ;HL NOW PTS TO 1ST BYTE OF FILE TYPE - ANI 7FH ;MASK OUT MSB - CPI ' ' ;NO FILE TYPE? - JRZ DIR9 ;CONTINUE IF SO -DIR7: - MVI A,' ' ;OUTPUT -DIR8: - CALL CONOUT ;PRINT CHAR - INR B ;INCR CHAR COUNT - MOV A,B - CPI 12 ;END OF FILENAME.TYP? - JRNC DIR9 ;CONTINUE IF SO - CPI 09H ;END IF FILENAME ONLY? - JRNZ DIR6 ;PRINT TYP IF SO - MVI A,'.' ;PRINT DOT BETWEEN FILE NAME AND TYPE - CALL CONOUT - JR DIR6 -DIR9: - POP PSW -DIR10: - CALL BREAK ;CHECK FOR ABORT - JRNZ DIR11 - CALL SEARN ;SEARCH FOR NEXT FILE - JR DIR3 ;CONTINUE -DIR11: - POP D ;RESTORE STACK - RET -; -; FILL FCB @HL WITH '?' -; -FILLQ: - MVI B,11 ;NUMBER OF CHARS IN FN & FT -FQLP: - MVI M,'?' ;STORE '?' - INX H - DJNZ FQLP - RET -; -;Section 5B -;Command: ERA -;Function: Erase files -;Forms: -; ERA Erase Specified files and print their names -; - IF ~RAS ;NOT FOR REMOTE-ACCESS SYSTEM -; -ERA: - CALL SCANER ;PARSE FILE SPECIFICATION - CPI 11 ;ALL WILD (ALL FILES = 11 '?')? - JRNZ ERA1 ;IF NOT, THEN DO ERASES - CALL PRINTC - DB "All",'?'+80H - CALL CONIN ;GET REPLY - CPI 'Y' ;YES? - JNZ RESTRT ;RESTART CPR IF NOT - CALL CRLF ;NEW LINE -ERA1: - CALL SLOGIN ;LOG IN SELECTED DISK IF ANY - XRA A ;PRINT ALL FILES (EXAMINE SYSTEM BIT) - MOV B,A ;NO SYS-ONLY OPT TO DIRPR - CALL DIRPR ;PRINT DIRECTORY OF ERASED FILES - LXI D,FCBDN ;DELETE FILE SPECIFIED - CALL DELETE - RET ;REENTER CPR -; - ENDIF ;RAS -; -;Section 5C -;Command: LIST -;Function: Print out specified file on the LST: Device -;Forms: -; LIST Print file (NO Paging) -; -LIST: - MVI A,0FFH ;TURN ON PRINTER FLAG - JR TYPE0 -; -;Section 5D -;Command: TYPE -;Function: Print out specified file on the CON: Device -;Forms: -; TYPE Print file -; TYPE P Print file with paging flag -; -TYPE: - XRA A ;TURN OFF PRINTER FLAG -; -; ENTRY POINT FOR CPR LIST FUNCTION (LIST) -; -TYPE0: - STA PRFLG ;SET FLAG - CALL SCANER ;EXTRACT FILENAME.TYP TOKEN - JNZ ERROR ;ERROR IF ANY QUESTION MARKS - CALL ADVAN ;GET PGDFLG IF IT'S THERE - STA PGFLG ;SAVE IT AS A FLAG - JRZ NOSLAS ;JUMP IF INPUT ENDED - INX D ;PUT NEW BUF POINTER - XCHG - SHLD CIBPTR -NOSLAS: - CALL SLOGIN ;LOG IN SELECTED DISK IF ANY - CALL OPENF ;OPEN SELECTED FILE - JZ TYPE4 ;ABORT IF ERROR - CALL CRLF ;NEW LINE - MVI A,NLINES-1 ;SET LINE COUNT - STA PAGCNT - LXI H,CHRCNT ;SET CHAR POSITION/COUNT - MVI M,0FFH ;EMPTY LINE - MVI B,0 ;SET TAB CHAR COUNTER -TYPE1: - LXI H,CHRCNT ;PT TO CHAR POSITION/COUNT - MOV A,M ;END OF BUFFER? - CPI 80H - JRC TYPE2 - PUSH H ;READ NEXT BLOCK - CALL READF - POP H - JRNZ TYPE3 ;ERROR? - XRA A ;RESET COUNT - MOV M,A -TYPE2: - INR M ;INCREMENT CHAR COUNT - LXI H,TBUFF ;PT TO BUFFER - CALL ADDAH ;COMPUTE ADDRESS OF NEXT CHAR FROM OFFSET - MOV A,M ;GET NEXT CHAR - ANI 7FH ;MASK OUT MSB - CPI 1AH ;END OF FILE (^Z)? - RZ ;RESTART CPR IF SO -; -; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION -; - CPI CR ;RESET TAB COUNT? - JRZ TABRST - CPI LF ;RESET TAB COUNT? - JRZ TABRST - CPI TAB ;TAB? - JRZ LTAB - CALL LCOUT ;OUTPUT CHAR - INR B ;INCREMENT CHAR COUNT - JR TYPE2L -TABRST: - CALL LCOUT ;OUTPUT OR - MVI B,0 ;RESET TAB COUNTER - JR TYPE2L -LTAB: - MVI A,' ' ; - CALL LCOUT - INR B ;INCR POS COUNT - MOV A,B - ANI 7 - JRNZ LTAB -; -; CONTINUE PROCESSING -; -TYPE2L: - CALL BREAK ;CHECK FOR ABORT - JRZ TYPE1 ;CONTINUE IF NO CHAR - CPI 'C'-'@' ;^C? - RZ ;RESTART IF SO - JR TYPE1 -TYPE3: - DCR A ;NO ERROR? - RZ ;RESTART CPR -TYPE4: - JMP ERRLOG -; -; PAGING ROUTINES -; PAGER COUNTS DOWN LINES AND PAUSES FOR INPUT (DIRECT) IF COUNT EXPIRES -; PAGSET SETS LINES/PAGE COUNT -; -PAGER: - PUSH H - LXI H,PAGCNT ;COUNT DOWN - DCR M - JRNZ PGBAK ;JUMP IF NOT END OF PAGE - MVI M,NLINES-2 ;REFILL COUNTER -; -PGFLG EQU $+1 ;POINTER TO IN-THE-CODE BUFFER PGFLG - MVI A,0 ;0 MAY BE CHANGED BY PGFLG EQUATE - CPI PGDFLG ;PAGE DEFAULT OVERRIDE OPTION WANTED? -; - IF PGDFLT ;IF PAGING IS DEFAULT - JRZ PGBAK ; PGDFLG MEANS NO PAGING, PLEASE - ELSE ;IF PAGING NOT DEFAULT - JRNZ PGBAK ; PGDFLG MEANS PLEASE PAGINATE - ENDIF -; - CALL CONIN ;GET CHAR TO CONTINUE - CPI 'C'-'@' ;^C - JZ RSTCPR ;RESTART CPR -PGBAK: - POP H ;RESTORE HL - RET -; -;Section 5E -;Command: SAVE -;Function: To save the contents of the TPA onto disk as a file -;Forms: -; SAVE -; Save specified number of pages (start at 100H) -; from TPA into specified file; is in DEC -; SAVE S -; Like SAVE above, but numeric argument specifies -; number of sectors rather than pages -; - IF ~RAS ;NOT FOR REMOTE-ACCESS SYSTEM -; -SAVE: - CALL NUMBER ;EXTRACT NUMBER FROM COMMAND LINE - MOV L,A ;HL=PAGE COUNT - MVI H,0 - PUSH H ;SAVE PAGE COUNT - CALL EXTEST ;TEST FOR EXISTENCE OF FILE AND ABORT IF SO - MVI C,16H ;BDOS MAKE FILE - CALL GRBDOS - POP H ;GET PAGE COUNT - JRZ SAVE3 ;ERROR? - XRA A ;SET RECORD COUNT FIELD OF NEW FILE'S FCB - STA FCBCR - CALL ADVAN ;LOOK FOR 'S' FOR SECTOR OPTION - INX D ;PT TO AFTER 'S' TOKEN - CPI SECTFLG - JRZ SAVE0 - DCX D ;NO 'S' TOKEN, SO BACK UP - DAD H ;DOUBLE IT FOR HL=SECTOR (128 BYTES) COUNT -SAVE0: - SDED CIBPTR ;SET PTR TO BAD TOKEN OR AFTER GOOD TOKEN - LXI D,TPA ;PT TO START OF SAVE AREA (TPA) -SAVE1: - MOV A,H ;DONE WITH SAVE? - ORA L ;HL=0 IF SO - JRZ SAVE2 - DCX H ;COUNT DOWN ON SECTORS - PUSH H ;SAVE PTR TO BLOCK TO SAVE - LXI H,128 ;128 BYTES PER SECTOR - DAD D ;PT TO NEXT SECTOR - PUSH H ;SAVE ON STACK - CALL DMASET ;SET DMA ADDRESS FOR WRITE (ADDRESS IN DE) - LXI D,FCBDN ;WRITE SECTOR - MVI C,15H ;BDOS WRITE SECTOR - CALL BDOSB ;SAVE BC - POP D ;GET PTR TO NEXT SECTOR IN DE - POP H ;GET SECTOR COUNT - JRNZ SAVE3 ;WRITE ERROR? - JR SAVE1 ;CONTINUE -SAVE2: - LXI D,FCBDN ;CLOSE SAVED FILE - CALL CLOSE - INR A ;ERROR? - JRNZ SAVE4 -SAVE3: - CALL PRNLE ;PRINT 'NO SPACE' ERROR -SAVE4: - CALL DEFDMA ;SET DMA TO 0080 - RET ;RESTART CPR -; -; Test File in FCB for existence, ask user to delete if so, and abort if he -; choses not to -; -EXTEST: - CALL SCANER ;EXTRACT FILE NAME - JNZ ERROR ;'?' IS NOT PERMITTED - CALL SLOGIN ;LOG IN SELECTED DISK - CALL SEARF ;LOOK FOR SPECIFIED FILE - LXI D,FCBDN ;PT TO FILE FCB - RZ ;OK IF NOT FOUND - PUSH D ;SAVE PTR TO FCB - CALL PRINTC - DB "Delete File",'?'+80H - CALL CONIN ;GET RESPONSE - POP D ;GET PTR TO FCB - CPI 'Y' ;KEY ON YES - JNZ RSTCPR ;RESTART IF NO - PUSH D ;SAVE PTR TO FCB - CALL DELETE ;DELETE FILE - POP D ;GET PTR TO FCB - RET -; - ENDIF ;RAS -; -;Section 5F -;Command: REN -;Function: To change the name of an existing file -;Forms: -; REN = Perform function -; - IF ~RAS ;NOT FOR REMOTE-ACCESS SYSTEM -; -REN: - CALL EXTEST ;TEST FOR FILE EXISTENCE AND RETURN - ; IF FILE DOESN'T EXIST; ABORT IF IT DOES - LDA TEMPDR ;SAVE CURRENT DEFAULT DISK - PUSH PSW ;SAVE ON STACK -REN0: - LXI H,FCBDN ;SAVE NEW FILE NAME - LXI D,FCBDM - LXI B,16 ;16 BYTES - LDIR - CALL ADVAN ;ADVANCE CIBPTR - CPI '=' ;'=' OK - JRNZ REN4 -REN1: - XCHG ;PT TO CHAR AFTER '=' IN HL - INX H - SHLD CIBPTR ;SAVE PTR TO OLD FILE NAME - CALL SCANER ;EXTRACT FILENAME.TYP TOKEN - JRNZ REN4 ;ERROR IF ANY '?' - POP PSW ;GET OLD DEFAULT DRIVE - MOV B,A ;SAVE IT - LXI H,TEMPDR ;COMPARE IT AGAINST CURRENT DEFAULT DRIVE - MOV A,M ;MATCH? - ORA A - JRZ REN2 - CMP B ;CHECK FOR DRIVE ERROR - MOV M,B - JRNZ REN4 -REN2: - MOV M,B - XRA A - STA FCBDN ;SET DEFAULT DRIVE - LXI D,FCBDN ;RENAME FILE - MVI C,17H ;BDOS RENAME FCT - CALL GRBDOS - RNZ -REN3: - CALL PRNNF ;PRINT NO FILE MSG -REN4: - JMP ERRLOG -; - ENDIF ;RAS -; -;Section 5G -;Command: USER -;Function: Change current USER number -;Forms: -; USER Select specified user number; is in DEC -; -USER: - CALL USRNUM ;EXTRACT USER NUMBER FROM COMMAND LINE - MOV E,A ;PLACE USER NUMBER IN E - CALL SETUSR ;SET SPECIFIED USER -RSTJMP: - JMP RCPRNL ;RESTART CPR -; -;Section 5H -;Command: DFU -;Function: Set the Default User Number for the command/file scanner -; (MEMLOAD) -;Forms: -; DFU Select Default User Number; is in DEC -; -DFU: - CALL USRNUM ;GET USER NUMBER - STA DFUSR ;PUT IT AWAY - JR RSTJMP ;RESTART CPR (NO DEFAULT LOGIN) -; -;Section 5I -;Command: JUMP -;Function: To Call the program (subroutine) at the specified address -; without loading from disk -;Forms: -; JUMP Call at ; is in HEX -; - IF ~RAS ;NOT FOR REMOTE-ACCESS SYSTEM -; -JUMP: - CALL HEXNUM ;GET LOAD ADDRESS IN HL - JR CALLPROG ;PERFORM CALL -; - ENDIF ;RAS -; -;Section 5J -;Command: GO -;Function: To Call the program in the TPA without loading -; loading from disk. Same as JUMP 100H, but much -; more convenient, especially when used with -; parameters for programs like STAT. Also can be -; allowed on remote-access systems with no problems. -; -;Form: -; GO -; - IF ~RAS ;ONLY IF RAS -; -GO: LXI H,TPA ;Always to TPA - JR CALLPROG ;Perform call -; - ENDIF ;END OF GO FOR RAS -; -;Section 5K -;Command: COM file processing -;Function: To load the specified COM file from disk and execute it -;Forms: -; -; -COM: - LDA FCBFN ;ANY COMMAND? - CPI ' ' ;' ' MEANS COMMAND WAS 'D:' TO SWITCH - JRNZ COM1 ;NOT , SO MUST BE TRANSIENT OR ERROR - LDA TEMPDR ;LOOK FOR DRIVE SPEC - ORA A ;IF ZERO, JUST BLANK - JZ RCPRNL - DCR A ;ADJUST FOR LOG IN - STA TDRIVE ;SET DEFAULT DRIVE - CALL SETU0D ;SET DRIVE WITH USER 0 - CALL LOGIN ;LOG IN DRIVE - JMP RCPRNL ;RESTART CPR -COM1: - LDA FCBFT ;FILE TYPE MUST BE BLANK - CPI ' ' - JNZ ERROR - LXI H,COMMSG ;PLACE DEFAULT FILE TYPE (COM) INTO FCB - LXI D,FCBFT ;COPY INTO FILE TYPE - LXI B,3 ;3 BYTES - LDIR - LXI H,TPA ;SET EXECUTION/LOAD ADDRESS - PUSH H ;SAVE FOR EXECUTION - CALL MEMLOAD ;LOAD MEMORY WITH FILE SPECIFIED IN CMD LINE - POP H ;GET EXECUTION ADDRESS - RNZ ;RETURN (ABORT) IF LOAD ERROR -; -; CALLPROG IS THE ENTRY POINT FOR THE EXECUTION OF THE LOADED -; PROGRAM;ON ENTRY TO THIS ROUTINE, HL MUST CONTAIN THE EXECUTION -; ADDRESS OF THE PROGRAM (SUBROUTINE) TO EXECUTE -; -CALLPROG: - SHLD EXECADR ;PERFORM IN-LINE CODE MODIFICATION - CALL DLOGIN ;LOG IN DEFAULT DRIVE - CALL SCANER ;SEARCH COMMAND LINE FOR NEXT TOKEN - LXI H,TEMPDR ;SAVE PTR TO DRIVE SPEC - PUSH H - MOV A,M ;SET DRIVE SPEC - STA FCBDN - LXI H,FCBDN+10H ;PT TO 2ND FILE NAME - CALL SCANX ;SCAN FOR IT AND LOAD IT INTO FCBDN+16 - POP H ;SET UP DRIVE SPECS - MOV A,M - STA FCBDM - XRA A - STA FCBCR - LXI D,TFCB ;COPY TO DEFAULT FCB - LXI H,FCBDN ;FROM FCBDN - LXI B,33 ;SET UP DEFAULT FCB - LDIR - LXI H,CIBUFF -COM4: - MOV A,M ;SKIP TO END OF 2ND FILE NAME - ORA A ;END OF LINE? - JRZ COM5 - CPI ' ' ;END OF TOKEN? - JRZ COM5 - INX H - JR COM4 -; -; LOAD COMMAND LINE INTO TBUFF -; -COM5: - MVI B,0 ;SET CHAR COUNT - LXI D,TBUFF+1 ;PT TO CHAR POS -COM6: - MOV A,M ;COPY COMMAND LINE TO TBUFF - STAX D - ORA A ;DONE IF ZERO - JRZ COM7 - INR B ;INCR CHAR COUNT - INX H ;PT TO NEXT - INX D - JR COM6 -; -; RUN LOADED TRANSIENT PROGRAM -; -COM7: - MOV A,B ;SAVE CHAR COUNT - STA TBUFF - CALL CRLF ;NEW LINE - CALL DEFDMA ;SET DMA TO 0080 - CALL SETUD ;SET USER/DISK -; -; EXECUTION (CALL) OF PROGRAM (SUBROUTINE) OCCURS HERE -; -EXECADR EQU $+1 ;CHANGE ADDRESS FOR IN-LINE CODE MODIFICATION - CALL TPA ;CALL TRANSIENT - CALL DEFDMA ;SET DMA TO 0080, IN CASE - ;PROG CHANGED IT ON US - CALL SETU0D ;SET USER 0/DISK - CALL LOGIN ;LOGIN DISK - JMP RESTRT ;RESTART CPR -; -; TRANSIENT LOAD ERROR -; -COM8: - POP H ;CLEAR RETURN ADDRESS - CALL RESETUSR ;RESET CURRENT USER NUMBER - ; RESET MUST BE DONE BEFORE LOGIN -ERRLOG: - CALL DLOGIN ;LOG IN DEFAULT DISK -ERRJMP: - JMP ERROR -; -;Section 5L -;Command: GET -;Function: To load the specified file from disk to the specified address -;Forms: -; GET Load the specified file at the specified page; -; is in HEX -; - IF ~RAS ;NOT FOR REMOTE-ACCESS SYSTEM -; -GET: - CALL HEXNUM ;GET LOAD ADDRESS IN HL - PUSH H ;SAVE ADDRESS - CALL SCANER ;GET FILE NAME - POP H ;RESTORE ADDRESS - JRNZ ERRJMP ;MUST BE UNAMBIGUOUS -; -; FALL THRU TO MEMLOAD -; - ENDIF ;RAS -; -; LOAD MEMORY WITH THE FILE WHOSE NAME IS SPECIFIED IN THE COMMAND LINE -; ON INPUT, HL CONTAINS STARTING ADDRESS TO LOAD -; -MEMLOAD: - CALL MLOAD ;USER MEMORY LOAD SUBROUTINE - PUSH PSW ;SAVE RETURN STATUS - CALL RESETUSR ;RESET USER NUMBER - POP PSW ;GET RETURN STATUS - RET - -; -; MEMORY LOAD SUBROUTINE -; EXIT POINTS ARE A SIMPLE RETURN WITH THE ZERO FLAG SET IF NO ERROR, -; A SIMPLE RETURN WITH THE ZERO FLAG RESET (NZ) IF MEMORY FULL, OR A JMP TO -; COM8 IF COM FILE NOT FOUND -; -MLOAD: - SHLD LOADADR ;SET LOAD ADDRESS - CALL GETUSR ;GET CURRENT USER NUMBER - STA TMPUSR ;SAVE IT FOR LATER - STA TSELUSR ;TEMP USER TO SELECT -; -; MLA is a reentry point for a non-standard CP/M Modification -; This is the return point for when the .COM (or GET) file is not found the -; first time, Drive A: is selected for a second attempt -; -MLA: - CALL SLOGIN ;LOG IN SPECIFIED DRIVE IF ANY - CALL OPENF ;OPEN COMMAND.COM FILE - JRNZ MLA1 ;FILE FOUND - LOAD IT -; -; ERROR ROUTINE TO SELECT USER 0 IF ALL ELSE FAILS -; -DFUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE - MVI A,DEFUSR ;GET DEFAULT USER -TSELUSR EQU $+1 ;MARK IN-THE-CODE VARIABLE - CPI DEFUSR ;SAME? - JRZ MLA0 ;JUMP IF - STA TSELUSR ;ELSE PUT DOWN NEW ONE - MOV E,A - CALL SETUSR ;GO SET NEW USER NUMBER - JR MLA ;AND TRY AGAIN -; -; ERROR ROUTINE TO SELECT DRIVE A: IF DEFAULT WAS ORIGINALLY SELECTED -; -MLA0: - LXI H,TEMPDR ;GET DRIVE FROM CURRENT COMMAND - XRA A ;A=0 - ORA M - JNZ COM8 ;ERROR IF ALREADY DISK A: - MVI M,1 ;SELECT DRIVE A: - JR MLA -; -; FILE FOUND -- PROCEED WITH LOAD -; -MLA1: -LOADADR EQU $+1 ;MEMORY LOAD ADDRESS (IN-LINE CODE MOD) - LXI H,TPA ;SET START ADDRESS OF MEMORY LOAD -ML2: - MVI A,ENTRY/256-1 ;GET HIGH-ORDER ADR OF JUST BELOW CPR - CMP H ;ARE WE GOING TO OVERWRITE THE CPR? - JRC PRNLE ;ERROR IF SO - PUSH H ;SAVE ADDRESS OF NEXT SECTOR - XCHG ;... IN DE - CALL DMASET ;SET DMA ADDRESS FOR LOAD - LXI D,FCBDN ;READ NEXT SECTOR - CALL READ - POP H ;GET ADDRESS OF NEXT SECTOR - JRNZ ML3 ;READ ERROR OR EOF? - LXI D,128 ;MOVE 128 BYTES PER SECTOR - DAD D ;PT TO NEXT SECTOR IN HL - JR ML2 -; -ML3: - DCR A ;LOAD COMPLETE - RZ ;OK IF ZERO, ELSE FALL THRU TO PRNLE -; -; LOAD ERROR -; -PRNLE: - CALL PRINTC - DB "Ful",'l'+80H - MVI A,1 ;SET NON-ZERO TO INDICATE ERROR - ORA A ;SET FLAG - RET -; - END diff --git a/branches/s100/Source/zcprw.asm b/branches/s100/Source/zcprw.asm deleted file mode 100644 index ed5c2838..00000000 --- a/branches/s100/Source/zcprw.asm +++ /dev/null @@ -1,64 +0,0 @@ -; -;================================================================================================== -; WRAPPER FOR ZCPR FOR N8VEM PROJECT -; WAYNE WARTHEN - 2011-01-10 -;================================================================================================== -; -; THE FOLLOWING MACROS DO THE HEAVY LIFTING TO MAKE THE ZCPR SOURCE -; COMPATIBLE WITH TASM -; -;#DEFINE DS .DS -;#DEFINE ds .ds -#DEFINE DS .FILL -#DEFINE ds .fill -#DEFINE TITLE .TITLE -#DEFINE title .title -#DEFINE EQU .EQU -#define equ .equ -#DEFINE NAME \; -#DEFINE PAGE .PAGE -#DEFINE page .page -#DEFINE CSEG .CSEG -#DEFINE ORG .ORG -#DEFINE org .org -#DEFINE END .END -#DEFINE IF .IF -#DEFINE if .if -#DEFINE ELSE .ELSE -#DEFINE else .else -#DEFINE ENDIF .ENDIF -#DEFINE endif .endif -#DEFINE DEFB .DB -#DEFINE defb .db -#DEFINE DEFW .DW -#DEFINE defw .dw -#DEFINE DEFL .EQU -#DEFINE defl .equ -#DEFINE DEFS .DB -#DEFINE defs .db -#DEFINE DW .DW -#DEFINE dw .dw -#DEFINE DB .DB -#DEFINE db .db -#DEFINE END .END -#DEFINE end .end -; -; Add some Z80 instructions -; -#ADDINSTR JR * 18 2 R1 1 -#ADDINSTR JRC * 38 2 R1 1 -#ADDINSTR JRNC * 30 2 R1 1 -#ADDINSTR JRZ * 28 2 R1 1 -#ADDINSTR JRNZ * 20 2 R1 1 -#ADDINSTR LDIR "" B0ED 2 NOP 1 -#ADDINSTR DJNZ * 10 2 R1 1 -#ADDINSTR LDED * 5BED 4 NOP 1 -#ADDINSTR SDED * 53ED 4 NOP 1 -; -; NOW INCLUDE THE MAIN SOURCE -; -#INCLUDE "zcpr.asm" -; - .FILL ((CPRLOC + 0800H) - $),055H -; - .END \ No newline at end of file diff --git a/branches/s100/Source/zsdos-gp.z80 b/branches/s100/Source/zsdos-gp.z80 deleted file mode 100644 index 320b0b56..00000000 --- a/branches/s100/Source/zsdos-gp.z80 +++ /dev/null @@ -1,3174 +0,0 @@ -;WW - Globally changed dquotes to squotes for all strings -;WW - Globally changed NOT, AND, OR in conditional assembly to ~, &, | -; -;**************************************************************************** -; Z S D O S -; A CP/M 2.2 compatible replacement Basic Disk Operating System (BDOS) -; -; Copyright (C) 1986,7,8 by: -; -; Harold F. Bower and Cameron W. Cotrill -; -; 7914 Redglobe Ct. 2160 N.W. 159th Place -; Severn, MD 21144-1048 Beaverton, OR 97006 -; USA. USA. -; -; HalBower@worldnet.att.net ccotrill@symantec.com -; -; This program is free software; you can redistribute it and/or modify -; it under the terms of the GNU General Public License as published by -; the Free Software Foundation; either version 2 of the License, or -; (at your option) any later version. -; -; This program is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -; General Public License (file LICENSE.TXT) for more details. -; -; You should have received a copy of the GNU General Public License -; along with this program; if not, write to the Free Software -; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -;--------------------------------------------------------------------------- -; ZSDOS is a CP/M 2.2 compatable BDOS replacement that contains numerous -; enhancements. It is based on P2DOS 2.1 by HAJ Ten Brugge and revisions -; to P2DOS made by Harold F. Bower, Benjamin Ho, and Cameron W. Cotrill. -; Several good ideas from both CP/M Plus(tm) and ZRDOS(tm) have been added. -; The authors wish to thank Bridger Mitchell of Plu*Perfect Systems for -; suggesting we put our heads together, for reviewing the efforts, and for -; suggesting better methods for coding some sections. Thanks also to Joe -; Wright of Alpha Systems for his review and suggestions, as well as -; squeezing a few more bytes for us. - -; Support for Plu*Perfect'a BackGrounder ii(tm) and ZDS DateStamper(tm) is -; included, as well as support for ZCPR/BGii WHEEL and PATH. -; ZSDOS is compatable with NZCOM by Joe Wright of Alpha Systems. - -; ZSDOS is designed for Z80 compatible processors ONLY!!! -; ZSDOS is coded to run in Z280 protected mode and may be ROMmed. - -; LEGAL DEPARTMENT: P2DOS was written by H.A.J. Ten Brugge, ZSDOS -; modifications were by Cameron W. Cotrill and Harold F. Bower. -; ZDDOS modifications were done by Carson Wilson, Cameron W. Cotrill -; and Harold F. Bower. - -; No author assumes responsibility or liability in the use of this -; program or any of its support utilities. - -; P2DOS is Copyright (C) 1985 by H.A.J. Ten Brugge - All Rights Reserved -; H.A.J. Ten Brugge -; F. Zernikestraat 207 -; 7553 EC Hengelo -; Netherlands -; Permission to use P2DOS code in ZSDOS granted to Harold F. Bower and -; Cameron W. Cotrill in letter 28 March 1988 - -; Code sections marked (bm) are revisions suggested by Bridger Mitchell. -; Code sections marked (bh) are from SUPRBDOS mods to P2DOS by Benjamin Ho. -; Code sections marked (crw) are revisions to support internal datestamper -; and are Copyright (C) 1988 by Carson Wilson. - -; NOTES: Backgrounder ii and DateStamper are trademarks of Plu*Perfect -; Systems. CP/M is a trademark of Digital Research, Incorporated. -; ZRDOS is a trademark of Echelon, Incorporated. - PAGE -;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -; Version 1.2a, 11/04/89 -; Assemble with : SLR Z80ASMP or ZMAC -; Revisions: -; 11/04/89 Moved home call to rddir so bios hostbuf always -; updated before dir read. -; 07/18/89 Fixed tderr routine in ZDDOS so return codes not -; CWC altered from tderr unless called from 102 or 103. -; 06/20/89 Fixed bug in F10 ^R that output 256 spaces if ^R -; CWC entered with tab counter =0. -;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - -; WW - MOVED TO N8VEM WRAPPER -; MACLIB ZSDOS.LIB ; Get initialization code - -RAMLOW EQU 0000H ; Start address memory - - CSEG -ZSDOS EQU $ ; Start address ZSDOS - - IF ZRL - COMMON /_BIOS_/ -BIOS: - CSEG - ELSE -BIOS EQU ZSDOS+0E00H - ENDIF - -BOOT EQU BIOS+0000H ; Cold Boot -WBOOT EQU BIOS+0003H ; Warm Boot -CONST EQU BIOS+0006H ; Console Status -CONIN EQU BIOS+0009H ; Console Input -CONOUT EQU BIOS+000CH ; Console Output -LIST EQU BIOS+000FH ; List Output -PUNCH EQU BIOS+0012H ; Punch Output -READER EQU BIOS+0015H ; Reader Input -HOME EQU BIOS+0018H ; Home Disk -SELDSK EQU BIOS+001BH ; Select Disk -SETTRK EQU BIOS+001EH ; Select Track -SETSEC EQU BIOS+0021H ; Select Sector -SETDMA EQU BIOS+0024H ; Set DMA Address -READ EQU BIOS+0027H ; Read 128 Bytes -WRITE EQU BIOS+002AH ; Write 128 Bytes -LISTST EQU BIOS+002DH ; List Status -SECTRN EQU BIOS+0030H ; Sector Translation - -; Internal Definitions - IF ZSDOS11 -VERMAJ EQU 1 ; Major version number -VERMIN EQU 1 ; Minor version number - ELSE -VERMAJ EQU 1 -VERMIN EQU 2 - ENDIF ;Zs -VERS EQU VERMAJ*10H+VERMIN - -CONTC EQU 03H ; Key to generate warm boot -CONTH EQU 08H ; Backspace -TAB EQU 09H ; Tab -LF EQU 0AH ; Line feed -CR EQU 0DH ; Carriage return -CONTP EQU 10H ; Set/reset print flag -CONTR EQU 12H ; Retype line -CONTS EQU 13H ; Stop console output -CONTX EQU 18H ; Delete line (backspaces) -CONTU EQU 15H ; Same as Control-X -RUBOUT EQU 7FH ; Delete last char - -MAXEXT EQU 1FH ; Maximum extent number -MAXMOD EQU 3FH ; Maximum data module number - -TDCKSM EQU 91H ; CHECKSUM OF !!!TIME&.DAT - -; Attribute Bit Definitions - -PUBATT EQU 2 ; Public attribute offset -PSFATT EQU 7 ; Public/system file (internal only) -WHLATT EQU 8 ; Wheel protect attribute offset -ROATT EQU 9 ; Read only attribute offset -SYSATT EQU 10 ; System attribute offset -ARCATT EQU 11 ; Archive attribute offset - -; FCB POSITION EQUATES - -FCBEXT EQU 12 ; Extent number -FCBUSR EQU 13 ; User valid at offset 13 if set (internal) -FCBMOD EQU 14 ; Data module number - D7 used as unmod flag -FCBREC EQU 15 ; Record number -NXTREC EQU 32 ; Next record number - PAGE -;************************************************************** -;* Z S D O S P r o g r a m S t a r t * -;************************************************************** - -; WARNING!! Do NOT change labels or sequences of ZSDOS through ZSDOS+25H -; ID string added for easy identification in running system (hfb) - - IF ZS - DEFB "ZSDOS " ; Used in CP/M for serial number. these bytes - ELSE ; are patched by INSTALOS to contain the serial - DEFB "ZDDOS " ; Number of the running system so MOVCPM can - ENDIF ; still be used without problems. - -; ZSDOS Entry Point - -START: JP ENTRY ; Jump to start of program code - -; CP/M 2.2 Compatable Error Vector Table - -STBDSC: DEFW ERROR ; Bad sector message -STSEL: DEFW ERROR ; Select error -STRO: DEFW ERROR ; Drive read only -SFILRO: DEFW ERROR ; File read only - -; External Path Name - -PATH: DEFW PATHAD ; Path address for file open, 0 if no path - -; Wheel Byte Pointer - -WHEEL: DEFW WHLADR ; Address of wheel byte, 0 if none - -; User configuration byte - -FLAGS: DEFB FLGBITS ; Flag byte set in zsdos.lib - -; Dispatch table for time/date stamp routines - -; ZSDOS uses all vectors in this table as indicated. ZDDOS uses all but -; STUPDV, GETSTV, and PUTSTV. STCRV is used to store the address of the -; stamp for ZDDOS, thus allowing ZSCONFIG to enable and disable stamping -; of Last Access and Modify. - -GSTIME: DEFW DOTDER ; Address of get/set time/date routine (hfb) - IF ZS -STLAV: DEFW DOTDER ; Address of stamp last access routine -STCRV: DEFW DOTDER ; Address of stamp create routine -STUPDV: DEFW DOTDER ; Address of stamp modify routine - ELSE -STLAV: DEFW STIME ; Address of stamp last access routine -STCRV: DEFW STIME ; Address of stamp create routine -STUPDV: DEFW STIME ; Address of stamp modify routine - ENDIF -GETSTV: DEFW DOTDER ; Address of get stamp routine -PUTSTV: DEFW DOTDER ; Address of set stamp routine - DEFW DOTDER ; Dummy vector to disable with ZSCONFIG -UNLOAD: DEFW 0 ; Pointer to remove Time Stamp routine - - PAGE -;******************************************************** -;* Z S D O S L o w R A M D a t a * -;******************************************************** - -; RAM has been moved down here to an area that is compatable with ZRDOS per -; suggestion by Hal Bower. The actual addresses used are NOT compatable with -; ZRDOS. - -; Due to ZSDOS's smaller RAM area, any program that saves RAM in accordance -; with ZRDOS's specifications for re-entry into BDOS should work under ZSDOS -; without problems. Some code will be saved also, as well as the Flag Byte, -; but this should be no problem for IOP'S. - -; The Write Protect, Login, and Hard Disk Login Vectors are kept at the top of -; ZSDOS, as they must reflect the current status of the Disk System and hence -; should NOT be saved with other system variables Under ANY Circumstance! - - IF ROM - DSEG - ENDIF -BGLORAM: -;-------------------------------------------------------------------- -; The following locations MUST remain in EXACTLY this order - -TABCNT: DEFB 0 ; Tab counter -TABCX1: DEFB 0 ; Temporary Tab counter (used by RDBUF) -;-------------------------------------------------------------------- - -FCONTP: DEFB 0 ; List enable flag (Control-P) - used by BGii -LASTCH: DEFB 0 ; Last character - used by BGii - -;-------------------------------------------------------------------- -; The following locations MUST remain in EXACTLY this order - -USER: DEFB 0 ; User number - used by BGii -DEFDRV: DEFB 0 ; Default drive number - used by BGii and DS -DRIVE: DEFB 0 ; Drive number -;-------------------------------------------------------------------- - -FCB0: DEFB 0 ; FCB byte 0 - -BGHIRAM: -DMA: DEFW 0080H ; DMA address - -TRANS: DEFW 0 ; Translation vector -TEMP0: DEFW 0 ; Number of files on drive - - -DIRBUF: DEFW 0 ; Directory buffer pointer - used by bgii -IXP: DEFW 0 ; Disk parameter block -CSV: DEFW 0 ; Check sum pointer -ALV: DEFW 0 ; Allocation vector pointer - -;-------------------------------------------------------------------- -; The following locations MUST remain in EXACTLY this order -; Copy of DPB for Current Drive - -DPBOF EQU $-ZSDOS ; Value needed by ZSDOS - -MAXSEC: DEFW 0 ; Number of sectors/track -NBLOCK: DEFB 0 ; Block shift -NMASK: DEFB 0 ; Mask number of blocks -NEXTND: DEFB 0 ; Extent mask -MAXLEN: DEFW 0 ; Maximum block number-1 -NFILES: DEFW 0 ; Maximum number of files-1 -NDIR0: DEFB 0 ; First two entries ALV buffer - DEFB 0 ; ..(NDIR1) -NCHECK: DEFW 0 ; Number of checksum entries -NFTRK: DEFW 0 ; First track number -;-------------------------------------------------------------------- -FUNCT: DEFB 0 ; Function number -PEXIT: DEFW 0 ; Exit code -;-------------------------------------------------------------------- -; The following locations MUST remain in EXACTLY this order - -FLDRV: DEFB 0 ; Drive select used flag -RDWR: DEFB 0 ; Read/write flag -SEARQU: DEFB 0 ; Search question mark used -SEARPU: DEFB 0 ; Search public file -;-------------------------------------------------------------------- -RECDIR: DEFW 0 ; Record directory (checksum) -FILCNT: DEFW 0 ; File counter -SECPNT: DEFB 0 ; Sector pointer -SUBFLG: DEFB 0 ; Submit flag (reset disk command) - -DCOPY: DEFW 0 ; Copy address FCB -SEAREX: DEFB 0 ; Exit code search -SEARNB: DEFB 0 ; Search number of bytes -ERMODE: DEFB 0 ; BDOS error mode - -ARWORD: DEFW 0 ; De argument on entry - used for BGii -DEVAL: DEFW 0 ; Return value for DE reg -SPSAVE: DEFW 0 ; Stack pointer location - IF ZS - DEFB "ZSDOS 1.1 Copyri" - ELSE - DEFB "ZDDOS 1.1 Copyri" - ENDIF - DEFB "ght (c) 1987,88 " - DEFB " C.W.Cotrill & H" - DEFB ".F.Bow" -IXSAVE: DEFB "er" ; User's IX register -ZSDOSS: ; ZSDOS stack - -BGRAMTOP EQU ZSDOSS - PAGE - CSEG -;********************************************************************** -;* Z S D O S e n t r y p o i n t * -;********************************************************************** - -ENTRY: XOR A ; Clear A - LD B,A ; For later 16 bit adds - LD L,A - LD H,A ; Set HL to zero - LD (PEXIT),HL ; Clear exit code - LD (FLDRV),HL ; Reset drive select and R/W flags - LD (SPSAVE),SP ; Save stack pointer - LD SP,ZSDOSS ; Get internal stack pointer - PUSH IX ; Save index register on our stack - PUSH DE ; Save parameter register - POP IX ; Get it back in IX - LD (ARWORD),IX ; Save in memory for BGii - IF ~PICKEY - LD (DEVAL),IX ; ..and for non-file access returns - ENDIF - LD HL,DOSEXIT ; Get exit address ZSDOS - PUSH HL ; Save it on stack to return from ZSDOS - LD A,C ; Get function code - B reg = 0 - LD (FUNCT),A ; Save it for later use - CP 12 ; Is it a non-disk function? - JR C,ENTRY0 ; ..jump if so - CP MAXCMD ; Cmnd < Maximum Command Number (48)? - JR C,ENTRY1 ; ..jump if disk function - -; Extended function scanner for added functions - - CP 98 ; Is it less than Cmd98? - RET C ; ..return if so - CP 103+1 ; Is it greater than Cmd103? - RET NC ; ..quit if so - SUB 98-MAXCMD ; Rework so 98-->49..103-->54 - LD C,A ; Save reworked function # - ; ..fall thru to entry0.. - -; If Non-disk Function (ie Function # less than 12), push the address of -; the SAVEA routine on the Stack (save A reg as return code). Saves -; code in Console Routines, as simple RET can be used in most cases. - -ENTRY0: LD HL,SAVEA - PUSH HL ; Vector return thru A reg save -ENTRY1: LD HL,CTABLE ; Load table - ADD HL,BC ; Add - ADD HL,BC ; Add twice to get word value - LD A,(HL) ; Get LSB - INC HL ; Pointer to MSB - LD H,(HL) ; Get MSB - LD L,A ; Save LSB in L - -; Copy byte argument into A and C to simplify Function calls. This allows -; direct BIOS jumps for several functions with resulting code savings. - - LD C,E ; Place arg in C for BIOS - LD A,E ; And in A for others - JP (HL) ; Jump to routine - - PAGE -;****************************************************** -;* C O M M A N D T A B L E * -;****************************************************** -CTABLE: - IF ROM - DEFW RAMINI ; Set up RAM - ELSE - DEFW ERROR5 ; Warm boot (BIOS) with ERMODE clear - ENDIF - DEFW CMND01 ; Console input - DEFW WRCON ; Console output - DEFW READER ; Reader input (BIOS) - DEFW PUNCH ; Punch output (BIOS) - DEFW LIST ; List output (BIOS) - DEFW CMND06 ; Direct console I/O - DEFW CMND07 ; Get I/O byte - DEFW CMND08 ; Set I/O byte - DEFW CMND09 ; Print string - DEFW CMND10 ; Read console buffer - DEFW CMND11 ; Get console status - DEFW CMND12 ; Return version number - DEFW CMND13 ; Reset disk system - DEFW CMND14 ; Select disk - DEFW CMND15 ; Open file - DEFW CMND16 ; Close file - DEFW CMND17 ; Search for first - DEFW CMND18 ; Search for next - DEFW CMND19 ; Delete file - DEFW CMND20 ; Read sequential - DEFW CMND21 ; Write sequential - DEFW CMND22 ; Make file - DEFW CMND23 ; Rename file - DEFW CMND24 ; Return login vector - DEFW CMND25 ; Return current disk - DEFW CMND26 ; Set DMA address - DEFW CMND27 ; Get address allocation vector - DEFW CMND28 ; Write protect disk - DEFW CMND29 ; Get R/O vector - DEFW CMND30 ; Set file attributes - DEFW CMND31 ; Get address disk parameter header (DPH) - DEFW CMND32 ; Get/set user code - DEFW CMND33 ; Read random - DEFW CMND34 ; Write random - DEFW CMND35 ; Compute file size - DEFW CMND36 ; Set random record - DEFW CMND37 ; Reset multiple drive - DEFW DUMMY ; Function 38 (unused) - DEFW CMND39 ; Return fixed disk login vector - DEFW CMND40 ; Write random with zero fill - DEFW DUMMY ; Function 41 (unused) - DEFW DUMMY ; Function 42 (unused) - DEFW DUMMY ; Function 43 (unused) - DEFW DUMMY ; Function 44 (unused) - DEFW CMND45 ; Set Error Mode - DEFW DUMMY ; Function 46 (unused) - DEFW CMND47 ; Return DMA - DEFW CMND48 ; Return DOS version - -MAXCMD EQU ($-CTABLE)/2 ; Jww - - DEFW CMD98 ; Get Time ; 49 - DEFW CMD99 ; Set Time ; 50 - DEFW CMD100 ; Get Flags ; 51 - DEFW CMD101 ; Set Flags ; 52 - DEFW CMD102 ; Get Stamp ; 53 - DEFW CMD103 ; Put Stamp ; 54 - - PAGE -;****************************************************** -;* N o n - D i s k F u n c t i o n s * -;****************************************************** - - IF ROM - -; Initialize RAM in Data Segment (ROM Systems Only) - -RAMINI: LD B,SPSAVE-BGLORAM ; Size of low RAM data segment (less stack) - XOR A - LD HL,BGLORAM ; Start of RAM -RAMIN1: LD (HL),A ; Clear first byte - INC HL - DJNZ RAMIN1 ; And everything else - IF ZS ; Need Internal path if ZSDOS - LD HL,IPATH ; Point to start of Internal Path - LD B,HDLOG+2-IPATH-1 ; and fill high mem less first byte of path - LD (HL),01 ; Set path to Drive = A - INC HL ; ..point to user and Null (Sets user=0) - ELSE ; No Path if ZDDOS - LD HL,TDFVCT - LD B,HDLOG+2-TDFVCT ; Now high RAM - ENDIF ;Zs -RAMIN2: LD (HL),A - INC HL - DJNZ RAMIN2 - LD HL,RAMLOW+80H ; Default DMA buffer - LD (DMA),HL ; And save it - RST 00 ; Now BIOS warm boot - ENDIF ; Rom - -;..... -; I/O Routines - -; ZSDOS Console Input. Read character from Console and Echo -; If Char=CR,LF,TAB,CONTH or >=Space - -CMND01: CALL GETCH ; Get character (and test it jww) - RET C ; Less than space, exit -PUTCH: PUSH HL ; Save regs for other calls - CALL WRCON ; Echo character - POP HL - RET - -; Direct Console Input/Output -; Call with Char in C and E - Enhanced to CP/M-3 Spec -; Checks ZSDOS typeahead for reliable console I/O under all conditions -; as per a suggestion by Bridger Mitchell. - -CMND06: INC E ; Test if get char if avail - JR Z,DCIO1 ; Yes do input - INC E ; Test for 0FEH - JR Z,DCIO2 ; Yes, get status - INC E ; Test for 0FDH - JR Z,GETCH ; Yes, wait for input char - JP CONOUT ; Else print char - -DCIO2: LD A,(LASTCH) ; Check for buffered char - OR A - LD A,0001B ; ..preset ready - CALL Z,CONST ; Get console status - AND A ; Test it - RET ; And return it to caller - -DCIO1: CALL DCIO2 ; Get console status - RET Z ; Exit if no character present - ; Else fall thru -; Get Character from Console - -GETCH: LD HL,LASTCH ; Check ZSDOS type ahead for char - LD A,(HL) - LD (HL),0 ; Reset last character - OR A ; ..set flags - CALL Z,CONIN ; Get character (and test it jww) - -; Test Character -; Exit Carry=0: CR,LF,TAB,CONTH or >= Space -; Carry=1: All other Characters - - CP CR ; Is it a carriage return? - RET Z ; ..return if so - CP LF ; Is it a line feed? - RET Z ; ..return if so - CP TAB ; Is it a tab? - RET Z ; ..return if so - CP CONTH ; Is it a backspace? - RET Z ; ..return if so - CP ' ' ; Test >=space - RET ; ..and return to caller - -; Set I/O Status Byte - -CMND08: LD (RAMLOW+0003H),A ; And save it in RAM and fall through - -; Get I/O Status Byte - -CMND07: LD A,(RAMLOW+0003H) ; Get I/O byte from RAM - RET - -; Buffered Console Read - -CMND10: LD A,(TABCNT) - LD (TABCX1),A ; Save start tab position - INC DE - XOR A - LD (DE),A ; Set char count to zero - INC DE ; Point to actual buffer start - -RDBUF1: PUSH DE ; Save buffer pointer - CALL GETCH ; Get next byte from user - POP DE - LD HL,RDBUF1 - PUSH HL ; Return address to stack - LD HL,(ARWORD) - LD C,(HL) ; Put buffer length in C - INC HL ; And point to current length - - CP CR - IF CTLREN - JR Z,JZRBX ; Exit if CR - ELSE - JR Z,RDBUFX - ENDIF ;Ctlren - - CP LF - IF CTLREN -JZRBX: JP Z,RDBUFX ; ..or LF - ELSE - JR Z,RDBUFX - ENDIF ;Ctlren - ;..Not CR or LF, so fall thru to next test - -; Delete Character from Buffer -; RUB, Backspace, CR, LF are NEVER in the Buffer - -RDBUF2: CP RUBOUT ; Delete char? - JR Z,DOBACK ; ..jump if so - CP CONTH ; Control-H also deletes - JR NZ,RDBUF3 ; Skip to next test if no delete - -DOBACK: LD A,(HL) - AND A ; Test if attempting del from empty line - RET Z ; ..Exit if so -DOBAK0: DEC DE ; Back up to last character - DEC (HL) ; Erase from buffer - PUSH DE ; Save buffer pointer - LD B,(HL) ; Get new char count - INC HL ; Point to first char - EX DE,HL - LD HL,TABCNT - LD C,(HL) ; Save current Tab count - INC HL - LD A,(HL) ; Get starting Tab position - DEC HL - LD (HL),A ; Init the counter - INC B ; Insure non-zero - JR DOBAK2 ; Jump to done test - -DOBAK1: LD A,(DE) ; Get char from buffer - CALL WRCON2 ; Counts chars - INC DE -DOBAK2: DJNZ DOBAK1 ; Continue count until done - LD A,C ; Get prior tab count - SUB (HL) ; Get diff between new and old - LD B,A ; Set up as count - LD (HL),C ; Restore prior count - POP DE ; Restore buffer pointer - -; Delete B Characters from Console - - PUSH DE ; Save pointer -DOBAK5: LD C,CONTH - PUSH BC ; Save counter from destruction - CALL CONOUT - LD C,' ' - CALL CONOUT ; Output backspace,space to CON: only - LD A,CONTH - CALL WRCON ; Now backspace CON:, counter, and printer - POP BC ; Restore counter - DJNZ DOBAK5 ; Loop until all done - POP DE ; Restore pointer - RET - -; Erase Buffer - -RDBUF3: CP CONTU ; Test erase line - JR Z,ERALIN ; Do it if so - CP CONTX - JR NZ,RDBUF4 ; Skip to next test if no erase line - -ERALIN: XOR A - OR (HL) ; Line empty? - RET Z ; Exit if so - PUSH HL - CALL DOBAK0 ; Else delete another (skip empty check) - POP HL - JR ERALIN - -RDBUF4: ; If CTL-R=True, do following code, else bypass - IF CTLREN - CP CONTR ; If ^R, type clean buffer version on console - JR NZ,RDBUF5 - PUSH HL ; Save pointer to buffer length - CALL CROUT ; Do CR/LF - LD HL,TABCNT - LD (HL),0 ; Init Tab count - INC HL - LD B,(HL) ; And get Tab offset count - LD A,' ' - inc b ; [1.1] insure nz value - jr rety1a ; [1.1] so case of lh side of screen ok -RETYP1: CALL WRCON ; Space off start of line -rety1a: DJNZ RETYP1 - POP HL ; Point to buffer length - LD B,(HL) ; Get how many chars to print - INC HL ; Restore buffer pointer - EX DE,HL ; Put buffer pointer in DE - INC B ; Comp for first DJNZ - JR RETYP3 ; Skip to done test -RETYP2: LD A,(DE) ; Get char from buffer - CALL WRCTL ; Output it - INC DE ; Bump pointer -RETYP3: DJNZ RETYP2 ; Loop until done - RET - ENDIF ; Ctlren - -; Toggle Line Printer Echo - -RDBUF5: CP CONTP ; Toggle printer? - JR NZ,RDBUF6 ; Next test if not - LD HL,FCONTP - LD A,(HL) ; Get printer echo flag - CPL ; Toggle it - LD (HL),A ; Put back - RET - -; Check if Control-C is First char in BUFF and Exit if so - -RDBUF6: LD (DE),A ; Put character in buffer - PUSH HL - CALL WRCTL ; Echo the character - POP HL - INC (HL) ; Increment the character count - - LD A,(HL) ; Get current length - CP C ; Test against buffer size - JR Z,RDBUFX - DEC A ; Set Z flag for first character - LD A,(DE) ; Get the character back - INC DE ; ..and bump the pointer - RET NZ ; Return if not the first character - CP CONTC ; Possible user abort? - RET NZ ; ..return if not - JP ERROR5 ; Else jump to error reset exit - -; Done with Read Console Buffer Function - -RDBUFX: POP HL ; Clear RDBUF1 return address - LD A,CR - JR WRCON ; ..and echo a CR - -; Print Control Character as '^X' - -WRCTL: CP ' ' ; Test if control char - JR NC,WRCON ; Not, send it out - CP TAB ; Test if Tab - JR Z,WRCON0 ; It is, so expand with spaces - PUSH AF ; Save char - LD A,'^' ; Output a karet - CALL WRCON1 ; No need for Tab test here - POP AF - ADD A,40H ; Convert to printable - ; And fall thru to WRCON - -; Output char with List Echo, Tab Expansion (Function 2) - -WRCON: CP TAB ; Is it a Tab? - JR NZ,WRCON1 ; ..jump if not -WRCON0: LD A,' ' ; Expand Tab with spaces - CALL WRCON1 ; Write space - LD A,(TABCNT) ; Get Tab count - AND 7 ; Test if done - JR NZ,WRCON0 ; No then repeat - LD A,TAB ; Return Tab - RET ; Return to caller - -WRCON1: PUSH BC - PUSH DE ; Save pointers - LD C,A - PUSH BC ; Save character - -BGPTCH0 EQU $+1 ;<-- BGii patches this address - - CALL CMND11 ; Test status and CONTS/CONTC - POP BC ; Get character back - PUSH BC ; Save it again - CALL CONOUT ; Output it - POP BC ; Get character back - PUSH BC ; Save it again - LD A,(FCONTP) ; Get printer echo flag - OR A ; Test it - CALL NZ,LIST ; Non zero => output char to printer - POP BC ; Restore character - LD A,C ; Fall through to count routine - POP DE - POP BC ; Restore pointers - -; Count Characters in line as shown by f10 - - LD HL,TABCNT ; Get pointer to Tab counter -WRCON2: INC (HL) ; Increment Tab counter - CP RUBOUT ; Test if character = Rubout - JR Z,WRCON3 ; Treat like Backspace - CP ' ' - RET NC ; Ok if not Control - CP TAB ; Only DOBACK ever gets Tabs through here - JR Z,WRCON4 ; Handle differently if Tab - CP CONTH - JR Z,WRCON3 ; Or Backspace - INC (HL) ; Must have been echoed as two chars - CP LF - JR Z,WRCON3 ; ..unless it's LF - CP CR ; ..or CR - RET NZ - LD (HL),2 ; Reset Tab count -WRCON3: DEC (HL) ; Decrement Tab counter - DEC (HL) - RET ; And exit - -WRCON4: LD A,7 ; Bumped by one already - ADD A,(HL) ; Tabs are every 8 spaces - AND 0F8H ; ...mod 8 - LD (HL),A ; Save updated Tab count - RET ; ..and continue - -; Get Console Status - BGII uses this routine - -BGCONST: -CMND11: CALL DCIO2 ; Get character present status - RET Z ; ..exit if none - CALL GETCH ; Get next console char - CP CONTS ; Is it stop char? - JR NZ,GCONS2 ; ..jump if Not - CALL CONIN ; Get next character - CP CONTC ; Does the user want to exit (^C)? - JR NZ,CMND11 ; ..check for another character if not - JP ERROR5 ; Else jump to warm boot & clear ERMODE - -GCONS2: LD (LASTCH),A ; Save character - LD A,1 ; Character present code - RET ; Return to caller - -; Echo CR,LF - -CROUT: LD DE,MCRLF ; Fall through to output routine - -; Output Message - -CMND09: LD A,(DE) ; Get byte from buffer - CP '$' ; Test last byte - RET Z ; Yes, then return to caller - INC DE ; Point to next byte - CALL WRCON ; Output character - JR CMND09 ; And test again - - PAGE -;********************************************** -;* E r r o r R o u t i n e s * -;********************************************** - -PRDEC: LD BC,100 - CALL NUM - LD C,10 - CALL NUM - LD BC,101H - -; Display Number - -NUM: LD D,-1 ; Load number -1 -NUM1: INC D ; Increment number - SUB C ; Divide by C - JR NC,NUM1 ; Not finished then loop - ADD A,C ; Restore last value - PUSH AF ; Save it - LD A,D ; Test if "0" - OR B ; And if leading zero - JR Z,NUM2 ; Yes, then exit - LD B,A ; Set no leading zero - LD A,D ; Get number - ADD A,'0' ; Make ASCII - CALL PUTCH ; Echo number preserving BC -NUM2: POP AF ; Restore number - RET ; And exit - -; Error Messages - -MDSKCH: DEFB "Changed$" - -MBADSC: DEFB "Bad Sector$" - -MSEL: DEFB "No Drive$" - -MFILRO: DEFB "File " - -MRO: DEFB "W/P$" - IF ZS -MBERR: DEFB "ZSDOS" - ELSE -MBERR: DEFB "ZDDOS" - ENDIF - DEFB " error on $" - -MBFUNC: DEFB CR,LF,"Call" -MDRIVE: DEFB ": $" - -MFILE: DEFB " File: $" - -MCRLF: DEFB CR,LF,'$' - -; New ZSDOS error handler - enter w/ error code in B and message pointer -; in DE - -ERROR: LD A,(ERMODE) - LD C,A ; Save error mode - RRCA ; Test supress print - JR C,ERROR3 ; Suppressed, so skip dsp - -; Print ZSDOS Error on X: Explanation - - PUSH BC - PUSH DE ; Save params - CALL CROUT ; Output CR/LF - LD DE,MBERR - CALL CMND09 ; Output ZSDOS error on - LD A,(DEFDRV) ; Get current default drive - ADD A,'A' ; Convert to ascii - CALL WRCON ; Output it to console - LD DE,MDRIVE ; Point to drive tag - CALL CMND09 ; Put it also - POP DE ; Restore error message pointer - CALL CMND09 ; Send message - -; Now print CALL: XXX [FILE: XXXXXXXX.XXX] - - LD DE,MBFUNC - CALL CMND09 ; Display 'call: ' - LD A,(FUNCT) ; Get function number - CALL PRDEC ; Output it - LD A,(FLDRV) - AND A ; Was FCB used? - JR Z,ERROR2 ; ..Skip file name display if not - POP BC - PUSH BC ; Get error type - PUSH IX ; Save FCB pointer - LD A,(FUNCT) ; ARE WE ERASING A FILE? - CP 19 ; IF SO, GET NAME FROM DIRBUF AS - JR NZ,ERROR0 ; AMBIG NAME MAY HAVE BEEN USED - CALL CALDIR ; Get DIR buffer pointer - EX (SP),HL ; To show what we really gagged on -ERROR0: LD DE,MFILE - CALL CMND09 ; Output 'file: ' - POP HL ; Point to FCB - LD B,11 ; Output this many chars -ERROR1: INC HL - LD A,3 - CP B ; Time to send '.'? - LD A,'.' ; Get ready for it - CALL Z,PUTCH ; Send it if time - LD A,(HL) ; Get char - AND 7FH ; Mask attributes - CALL PUTCH ; Output it - DJNZ ERROR1 -ERROR2: CALL CROUT ; Send CR,LF - POP BC ; Get error mode back -ERROR3: LD A,4 - SUB B ; Test if select error - JR NZ,ERROR4 ; Skip if not - ld hl,DRIVE ; point to old default - ld a,(hl) ; get it - dec hl ; point to bad drive - cp (hl) ; same? - jr z,ERROR4 ; if so, skip relog - PUSH BC - CALL SELDK ; Get BIOS back in step - POP BC -ERROR4: BIT 1,C ; Test if return error mode - JR NZ,ERROR7 ; Go if return error - LD A,1 - SUB B ; Test if fatal error - JR NC,ERROR6 ; If not a fatal error -ERROR5: XOR A - LD (ERMODE),A ; Set DOS error mode to default CP/M - RST 00 ; ..and leave - -ERROR6: CALL DCIO1 ; Get console char if present - AND A ; Test if any - JR NZ,ERROR6 ; Keep getting them until typeahead eaten - CALL GETCH ; Now get operator's response - CP CONTC ; Test if abort - RET NZ ; If operator said ignore error - JR ERROR5 ; Else boot - -ERROR7: LD A,B ; Get error - LD H,A ; Save code in H reg for return - AND A ; Test if disk changed warning - RET Z ; Continue relog if so - LD L,0FFH ; Set extended error code - LD (PEXIT),HL ; Save as return code - ; ..and fall thru to DOS exit - PAGE -;****************************************************** -;* D O S E x i t R o u t i n e * -;****************************************************** - -DOSEXIT: LD A,(FLDRV) ; Test drive select used flag - OR A - JR Z,DOSEXT0 ; No then exit - LD A,(FCB0) ; Get FCB byte 0 - LD (IX+0),A ; Save it - LD A,(DRIVE) ; Get old drive number - CALL SELDK ; Select disk - IF PICKEY - LD DE,(DEVAL) ; And DE reg for datestamper - ENDIF - -; If the error handler was invoked, the stack is in an undefined -; condition at this point. We therefore have to restore the user's -; IX register independent of stack position. Thanks to Joe Wright's -; eagle eye for catching this one! - -DOSEXT0: LD SP,(SPSAVE) ; Restore user stack - LD IX,(IXSAVE) ; Restore IX (stack is don't care) - LD HL,(PEXIT) ; Get exit code - IF ~PICKEY - LD DE,(DEVAL) ; And DE reg for DateStamper - ENDIF - LD A,L ; Copy function code - LD B,H - RET ; And return to caller - PAGE -;****************************************************** -;* D i s k F u n c t i o n s * -;****************************************************** - -; Reset Disk System - -CMND13: LD HL,RAMLOW+0080H ; Set up DMA address - LD (DMA),HL ; And save it - CALL STDMA ; Do BIOS call - XOR A ; Set default drive = 'A' - LD (DEFDRV),A ; Save it - LD DE,0FFFFH ; Reset all drives - -; Reset Multiple Login Drive - DE = Reset mask -; Fixed Disk Login vector is also altered by this call - -CMND37: CALL UNLOG ; Clear selected drives in DE from login - LD A,(FLAGS) - BIT 2,A ; Test hard R/O enabled - JR NZ,UNWPT1 ; If enabled - LD HL,DSKWP ; Get drive W/P vector - CALL ANDDEM ; Reset W/P stat only of requested drvs -UNWPT1: LD A,(FUNCT) - CP 13 ; Skip hard disk login change? - LD HL,HDLOG - CALL NZ,ANDDEM ; Clear HD Login Vector if Fcn 37 -RELOG1: - IF ZS - LD HL,(HDLOG) - CALL HLORDE ; Don't clear fixed disks from T/D - EX DE,HL ; Place modified logout in DE - LD HL,TDFVCT - CALL ANDDEM ; Clear T/D vector as needed - ENDIF - - LD A,(DEFDRV) ; Get default drive - PUSH AF -RELOG2: - IF RESDSK ; (bh) - CALL SETDSK ; Allow BIOS to detect density change (bh) - ELSE - DEFB 0,0,0 ; Make 3 NOP's to keep constant code (hfb) - ENDIF ; (bh) - POP AF - CALL SELDK ; Select default drive - -; ZSDOS watches for any $*.* in any user on any drive during re-log, -; make, and delete. In this manner, SUBFLG will always be valid - -; even under fast relog and NZCOM! Thanks to Joe Wright for suggesting -; the need for this, and suggesting ways to do it. - -SUBEXT: LD A,(SUBFLG) ; Get submit flag - JR SAVEA ; Exit - -; Check for possible existance of submit file by checking first -; byte of dir entry or FCB for '$'. Pointer to dir or FCB passed -; to routine in HL. - -CKSUB: INC HL ; Point to file name - LD A,(HL) ; Get first char filename - DEC HL - SUB '$' ; Test if '$' - RET NZ ; Not then exit - DEC A ; Load a with 0FFH - LD (SUBFLG),A ; Save it in subflg - RET - -; Unlog Drive mask in DE - -UNLOG: LD A,E ; Get LSB - CPL ; Complement it - LD E,A - LD A,D ; Get MSB - CPL ; Complement it - LD D,A ; DE = not reset - LD HL,LOGIN ; Get addr of login vector -ANDDEM: LD A,E ; Clear login bits of reset drives - AND (HL) ; ..a byte at a time - LD (HL),A ; Put to memory - INC HL - LD A,D - AND (HL) - LD (HL),A - RET - -; Search for File - -CMND17: CALL SELDRV ; Select drive from FCB - LD A,(IX+0) - SUB '?' ; Test if '?' - JR Z,CMD17B ; If so all entries match - LD A,(IX+FCBMOD) ; Get system byte - CP '?' ; Test if '?' - JR Z,CMD17A ; Yes, jump - LD (IX+FCBMOD),0 ; Load system byte with Zero -CMD17A: LD A,15 ; Test first 15 items in FCB -CMD17B: CALL SEARCH ; Do search -CMD17C: LD HL,(DIRBUF) ; Copy directory buffer - LD BC,128 ; Directory=128 bytes -MV2DMA: LD DE,(DMA) ; To DMA address - LDIR - RET ; Exit - -; Search for Next Occurence of File - -CMND18: LD IX,(DCOPY) ; Get last FCB used by search - LD (ARWORD),IX ; Save FCB pointer for BGii - CALL SELDRV ; Select drive from FCB - CALL SEARCN ; Search next file match - JR CMD17C ; And copy directory to DMA address - -; Delete File - -CMND19: CALL SELDRV ; Select drive from FCB - CALL DELETE ; Delete file -CMD19A: LD A,(SEAREX) ; Get exit byte 00=file found, 0FFH=Not - JR SAVEA ; And exit - -; Rename File - -CMND23: CALL SELDRV ; Select drive from FCB - CALL RENAM ; Rename file - JR CMD19A ; And exit - -; Return Current Drive - -CMND25: LD A,(DEFDRV) ; Get current drive -SAVEA: LD (PEXIT),A ; Return character -DUMMY: RET ; ..and exit ZSDOS - -; Set flags - -CMD101: LD (FLAGS),A ; Set ZSDOS flags - ; ..and fall thru -; Get flags - -CMD100: LD A,(FLAGS) ; Get ZSDOS flags - JR SAVEA ; ..and exit - -; Change Status - -CMND30: CALL SELDRV ; Select drive from FCB - CALL CSTAT ; Change status - JR CMD19A ; And exit - -; Return CP/M Version Number - -ZDPCH1: -CMND12: LD HL,22H ; Set CP/M compatable version number - IF ~ZS ; (crw) - CP 'D' ; IS Caller testing for DS? - JR NZ,SAVHL ; ..exit if Not - LD A,(UNLOAD+1) ; See if Clock was installed by testing - ; ..MSB of Remove vector - AND A ; ..if it's zero, then No Clock - JR Z,SAVHL ; ..and No DateStamper - LD H,E ; Otherwise, return DS Active Flag - LD DE,CMD98A ; Have a clock, so get Clock Address - ENDIF - IF ~PICKEY - LD (DEVAL),DE ; In case DS gave us a clock addr - ENDIF - JR SAVHL ; For speed - -; Following commands return status in like manner and are consolidated here -; in selected order with least-accessed commands taking longest to traverse -; string, and frequently accessed/time critical exitting quickest. - -; The code in this section is a bit obscure, as it depends on burying -; instructions within other instructions. 6502 users have long used the -; 'BIT' trick to skip instructions - this inspired me to see if similar -; things could be done with the Z80. Indeed they can, as this demonstrates. -; When the Z80 jumps in at a label, it executes the LD HL instruction. The -; DEFB 0DDH turns the LD HL instructions that follow into LD IX. In effect, -; this turns the DEFB 0DDH into a one byte relative jump to SAVHL. As IX -; is never used by these calls, its loss is of no consequence. -; A similar trick is used in SEAR15, resulting in a useless LD HL but -; saving a byte. - -; New Universal Return Version FUNCTION 48 - -CMND48: - IF ZS - LD HL,'S' << 8 + VERS ;"S" indicates ZSDOS - ZRDOS returns 0 - ELSE - LD HL,'D' << 8 + VERS ;"D" indicates ZDDOS - ZRDOS returns 0 - ENDIF - DEFB 0DDH ; Trash IX and fall through - -; Return Disk W/P Vector - -CMND29: LD HL,(DSKWP) ; Get disk W/P vector - DEFB 0DDH ; Trash IX and fall through - -; Return Fixed Disk Login Vector - -CMND39: LD HL,(HDLOG) ; Return fixed disk login vector - DEFB 0DDH ; Trash IX and fall through - -; Return ALV Vector - -CMND27: LD HL,(ALV) ; Get allocation vector - DEFB 0DDH ; Trash IX and fall through - -; Return Login Vector - -CMND24: LD HL,(LOGIN) ; Get login vector - DEFB 0DDH ; Trash IX and fall through - -; Return Drive Table - -CMND31: LD HL,(IXP) ; Get drive table - DEFB 0DDH ; Trash IX and fall through - -; Return Current DMA - -CMND47: LD HL,(DMA) ; Return current DMA addr -SAVHL: LD (PEXIT),HL ; Save it - RET ; And exit - -; Set BDOS Error Mode - -CMND45: LD (ERMODE),A ; Save error mode - RET ; And exit - -; Set/Get User Code - -CMND32: LD HL,USER ; Point to user byte location - INC A ; Test if 0FFH - LD A,(HL) ; Get old user code - JR Z,SAVEA ; If 0FFH then exit - LD A,E ; Get new user code - AND 01FH ; Mask it - LD (HL),A ; Save it - RET ; And exit - -; Compute File Size Command - -CMND35: CALL SELDR1 ; Select drive from FCB - CALL FILSZ ; Compute file size - JR CMD19A ; And exit - -; Set Random Record Count - -CMND36: LD HL,32 ; Set pointer to next record - CALL CALRRC ; Calculate random record count -LDRRC: LD (IX+33),D ; And save random record count - LD (IX+34),C - LD (IX+35),B - RET ; And exit - -; Select Disk From FCB - -BGSELDRV: -SELDRV: LD A,(ERMODE) ; Are we in modified user mode? - AND A - JR NZ,SELDR1 ; Jump if so, else.. - LD HL,(ARWORD) ; - LD BC,FCBUSR ; Point to user number - ADD HL,BC ; - LD (HL),A ; Clear user flag -SELDR1: LD A,0FFH ; Set disk select done flag - LD (FLDRV),A - LD A,(DEFDRV) ; Get current drive - LD E,A ; Save it in register E - LD HL,(ARWORD) - LD A,(HL) ; Get drive from FCB - LD (FCB0),A ; Save it - CP '?' ; Test if '?' - JR Z,CMND14 ; Yes, then select drive from register E - PUSH IX ; Save BGii's IX register - ; IX won't be altered on cmnd14 - LD IX,(ARWORD) ; Get FCB pointer -;1.1a Changed to allow proper access to Drive P: -;1.2a AND 0FH ; Mask drive - AND 1FH ;1.2a Mask Drive - PUSH HL - JR Z,SELDR0 ; Select drive from register E - LD E,(HL) ; Get drive from FCB - DEC E ; Decrement drive number so A=0 -SELDR0: CALL CMND14 ; - do select of drive - POP HL ; Restore FCB pointer - -; Resolve User for FCB - FCBPTR in IX, Returns User in A - - LD A,(IX+FCBUSR) ; ..get potential user in case - BIT 7,A ; Is this a valid user? - JR NZ,RESUS1 ; Skip if there is - LD A,(USER) ; Get user number - JR RESUS1 ; ..and bypass push IX - -; Set User in FCB to Value passed in A - -RESUSR: PUSH IX ; Preserve IX -RESUS1: LD IX,(ARWORD) - AND 1FH ; User number in A - LD (IX+0),A ; Save in FCB 0 byte - OR 80H ; Set valid DOS user flag - LD (IX+FCBUSR),A ; ..and in FCB 13 byte - POP IX ; Restore caller's IX - RET - -; Select Disk Error Exit - The stack is off by one level here, but -; this is a one way trip anyway. - -SELDK3: LD HL,(STSEL) ; Load error message address - LD B,4 ; Select error - LD DE,MSEL ; Load select error message - JP (HL) ; And display error - -; Select Disk from E register - -CMND14: LD A,(DEFDRV) ; Get current drive - LD (DRIVE),A ; Save it in memory - LD A,E ; Copy drive number - -; Select Disk -; Call w/ A = Drive Number (0..15 = A..P) - -SELDK: LD HL,(LOGIN) ; Get login vector - AND 0FH ; Mask drive number - LD B,A ; Save counter - CALL NZ,SHRHLB ; ..and rotate into position -SELDK0: EX DE,HL ; Put drive bit mask in DE - LD HL,DEFDRV ; Get pointer last drive - BIT 0,E ; Test if drive logged in - JR Z,SELDK2 ; No, login drive - CP (HL) ; Test same drive - RET Z ; Yes then exit - -; NOTE: A long standing DOS bug concerns the SELECT function. If a -; function 14 call is made and the drive doesn't exist, the default -; will still point to the bad drive unless we fix it in the error -; routine. It is for this reason that drive is saved above. We must -; allow default to assume the illegal drive value long enough for the -; error handler to print it, then re-select the old default. - -SELDK2: LD (HL),A ; Save new current drive - PUSH DE ; Save drive logged in flag - LD C,A ; Copy drive number - CALL SELDSK ; Do BIOS select - LD A,H ; Test if error - OR L - JR Z,SELDK3 ; Yes, illegal drive number - LD DE,TRANS ; Point to local translation store - LD BC,2 ; ..and move 2-byte ptr in - LDIR - LD (TEMP0),HL ; Save address temp0 - LD C,6 ; Advance to dirbuf part of DPH - ADD HL,BC ; As TEMP1 and TEMP2 unused in P?DOS - LD DE,DIRBUF ; Load DIRBUF pointer - LD C,8 ; Copy 8 bytes - LDIR - LD HL,(IXP) ; Get drive parameter address - LD C,15 ; Copy 15 bytes - LDIR - POP DE ; Get drive logged in flag - BIT 0,E ; Test it - RET NZ ; Drive logged in so return - CALL GETCDM - EX DE,HL ; Drive mask in DE - LD HL,(LOGIN) ; Get login vector - CALL HLORDE ; Set drive bit in login vector - LD (LOGIN),HL ; Save login vector - LD A,(FLAGS) ; Get flags - BIT 3,A ; Fast relog enabled? - JR Z,INITDR ; Skip if disabled - -; The following code checks the WACD size to determine if the drive -; being selected is a fixed disk. If the WACD size is 0, the disk -; is Non-Removable. However, several BIOSes support remapping of -; logical drives. This complicates matters because BDOS must catch -; the swap and clear the Hard Disk Allocation Vector and allow the -; allocation bitmaps to be rebuilt. Thus, every disk that is being -; selected for the first time traverses this code. If a disk was -; logged as a fixed disk and all of the sudden has a WACD buffer, -; the Fixed Disk Login Vector is cleared. Thus, for Bug-free -; operation of Fast Fixed Disk Logging, if drives are swapped -; NEVER SWAP TWO FIXED DRIVES! - - LD HL,(NCHECK) ; Is this a fixed drive? - LD A,H - OR L - LD C,A ; Save fixed disk flag (Z=true) - LD HL,(HDLOG) - LD A,E ; See if logged as fixed disk - AND L - LD L,A - LD A,D - AND H ; MSB - OR L ; Z flag set if HL and DE = 0 - LD A,0FFH ; Don't alter flags - JR Z,SELDK4 ; If not logged as fixed disk - INC A ; Else flag as logged -SELDK4: LD B,A ; Save logged as fixed disk flag (Z=true) - OR C ; Test if still fixed disk - RET Z ; Skip re-map if logged and not swapped - XOR A - LD H,A - LD L,A ; Null vector - OR B ; Was it logged as a fixed disk? - JR Z,SELDK5 ; Invalidate HDLOG vector - drive no longer - ; Fixed disk - LD A,C - OR A ; Wasn't fixed disk before - is it now? - JR NZ,INITDR ; Skip vector update if it isn't - LD HL,(HDLOG) - CALL HLORDE ; Else add this drive to fixed disk vector -SELDK5: LD (HDLOG),HL ; Update fixed disk vector - ;..fall thru to INITDR - -; Init Drive -; Clear ALV Bit Buffer after Drive reset - -INITDR: LD HL,(MAXLEN) ; Get length ALV buffer-1 (bits) - CALL SHRHL3 ; Divide by 8 to get bytes - LD B,H - LD C,L ; Counter to BC (will be count+1 cleared) - LD HL,(ALV) ; Get pointer ALV buffer - PUSH HL - LD D,H - LD E,L - INC DE ; ALV buffer +1 in DE - XOR A - LD (HL),A ; Clear first 8 bits - LDIR ; And remainder of buffer - POP HL ; Get ALV pointer - LD DE,(NDIR0) ; Get first two bytes ALV buffer - LD (HL),E ; Save LSB - INC HL ; Increment pointer - LD (HL),D ; Save MSB - LD HL,(TEMP0) ; Clear number of files on this drive - LD (HL),A ; Clear LSB (A still has 0) - INC HL ; Increment pointer - LD (HL),A ; Clear MSB - -ZDPCH2 EQU $ ;<-- Intercept first scan (ZDS Patch) - CALL SETFCT ; Set file count -INITD2: LD A,0FFH ; Update directory checksum - CALL RDDIR ; Read FCB's from directory - CALL TSTFCT ; Test last FCB - JP Z,SUBEXT ; Return subflg for strict CP/M compat (hfb) - CALL CALDIR ; Calculate entry point FCB - LD A,(HL) ; Get first byte FCB - CP 0E5H ; Test empty directory entry - JR Z,INITD2 ; Yes then get next FCB - CP 021H ; Test time stamp - JR Z,INITD2 ; Yes then get next FCB - -ZDPCH3 EQU $ ;<-- Test for T&D if first time (ZDS Patch) - CALL CKSUB ; Test for submit file - LD C,1 ; Set bit in ALV buffer - CALL FILLBB ; Set bits from FCB in ALV buffer - CALL TSTLF ; Test for last file - CALL NC,SETLF0 ; ..and update the last file count if so - JR INITD2 ; And get next FCB - -; Return Mask for Current Drive in HL - -GETCDM: LD HL,0 ; No drives to Or - -; Set Drive bit in HL - -SDRVB: EX DE,HL ; Copy HL=>DE - LD HL,1 ; Get mask drive "A" - LD A,(DEFDRV) ; Get current drive - OR A ; Test if drive "A" - JR Z,HLORDE ; Yes then done -SDRVB0: ADD HL,HL ; Get next mask - DEC A ; Decrement drive counter - JR NZ,SDRVB0 ; And test if done -HLORDE: LD A,D ; HL=HL or DE - OR H - LD H,A - LD A,E - OR L - LD L,A - RET ; Exit - -SHRHL3: LD B,3 ; Used in a few places - -; Shift HL right logical B bits - -SHRHLB: SRL H - RR L ; Shift HL right one bit (divide by 2) - DJNZ SHRHLB - RET - -; Calculate Sector/Track Directory - -STDIR: LD HL,(FILCNT) ; Get FCB counter directory - IF UNROLL - SRL H - RR L - SRL H ; (net cost: 3) - RR L ; Divide by 4 (inline for speed) - ELSE - LD B,2 - CALL SHRHLB ; Divide by 4 - ENDIF - LD (RECDIR),HL ; Save value (used by checksum) -STDIR2: EX DE,HL ; Copy it to DE -STDIR1: LD HL,0 ; Clear HL - -; Calculate Sector/Track -; Entry: HL,DE=Sector Number (128 byte sector) -; Result Set Track =HL,DE / MAXSEC -; Set Sector =HL,DE MOD MAXSEC - -CALST: LD BC,(MAXSEC) ; Get sectors/track - LD A,17 ; Set up loop counter -CALST0: OR A - SBC HL,BC ; HL > BC? - CCF - JR C,CALST1 ; Yes then jump - ADD HL,BC ; No then restore HL - OR A ; Clear Carry -CALST1: RL E ; Shift result in DE - RL D - DEC A ; Test last bit done - JR Z,CALST2 ; Yes then exit - ADC HL,HL ; Shift next bit in HL - JR CALST0 ; Continue - -CALST2: PUSH HL ; Save sector number - LD HL,(NFTRK) ; Get first track - ADD HL,DE ; Add track number - LD B,H ; Copy it to BC - LD C,L - CALL SETTRK ; CBIOS call Set Track - POP BC ; Restore sector number - LD DE,(TRANS) ; Get translation table address - CALL SECTRN ; CBIOS call sector translation - LD B,H ; Copy result to BC - LD C,L - JP SETSEC ; BIOS call Set Sector - -; Get Disk Map Block Number from FCB (Squeezed by Joe Wright) -; Exit HL=Address FCB -; DE=DM -; BC=Offset in DM -; Zero Flag Set (Z) if DM=0, Else reset (NZ) - -GETDM: LD L,(IX+NXTREC) ; Get record number in L - RL L ; Shift it left once - LD A,(NEXTND) ; Get EXM - AND (IX+FCBEXT) ; And the extent number - LD H,A ; To H - LD A,(NBLOCK) ; Get BSH - LD B,A ; To B - INC B ; +1 - CALL SHRHLB ; Shift HL right B times - LD D,B ; Zero to D - LD A,L ; Result to A - -GETDM4: LD HL,(ARWORD) - LD C,16 ; Add offset 16 to point to DM - ADD HL,BC - LD C,A ; Add entry FCB - ADD HL,BC - LD A,(MAXLEN+1) ; Test 8 bits/16 bits FCB entry - OR A - LD E,(HL) ; Get 8 bit value - JR Z,GETDMX ; ..and exit if 8-bit entries - - ADD HL,BC ; Add twice (16 bit values) - LD E,(HL) ; Get LSB - INC HL ; Increment pointer - LD D,(HL) ; Get MSB - DEC HL ; Decrement pointer -GETDMX: LD A,D ; Check for zero DM value - OR E - RET ; And exit - -; Calculate Sector Number -; Entry: DE=Block Number from FCB - -CALSEC: LD HL,0 ; Clear MSB sector number - LD A,(NBLOCK) ; Get loop counter - LD B,A ; Save it in B - EX DE,HL -CALSC0: ADD HL,HL ; Shift L,D,E - RL E - DJNZ CALSC0 ; B times - EX DE,HL - LD A,(NMASK) ; Get sector mask - AND (IX+NXTREC) ; And with next record - OR E ; Set up LSB sector number - LD E,A - RET ; And exit - -; Check for File Read-Only status, then fall thru to CALDIR - -CKRODI: CALL CHKFRO ; Abort if the file is R/O - ; ..fall thru.. - -; Calculate DIRBUF Entry Point - -CALDIR: LD A,(SECPNT) ; Get sector pointer -CALDIR1: ; New label for DS (crw) - LD HL,(DIRBUF) ; Get start address dirbuf -CALDI0: ADD A,L ; Add L=L+A - LD L,A - RET NC ; No carry exit - INC H ; Increment H - RET ; And exit - -; Init File Count - -SETFCT: LD HL,-1 ; Set up file count - LD (FILCNT),HL ; Save it - RET ; And exit - -; Set Write Protect Disk Command (relocated & compressed hfb) - -CMND28: ; Set read only disk - LD HL,(DSKWP) ; Get disk W/P vector - CALL SDRVB ; Include drive bit - LD (DSKWP),HL ; Save disk W/P vector - LD DE,(NFILES) ; Get max number of files-1 (bumped below) - LD HL,(TEMP0) ; Get pointer to disk parameter block - INC HL ; Correct pointer.. - ; Setlf0 relocated in-line here (hfb) -SETLF0: INC DE ; Increment last file - LD (HL),D ; Save it in TEMP0 - DEC HL - LD (HL),E - RET ; And exit - -; Search using first 15 bytes of FCB, test if found - -SRCT15: CALL SEAR15 ; Search on 15-bytes..(consolidated-hfb) - ; ..fall thru to test presence.. -; Test File Count - -TSTFCT: LD HL,(FILCNT) ; Test file count=0FFFFH - LD A,H ; Get MSB - AND L ; And LSB - INC A ; Test if result=0FFH - RET ; And exit - -; Test Last File - -TSTLF: LD HL,(TEMP0) ; Get pointer to last file - LD DE,(FILCNT) ; Get file counter - LD A,E ; Subtract DE-(HL) - SUB (HL) - INC HL - LD A,D - SBC A,(HL) - RET ; Exit - -; Get Next FCB from Drive -; Entry A=0 Check Checksum, A=0FFH Update Checksum - -RDDIR: LD C,A ; Save checksum flag - LD HL,(FILCNT) ; Get file counter - INC HL ; Increment it - LD (FILCNT),HL ; And save it - LD DE,(NFILES) ; Get maximum number of files - LD A,E ; Is this the last file? - SUB L - LD A,D - SBC A,H - JR C,SETFCT ; ..set file count to 0FFFFH if so - LD A,L ; Get file count LSB - RRCA ; *32 (bm/hfb-to save a byte) - RRCA - RRCA - AND 060H ; Mask it - LD (SECPNT),A ; Save it for later use - RET NZ ; Return if not first FCB sector - PUSH BC ; Save checksum flag - IF ~ZSDOS11 ; (* This was NOT in released package *) - LD A,H ; [1.2] - OR L ; [1.2] First dir entry? - IF ZS - JR NZ,RdDir0 ; [1.2] If not - LD HL,(NCHECK) ; [1.2] Is this a fixed disk? - LD A,H ; [1.2] - OR L ; [1.2] - CALL NZ,HOME ; [1.2] Home if media could change - ELSE ;~Zs - CALL Z,HOME ; [1.2] Home if first dir entry - ENDIF ;Zs - ENDIF ;~Zsdos11 -RdDir0: CALL STDIR ; Calculate sector/track directory - IF ~ZS - CALL READDR ; Read into DIR buffer - -; Check if !!!TIME&.DAT on disk, save temp. result in TDCHEK - - LD HL,(FILCNT) - LD A,H - OR L ; First file? (filcnt = 0) - JR NZ,RDDIR2 ; ..jump if not - LD HL,(DIRBUF) ; Else look for !!!TIME&.DAT - LD B,11 ; Test 11 bytes -RDDIR1: INC HL - LD C,(HL) ; Get Next Char - RES 7,C ; Clear Attricute Bit - ADD A,C ; Add to Checksum - DJNZ RDDIR1 ; Back for more... - SUB TDCKSM ; See it it's !!!TIME&.DAT - LD (TDCHEK),A ; Save result (0 = !!!TIME&.DAT found) -RDDIR2: ; - ELSE - ; READDR subroutine moved in-line here - CALL DMADIR ; Set up DMA directory - CALL READR ; Read a record - CALL STDMA ; ..and set up user's DMA - ENDIF - POP BC ; Restore checksum flag - -; Update/Check Checksum Directory -; Entry C=0 Check Checksum, C=0FFH update Checksum - -CHKDIR: LD HL,(NCHECK) ; Get number of checked records - LD DE,(RECDIR) ; Get current record - XOR A ; Clear carry (bm) - SBC HL,DE ; Test current record - RET Z ; Exit if zero - RET C ; Exit if greater than ncheck - LD HL,(DIRBUF) ; Get dirbuf - CALL CKS127 ; ..and checksum first 127 bytes.. - ADD A,(HL) ; ...then 128th byte (hfb) - LD HL,(CSV) ; Get pointer checksum directory - ADD HL,DE ; Add current record - INC C ; Test checksum flag - JR NZ,CHKDR1 ; 0FFH=> update checksum - LD (HL),A ; Update checksum - RET ; And exit - -CHKDR1: CP (HL) ; Test checksum - RET Z ; Exit if ok - -; Checksum differs, So Disk has changed. Relog it and continue - - LD A,(FLAGS) - BIT 4,A ; Inform user? - LD B,0 ; Disk change error code - LD DE,MDSKCH ; Disk changed message - CALL NZ,ERROR ; Inform user - -; Relog Current Drive after media change detected - - CALL GETCDM ; Get current drive mask in HL - EX DE,HL ; Xfer mask to DE - CALL UNLOG ; Reset login vector for logged drive - CALL RELOG1 ; Do the meat of relogging - ; Caveat emptor: this call is recursive... - CALL SETFCT ; Re-initialize search file count - XOR A ; We only get here by checking.. (bm) - JR RDDIR ; And all checking is done from rddir - -; Read Sector from Drive - -READR: CALL READ ; CBIOS call read sector - JR WRITE0 - -; Write Sector on Drive - -WRITER: CALL WRITE ; CBIOS call write sector -WRITE0: OR A ; Test exit code - RET Z ; Exit if ok - LD B,1 ; Disk I/O error code - LD DE,MBADSC ; Load bad sector message - LD HL,(STBDSC) ; Load bad sector vector - JP (HL) ; ZSDOS error on D: Bad Sector - -; Close File Command (relocated hfb) - -BGPTCH2 EQU $+1 ;<-- BGii patch point - -CMND16: CALL SELDR1 ; Select drive from FCB - -; Close File - -CLOSE: BIT 7,(IX+FCBMOD) ; Test FCB/file modified - RET NZ ; Not then no close required - CALL CHKRO ; Test disk W/P - CALL SRCT15 ; Search file and test present - RET Z ; No then exit with error - CALL CKRODI ; Check file W/P, get directory entry - LD BC,16 ; Offset to DM block - ADD HL,BC ; Add offset - EX DE,HL ; Save DIR PTR in DE - LD HL,(ARWORD) ; Get FCB ptr - ADD HL,BC ; Add offset - EX DE,HL - LD B,C ; Xfer counter - -; Copy FCB (DE) to DIR (HL) if and only if DIR=0 or DIR=FCB - -CLOSE0: INC (HL) - DEC (HL) ; Test DIR for 0 - LD A,(DE) ; Get byte from FCB - JR Z,CLOSE1 ; OK to Copy if 0 - CP (HL) ; Test if same as DIR - JP NZ,RETCFF ; ..if Not, abort Close and return error -CLOSE1: LD (HL),A ; Else save in DIR - INC DE - INC HL - DJNZ CLOSE0 ; Bump pointers and loop until done - LD DE,-20 ; Add -20 to get Extent Number from DIR - ADD HL,DE ; HL contains pointer to extent number - LD A,(IX+FCBEXT) ; Get extent number FCB - CP (HL) ; Compare with extent number directory - JR C,CLOSE3 ; FCB < directory then jump - LD (HL),A ; Save extent number in directory - INC HL ; Get pointer to next record - INC HL - INC HL - LD A,(IX+FCBREC) ; Get next record FCB - LD (HL),A ; Save next record in directory -CLOSE3: CALL CLOSE6 ; Clear Archive Bit and Write FCB - CALL GETDME ; Get Data Module and Extent - IF ~ZSDOS11 ; (* NOT in Release version *) - PUSH BC ;[1.2] Save prior module and Extent - JR Z,CLOSE4 ; ..jump to Stamp if they are both 0 - ELSE ;Zsdos11 (* This was Release version *) - JR Z,CLOSE4 ; ..jump to Stamp if they are both 0 - PUSH BC ; Save prior module and Extent - ENDIF ;~Zsdos11 - LD BC,0 - CALL SETDME ; Set FCB Data Module and Extent to 0 - CALL SRCT15 ; Find proper DIR Entry - IF ~ZSDOS11 - JR Z,JSETDME ; ..Exit if Extent 0 Not Found -CLOSE4: - ELSE ;Zsdos11 - POP BC - JR Z,JSETDME ; ..Exit if Extent 0 Not Found -CLOSE4: PUSH BC - ENDIF ;~Zsdos11 - CALL CLOSE6 ; Clear Archive Bit and Write FCB - LD HL,(STUPDV) ; Get the update routine address - IF ZS - CALL STAMPT ; ..and stamp it - ELSE ;If not Zs (crw) - LD C,10 ; Set Last Modify - CALL JPHL ; ..and Stamp if Enabled - ENDIF ;ZS - IF ~ZSDOS11 -JSETDME: - POP BC ; Get Original Module and Extent Back - ELSE ;Zsdos11 - POP BC ; Get Original Module and Extent Back -JSETDME: - ENDIF ;~Zsdos11 - JP SETDME ; Restore to FCB and Exit - -CLOSE6: CALL CALDIR ; Get directory entry - LD BC,11 ; Point to archive byte - ADD HL,BC - RES 7,(HL) ; Reset archive bit - RES 7,(IX+ARCATT) ; Reset bit in FCB - IF ZSDOS11 - JR WRFCB ; Write FCB to Disk - - IF ~ZS -READDR: CALL DMADIR ; Set up DMA directory - CALL READR ; Read a record - JR STDMA ; ..and set up user's DMA - ENDIF ;NOT Zs - ENDIF ;Zsdos11 - -WRFCB: CALL CALDIR ; Point to dir entry to write - LD A,FCBUSR ; Offset to user byte in FCB - CALL CALDI0 ; ..do the add here - LD (HL),0 ; Prevent writing it to disk - CALL STDIR ; Calculate sector/track directory - LD C,0FFH ; Update checksum directory - CALL CHKDIR -WRITD1: CALL DMADIR ; Set up dma directory (label for DS - crw) - LD C,1 ; Write directory flag - CALL WRITER ; Write record - JR STDMA ; Set up DMA user - - IF ~ZSDOS11 - IF ~ZS -READDR: CALL DMADIR ; Set up DMA directory - CALL READR ; Read a record - JR STDMA ; ..and set up user's DMA - ENDIF ;NOT Zs - ENDIF ;~Zsdos11 - -; Set DMA Address Command - -CMND26: LD (DMA),DE ; Save DMA address - -; Set DMA Address - -STDMA: LD BC,(DMA) ; Get DMA address - JR DMADR0 ; And do BIOS call - -; Set DMA Address Directory - -DMADIR: LD BC,(DIRBUF) ; Get DMA address directory -DMADR0: JP SETDMA ; Cbios call set DMA - -; Get Bit from ALV Buffer -; Entry DE=Block Number -; Exit A =Bit in LSB -; B =Bit Number in A -; HL=Pointer in ALV Buffer - -GETBIT: LD A,E ; Get bit number - AND 7 ; Mask it - INC A ; Add 1 - LD C,A ; Save it - IF UNROLL - SRL D ; Get byte number - RR E ; DE=DE/8 - SRL D - RR E - SRL D - RR E ; ..inline for speed (net cost: 4) - LD B,A ; Re-save bit number for next shift - LD HL,(ALV) ; Get start address ALV buffer - ELSE - EX DE,HL - CALL SHRHL3 ; Divide by 8 - LD B,A ; Re-save bit number for next shift - LD DE,(ALV) ; Get start address ALV buffer - ENDIF ;Unroll - ADD HL,DE ; Add byte number - LD A,(HL) ; Get 8 bits -GETBT0: RLCA ; Get correct bit - DJNZ GETBT0 - LD B,C ; Restore bit number - RET ; And return to caller - -; Set/Reset bit in ALV Buffer -; Entry DE=Block Number -; C =0 Reset Bit, C=1 Set Bit - -SETBIT: PUSH BC ; Save set/reset bit - CALL GETBIT ; Get bit - AND 0FEH ; Mask it - POP DE ; Get set/reset bit - OR E ; Set/reset bit -SETBT0: RRCA ; Rotate bit in correct position - DJNZ SETBT0 - LD (HL),A ; Save 8 bits - RET ; And return to caller - -; Delete File - -DELETE: CALL COMCOD ; Call common code w/VDEL on stack - -; Delete Routine Core (relocated to save space) (hfb) - -VDEL: CALL CKRODI ; Check file W/P, get directory entry - LD (HL),0E5H ; Remove file - INC HL - LD A,(HL) ; Get first char - SUB '$' ; See if submit file - JR NZ,VDEL1 ; If not - LD (SUBFLG),A ; Clear subflg if $*.* erased -VDEL1: INC HL - RES 7,(HL) ; Insure erased files are not public - LD C,0 ; Remove bits ALV buffer - ; ..fall thru and return to caller.. - -; Fill bit buffer from FCB in DIRBUF -; Entry C=0 Reset Bit, C=1 Set Bit - -FILLBB: CALL CALDIR ; Get directory entry - LD DE,16 ; Get offset DM block - ADD HL,DE ; Add offset - LD B,E ; Get block counter -FILLB0: LD E,(HL) ; Get LSB block number - INC HL ; Increment pointer - LD D,0 ; Reset MSB block number - LD A,(MAXLEN+1) ; Test >256 blocks present - OR A - JR Z,FILLB1 ; No then jump - DEC B ; Decrement block counter - LD D,(HL) ; Get correct MSB - INC HL ; Increment pointer -FILLB1: LD A,D ; Test block number - OR E - JR Z,FILLB2 ; Zero then get next block - PUSH HL ; Save pointer - PUSH BC ; Save counter and set/reset bit - LD HL,(MAXLEN) ; Get maximum length ALV buffer - OR A ; Reset carry - SBC HL,DE ; Test DE<=maxlen ALV buffer - CALL NC,SETBIT ; Yes then insert bit - POP BC ; Get counter and set/reset bit - POP HL ; Get pointer -FILLB2: DJNZ FILLB0 ; Repeat for all DM entries - RET ; And return to caller - -; Check File W/P Bit - SEARCH called first - -CHKFRO: CALL CALDIR ; Get directory entry - LD DE,WHLATT ; Offset to R/O bit - ADD HL,DE ; Add offset - LD DE,(WHEEL) ; Get wheel byte address from header - LD A,(DE) ; ..and retrieve the actual byte - AND A ; ..and check the Wheel byte - JR NZ,CHKFR4 ; We have wheel, so allow writes anyway - BIT 7,(HL) ; Else check Wheel attribute - JR NZ,CHKFR2 ; Yes then error -CHKFR4: INC HL ; Check W/P bit (hfb) - BIT 7,(HL) ; Test file W/P - JR NZ,CHKFR2 ; If W/P -CHKFR3: BIT 7,(IX+PSFATT) ; Was file accessed as Public or Path? - RET Z ; If normal access - LD A,(FLAGS) ; Else test for writes allowed - AND 0010B - RET NZ ; Go ahead, writes are allowed -CHKFR2: LD HL,(SFILRO) ; Get pointer to file W/P message - LD B,3 ; File W/P error code - LD DE,MFILRO ; Load file W/P message - JP (HL) ; Display message - - -; Check Drive Write Protect - -BGCKDRO: -CHKRO: CALL CHKRO1 ; Is the disk W/P? - RET NZ ; ..return if disk R/W - LD B,2 ; Else set disk W/P error code - LD DE,MRO ; Load drive W/P message - LD HL,(STRO) ; Get pointer to drive W/P message - JP (HL) ; Display message - -CHKRO1: LD HL,(DSKWP) ; Get the W/P drive vector - CALL SDRVB ; Set the bit for this drive - SBC HL,DE ; See if extra bit added (Cy is clear) - RET - -; Search using first 12 bytes of FCB (hfb) - -SEAR12: LD A,12 - DEFB 21H ; Trash HL and fall through - -; Search using first 15 bytes of FCB - -SEAR15: LD A,15 - -; Search for File Name -; Entry: A = Number of bytes for which to search - -SEARCH: LD (SEARNB),A ; Save number of bytes - LD A,0FFH ; Set exit code to 0FFH (not found) - LD (SEAREX),A - LD (DCOPY),IX ; Copy FCB pointer to RAM (search next) - CALL SETFCT ; Initiate file counter - -; Force directory read with a Call HOME (bh) (Only if Floppys-hfb) - IF ZSDOS11 ; (* Logic moved to RDDIR if NOT Zsdos11 *) - LD HL,(NCHECK) ; Is this a fixed media? - LD A,H - OR L - CALL NZ,HOME ; Invoke CBIOS Home routine if removeable - ENDIF ;~Zsdos11 - -; Search Next File Name - -SEARCN: XOR A ; Check checksum directory - LD H,A - LD L,A - LD (SEARQU),HL ; Clear question mark & public detected flags - RES 7,(IX+PSFATT) ; Reset public/system file flag - CALL RDDIR ; Get FCB from directory - CALL TSTFCT ; Test if past last entry - JR Z,JSEAR8 ; Yes then jump (note carry always clear) - LD DE,(DCOPY) ; Get FCB pointer - LD A,(DE) ; Get first byte - CP 0E5H ; Test if searching empty directory - JR Z,SEARC1 ; Yes then jump - PUSH DE ; Save FCB pointer - CALL TSTLF ; Test last file on this drive - POP DE ; Restore FCB pointer -JSEAR8: JR NC,SEARC8 ; Yes then jump -SEARC1: CALL CALDIR ; Get entry in directory - LD A,(HL) ; Get first byte directory entry - CP 21H ; Test time stamp - JR Z,SEARCN ; Yes then get next directory entry - LD C,0 ; Clear counter - LD A,(SEARNB) ; Get number of bytes to search for - LD B,A ; Save it in counter -SEARC2: LD A,B ; Test if counter is zero - OR A - JR Z,SEARC9 ; Yes then jump - LD A,(DE) ; Get byte from FCB - XOR '?' ; Test if question mark - AND 7FH ; Mask it - JR Z,SEARC6 ; Yes then jump - LD A,C ; Get FCB counter - OR A ; Test first byte - JR NZ,SEARC3 ; No then jump - LD A,(FLAGS) ; Get flag byte - RRA ; Test public file enable - JR NC,SEARC3 ; ..jump if not - INC HL ; Get pointer to Public Bit - INC HL - BIT 7,(HL) ; Test Public Bit directory - DEC HL ; Restore pointer - DEC HL - JR Z,SEARC3 ; No public file then jump - LD A,(DE) ; Get first byte FCB - CP 0E5H ; Test if searching empty directory - JR Z,SEARC3 ; Yes then jump - -; The following 3 lines of code represent a deviation from the description of -; PUBLIC Files as given in DDJ Article by Bridger Mitchell and Derek McKay of -; Plu*Perfect Systems. The PUBLIC Specification states that Public Files will -; NOT be found by any wildcard reference except when a "?" is in the FCB+0 -; byte. The code here relaxes that requirement as follows: If we are in the -; same user area as the public file, then don't report the file as PUBLIC, but -; find it. This has a nasty side effect - it allows erasing of PUBLIC files -; if we are in the same area. However, these files also show up on the direc- -; tory (they wouldn't otherwise), so at least we should know we're blasting -; them. - - XOR (HL) ; Test FCB = Directory Entry - AND 7FH ; Mask it (setting Zero Flag) - JR Z,SEARC5 ; Jump if user is same - LD A,0FFH - LD (SEARPU),A ; Set Public file found - IF UPATH - CALL SETPSF ; Set Public/System file flag - ELSE - SET 7,(IX+PSFATT) ; Set Public/System file flag - ENDIF - JR SEARC5 ; Jump found - -SEARC3: LD A,C ; Get FCB counter - CP 13 ; Is it User Code? - JR Z,SEARC5 ; ..jump if so..don't test - CP 12 ; Is it an Extent Number? - LD A,(DE) ; ..Get byte from FCB - JR Z,SEARC7 ; ..Jump if Extent Number - XOR (HL) ; Is FCB byte = Directory Entry byte? - AND 07FH ; ..Mask it -SEARC4: JR NZ,SEARCN ; ..jump if not same and get next entry -SEARC5: INC DE ; Increment FCB pointer - INC HL ; Increment Directory Entry pointer - INC C ; Increment counter - DEC B ; Decrement counter - JR SEARC2 ; Test next byte - -SEARC6: DEC A ; Set question mark found flag - LD (SEARQU),A - JR SEARC5 ; Jump found - -SEARC7: - XOR (HL) ; Test extent - CALL SEARC7A ; Mask Extent - JR SEARC4 ; ..and test Result - - -SEARC7A: PUSH BC - LD B,A ; Save Extent - LD A,(NEXTND) ; Get extent mask - CPL ; Complement it - AND MAXEXT ; Mask it - AND B ; Mask extent - POP BC ; Restore counters - RET - -SEARC8: CALL SETFCT ; Error set file counter - JP RETCFF ; Set return code to FF and exit - -SEARC9: LD HL,(SEARQU) ; Get question mark and public found flags - LD A,H - AND L - JR NZ,SEARC4 ; Yes then search for next entry - CALL TSTLF ; Test for last file - CALL NC,SETLF0 ; And update if so - LD HL,(RECDIR) ; Set DE return to directory record - LD (DEVAL),HL ; .. for DateStamper simulation - LD A,(FILCNT) ; Get file counter - AND 3 ; Mask it - LD (PEXIT),A ; And set exit code - XOR A ; Clear exit code search - LD (SEAREX),A - RET ; And return to caller - -; The following code is common to DELETE, RENAME, and CSTAT. -; It is coded in a manner that is compatable with the Z280 -; in protected Mode. - -COMCOD: CALL CHKRO ; Check disk W/P - CALL SEAR12 ; Search file -COMCO1: CALL TSTFCT ; Test if file found - POP HL ; Routine addr to HL (in case not found) - RET Z ; Not then exit - PUSH HL ; ..found, so routine back to stack - PUSH HL ; Twice, as RET pops first push - LD HL,COMCO2 - EX (SP),HL ; COMCO2 to stack, routine addr to HL - JP (HL) ; ..branch to routine - -COMCO2: CALL WRFCB ; Write directory buffer on disk - CALL SEARCN ; Search next entry - JR COMCO1 ; And test it - - -; Rename File - Note Wildcard Support - -RENAM: CALL COMCOD ; Go to common code w/VRENAM on stack - -VRENAM: CALL CHKFRO ; Check file W/P - LD HL,(ARWORD) - LD DE,16 ; Offset to new name - ADD HL,DE ; Add offset - EX DE,HL ; Copy HL=>DE - CALL CALDIR ; Get directory entry - INC HL - INC HL - RES 7,(HL) ; Make any renamed file private - DEC HL - DEC HL - LD B,11 ; Set up loop counter -RENAM1: INC HL ; Increment directory pointer - INC DE ; Increment FCB pointer - LD A,(DE) ; Get character from FCB - AND 7FH ; Mask it - CP '?' ; Test if question mark - JR NZ,RENAM2 ; no, then change character on disk - LD A,(HL) ; Else get what's there as there is no change -RENAM2: RLA ; Clear MSB - RL (HL) ; Get MSB from directory - RRA ; And move to FCB - LD (HL),A ; Save in directory - DJNZ RENAM1 ; Loop until done - RET - -; Change Status Bits for File - -CSTAT: CALL COMCOD ; Go to common code w/VCSTAT on stack - -VCSTAT: PUSH IX - POP DE ; FCB pointer in DE - CALL CALDIR ; Get directory entry - LD B,11 ; Set up loop counter -CSTAT1: INC HL ; Increment directory pointer - INC DE ; Increment FCB pointer - LD A,4 ; Are we pointing to Wheel Attribute? - CP B - JR NZ,CSTAT2 ; ..jump if not - PUSH HL - LD HL,(WHEEL) ; Else do we have Wheel privileges? - LD A,(HL) - POP HL - AND A ; ..set flags to show - JR NZ,CSTAT2 ; Jump if we have Wheel - BIT 7,(HL) ; Is file Wheel protected? - JP NZ,CHKFR2 ; ..jump if so -CSTAT2: LD A,(DE) ; Get status bit from FCB - RL (HL) ; Remove MSB of directory - RLA ; Get msb from FCB - RR (HL) ; And move into directory char - DJNZ CSTAT1 ; Loop until done - RET - -; Compute File Size - -FILSZ: LD BC,0 ; Reset file size length - LD D,C - CALL LDRRC ; Save it in FCB+33,34,35 - CALL SEAR12 ; Search file (hfb) -FILSZ0: CALL TSTFCT ; Test if file found - RET Z ; Not then exit - CALL CALDIR ; Get directory entry - EX DE,HL ; Copy to DE - LD HL,15 ; Offset to next record - CALL CALRRC ; Calculate random record count - LD A,D ; Test LSB < (ix+33) - SUB (IX+33) - LD A,C ; Test ISB < (ix+34) - SBC A,(IX+34) - LD A,B ; Test MSB < (ix+35) - SBC A,(IX+35) - CALL NC,LDRRC ; Write new maximum - CALL SEARCN ; Search next file - JR FILSZ0 ; And test it - -; Find File - IF UPATH -FINDF: CALL SRCT15 ; Search file - RET NZ ; Yes then exit - LD A,(FLAGS) - BIT 5,A ; Test if Path enabled - RET Z ; Exit if not - LD HL,(PATH) ; Get Path address - LD A,H ; Test if zero (no path) - OR L - RET Z ; Yes then exit -FINDF0: LD A,(HL) ; Get first entry path name - INC HL ; Increment pointer - OR A ; Test if last entry - JP Z,SEARC8 ; Yes then error exit - AND 7FH ; Mask drive number - CP '$' ; Test if current drive - JR NZ,FINDF1 ; No then jump - LD A,(DRIVE) ; Get current drive - INC A ; Increment drive number -FINDF1: DEC A ; Decrement drive number - PUSH HL ; Save path pointer - CALL SELDK ; Select drive - POP HL ; Restore path pointer - LD A,(HL) ; Get user number - INC HL ; Advance pointer - AND 7FH ; Mask user number - CP '$' ; Test if current user - JR NZ,FINDF2 ; No then jump - LD A,(USER) ; Get current user -FINDF2: AND 1FH ; Mask user number - PUSH HL ; Save path pointer - CALL RESUSR ; Add new user number in FCB+0 and FCB+13 - CALL SRCT15 ; Search file and test if present - POP HL ; Restore path pointer - JR Z,FINDF0 ; No then test next path entry - PUSH HL ; Save path pointer - CALL CALDIR ; Get directory entry - LD DE,10 ; Add offset system bit - ADD HL,DE - BIT 7,(HL) ; Test system file - LD A,(FLAGS) ; Test for relaxed path definition - RLA ; ..by rotating bit.. - RLA ; ..into carry flag - POP HL ; Restore path pointer - JR C,FINDF3 ; If carry, system attrib not required - JR Z,FINDF0 ; No system file then test next path entry -FINDF3: LD A,(DEFDRV) ; Get current drive - INC A ; Increment drive number - LD (FCB0),A ; Save it in exit FCB0 -SETPSF: SET 7,(IX+PSFATT) ; set Public/System file flag - RET ; And return to caller - ENDIF ;Upath - -; Open File Command - -CMND15: CALL SELDRV ; Select drive from FCB - LD (IX+FCBMOD),0 ; Clear data module number - -; Open File - IF UPATH - CALL FINDF ; Find file (use path name) - CALL TSTFCT ; Test file found - ELSE - CALL SRCT15 ; Find file W/O path - ENDIF ;Upath - RET Z ; No then exit -OPENF0: LD A,(IX+PSFATT) ; Get Public/System file bit - PUSH AF ; Save it - LD A,(IX+FCBEXT) ; Get extent number from FCB - PUSH AF ; Save it - CALL CALDIR ; Get directory entry - LD A,(HL) ; Find real user number file is in - OR 80H ; Set user valid flag - PUSH IX ; Save FCB entry - POP DE ; Get in in DE - LD BC,32 ; Number of bytes to move - LDIR ; Move directory to FCB - LD (IX+FCBUSR),A ; And put user byte back - CALL SETB14 ; Set FCB/File Not Modified - LD B,(IX+FCBEXT) ; Get extent number - LD C,(IX+FCBREC) ; Get next record number - POP AF ; Get old extent number - LD (IX+FCBEXT),A ; Save it - CP B ; Compare old and new extent number - JR Z,OPENF1 ; Same then jump - LD C,0 ; Set next record count to 0 - RR C ; Record count to Max (80H) if need new extent -OPENF1: LD (IX+FCBREC),C ; Save next record count - POP AF ; Get Public/System file bit - RL (IX+PSFATT) ; Remove MSB from IX+8 - RLA ; Set new MSB in carry - RR (IX+PSFATT) ; Save Carry in IX+8 - IF ZS - LD HL,(STLAV) ; Get address of last accessed routine - JP STAMPT - ELSE - LD C,5 ; Set access stamp - LD HL,(STLAV) ; Get address of last accessed routine -JPHL: JP (HL) ; ..and Jump to it (or DOTDER) - ENDIF ;Zs - -; Make File Command - -CMND22: CALL SELDRV ; Select drive from FCB - LD (IX+FCBMOD),0 ; Clear data module number - -; Make File - -MAKES: CALL CHKRO ; Check drive W/P - LD HL,(ARWORD) - LD A,(HL) ; Get first byte FCB - PUSH AF ; Save it - LD (HL),0E5H ; Set first byte to empty file - LD A,1 ; Search for 1 byte - CALL SEARCH ; Search empty file - POP AF ; Get first byte FCB - LD (IX+0),A ; Restore it - CALL TSTFCT ; Test empty file found - RET Z ; No then return error - LD HL,(ARWORD) ; Get FCB pointer - CALL CKSUB ; Check if this is a submit file - LD DE,15 ; Prepare offset - ADD HL,DE ; Add it - LD B,17 ; Set loop counter - XOR A -MAKE0: LD (HL),A ; Clear FCB+15 up to FCB+31 - INC HL ; Increment pointer - DJNZ MAKE0 ; And clear all bytes - RES 7,(IX+PSFATT) ; Reset Public/System file bit - RES 7,(IX+ARCATT) ; Reset archive bit if present - CALL CALDIR ; Get directory entry - PUSH IX ; Save FCB entry - POP DE ; Get it in DE - EX DE,HL ; Exchange FCB and directory entry - LD BC,32 ; Number of bytes to move - LDIR ; Move bytes - CALL WRFCB ; Write FCB on disk - CALL SETB14 ; Set file not modified - IF ZS - LD HL,(STCRV) ; Get address of Stamp Create routine - JP STAMPT ; ..and stamp it - ELSE - LD C,0 ; Set Create Stamp - JP STIME ; And exit - ENDIF ;Zs - -; Open Next Extent - -OPENEX: BIT 7,(IX+FCBMOD) ; Test if FCB/File Modified (write) - JR NZ,OPENX2 ; Not then jump - CALL CLOSE ; Close current FCB - LD A,(PEXIT) ; Get exit code - INC A ; Test if error - RET Z ; Yes then exit -OPENX2: CALL CALNEX ; Calculate next extent (LABEL MOVED) - JR C,OPENX3 ; Error then jump - -OPENX0: CALL SRCT15 ; Search for 15-char match & test presence - JR NZ,OPENX5 ; Yes then jump - LD A,(RDWR) ; Test Read/Write flag - OR A ; Test if read - JR Z,OPENX3 ; Yes then error - CALL MAKES ; Make new extent if write - CALL TSTFCT ; Test if succesfull - JR NZ,OPENX6 ; Yes then exit -OPENX3: CALL SETB14 ; Set FCB/File Not Modified -RETCFF: LD A,0FFH ; (hfb/cwc) set exit code -OPENX4: JP SAVEA ; And return to caller - -OPENX5: CALL OPENF0 ; Open file -OPENX6: XOR A ; And clear exit code - JR OPENX4 ; Use same routine - -;==OPENX2: CALL CALNEX ; Calculate next extent -;== JR C,OPENX3 ; Error then jump -;== JR OPENX0 ; Open next extent, FCB contains DU: - -; Calculate Next Extent -; Exit: Carry=1 => Overflow Detected - -CALNEX: CALL GETDME ; Get extent number, data module number - BIT 6,B ; Test error bit random record - SCF ; Set error flag - RET NZ ; ..Error exit if Non-zero - INC C ; Increment extent number - LD A,C ; Get extent number - AND MAXEXT ; Mask it for max extent - LD C,A ; Save it in C -;== JR NZ,SETDME ; If new data module not required - JR NZ,CALNE1 ;== IF NEW DATA MODULE NOT REQUIRED - INC B ; Set next data module - LD A,B ; Get it in A - AND MAXMOD ; Mask it for max module - LD B,A ; Save it in B - SCF ; Set error flag - RET Z ; And return if file overflow -CALNE1: LD (IX+NXTREC),0 ;== ZERO NEXT RECORD COUNT -SETDME: LD (IX+FCBEXT),C ; Save Extent number - LD (IX+FCBMOD),B ; Save Data Module number - IF ZS - AND A ; Clear flag here if ZS - RET - ENDIF ; ..else fall thru on ZD to do same thing - -GETDME: LD C,(IX+FCBEXT) ; Get Extent number - LD B,(IX+FCBMOD) ; Get Data Module number - LD A,C - CALL SEARC7A ; Mask Extent - RES 7,B ; Clear Unmodified Flag - OR B ; Test for Module and Extent = 0 - RET ; ..and return to caller - -; Read Random Record Command - -CMND33: CALL SELDR1 ; Select drive from FCB - -; Read Random Sector - - XOR A ; Set read/write flag - CALL LDFCB ; Load random record in FCB - JR Z,READS ; No error then read sector - RET ; Return error - -; Read Sequential - -CMND20: CALL SELDR1 ; Select drive from FCB - -; Read Sector - -READS: XOR A ; Set Read/Write flag - LD (RDWR),A ; Save it - LD A,(IX+NXTREC) ; Get record counter - CP 80H ; Test if last record this extent -;= JR NC,READS1 ; Yes then open next extent - JR Z,READS1 ;= Yes then open next extent - CP (IX+FCBREC) ; Test if greater then current record - JR C,READS2 ; No then get record -READS0: LD A,1 ; Set end of file flag - JR OPENX4 ; And exit - -READS1: CALL OPNXCK ; Open next extent -READS2: CALL GETDM ; Get block number from DM in FCB - JR Z,READS0 ; Jump if block number=0 to end file - CALL CALSEC ; Calculate Sector Number (128 bytes) - CALL CALST ; Calculate Sector/Track number - CALL READR ; Read data - JP WRITS7 ; Increment elsewhere if necessary - -; Consolidated Routine to Open Extent and check status - -OPNXCK: CALL OPENEX ; Open next extent - LD A,(PEXIT) ; Get exit code - OR A - RET Z ;== IF OPEN OK - POP HL ;== ELSE POP RETURN ADDRESS TO ABORT R/W - JR READS0 ;== AND SET ERROR CODE TO EOF -;== JR NZ,READS0 ; Yes then end of file -;== LD (IX+NXTREC),A ; Clear record counter (jww) -;== RET - -; Write Random Record Command (with and without Zero Fill) - -CMND40: ; (hfb/cwc) -CMND34: CALL SELDR1 ; Select drive from FCB - -; Write Random Sector and Write Random with Zero Fill - - LD A,0FFH ; Set Read/Write flag - CALL LDFCB ; Load FCB from random record - JR Z,WRITES ; No error then write record - RET ; Return error - -; Write Sequential - -CMND21: CALL SELDR1 ; Select drive from FCB - -; Write Sector. Permitted to PUBlic files and those found along Path - -WRITES: LD A,0FFH ; Set read/write flag - LD (RDWR),A ; And save it - -BGPTCH1 EQU $+1 ;<-- Patched location for BGii - - CALL CHKRO ; Check disk W/P - BIT 7,(IX+ROATT) ; Test if file W/P - JR NZ,WRITSA ; Yes then file W/P message - CALL CHKFR3 ; Test W/P if path or Public used - LD HL,(WHEEL) ; Get address of Wheel byte - LD A,(HL) ; Do we have it? - AND A - JR NZ,WRITSB ; Yes - allow write - BIT 7,(IX+WHLATT) ; Else test if Wheel Prot file -WRITSA: JP NZ,CHKFR2 ; Yes then file W/P message -WRITSB: BIT 7,(IX+NXTREC) ; End of this extent? - CALL NZ,OPNXCK ; Open next extent and check status (hfb) - CALL GETDM ; Get block number from FCB - JP NZ,WRITS5 ; Jump to write sector if Block Number <> 0 - PUSH HL ; Save pointer to Block Number - LD A,C ; Test first Block Number in extent - OR A - JR Z,WRITS1 ; Yes then jump - DEC A ; Decrement pointer to Block Number - CALL GETDM4 ; Get previous Block Number - -; Get Free Block from ALV Buffer -; Entry DE=Old Block Number -; Exit DE=New Block Number (0 if No Free Block) -; HL counts Up,DE counts Down - ; GETFRE routine relocated here inline -WRITS1: LD H,D ; Copy old block to HL - LD L,E -GETFR0: LD A,D ; Test down counter is zero - OR E - JR Z,GETFR1 ; Yes then jump - DEC DE ; Decrememt down counter - PUSH HL ; Save up/down counter - PUSH DE - CALL GETBIT ; Get bit from ALV buffer - RRA ; Test if zero - JR NC,GETFR3 ; Yes then found empty block - POP DE ; Get up/down counter - POP HL -GETFR1: LD BC,(MAXLEN) ; Get maximum ALV length-1 in BC - LD A,L ; Is HL >= length ALV-1? - SUB C ; ..do while preserving HL - LD A,H - SBC A,B - JR NC,GETFR2 ; End buffer then jump - INC HL ; Increment up counter - PUSH DE ; Save down/up counter - PUSH HL - EX DE,HL ; Save up counter in DE - CALL GETBIT ; Get bit from ALV buffer - RRA ; Test if zero - JR NC,GETFR3 ; Yes then found empty block - POP HL ; Get down/up counter - POP DE - JR GETFR0 ; And test next block - -GETFR2: LD A,D ; Test if last block tested - OR E - JR NZ,GETFR0 ; No then test next block - JR WRITSG ; Continue with DE=0 - -GETFR3: SCF ; Set block number used - RLA ; Save bit - CALL SETBT0 ; Put bit in ALV buffer - POP DE ; Get correct counter - POP HL ; Restore stack pointer - ; ..continue with (DE=block number) - -WRITSG: POP HL ; Get pointer to Block Number - LD A,D ; Test if blocknumber = 0 - OR E - JR Z,WRITS8 ; Yes then disk full error - RES 7,(IX+FCBMOD) ; Reset FCB/File Modified - LD (HL),E ; Save blocknumber - LD A,(MAXLEN+1) ; Get number of blocks - OR A ; Is it < 256? - JR Z,WRITS2 ; ..Jump if so - INC HL ; Increment to MSB Block Number - LD (HL),D ; ..and save MSB block number -WRITS2: LD C,2 ; Set write new block flag - LD A,(NMASK) ; Get sector mask - AND (IX+NXTREC) ; Mask with record counter - JR Z,WRITSX ; Zero then Ok (at start new record) - LD C,0 ; Else clear new block flag -WRITSX: LD A,(FUNCT) ; Get function number - SUB 40 ; Test if Write RR with zero fill - JR NZ,WRITS6 ; No then jump - PUSH DE ; Save blocknumber - LD HL,(DIRBUF) ; Use directory buffer for zero fill - LD B,128 ; 128 bytes to clear -WRITS3: LD (HL),A ; Clear directory buffer - INC HL ; Increment pointer - DJNZ WRITS3 ; Clear all bytes - CALL CALSEC ; Calculate sector number (128 bytes) - LD A,(NMASK) ; Get sector mask - LD B,A ; Copy it - INC B ; Increment it to get number of writes - CPL ; Complement sector mask - AND E ; Mask sector number - LD E,A ; And save it - LD C,2 ; Set write new block flag -WRITS4: PUSH HL ; Save registers - PUSH DE - PUSH BC - CALL CALST ; Calculate sector/track - CALL DMADIR ; Set DMA directory buffer - POP BC ; Get write new block flag - PUSH BC ; Save it again - CALL WRITER ; Write record on disk - POP BC ; Restore registers - POP DE - POP HL - LD C,0 ; Clear write new block flag - INC E ; Increment sector number - DJNZ WRITS4 ; Write all blocks - CALL STDMA ; Set user DMA address - POP DE ; Get Block Number -WRITS5: LD C,0 ; Clear write new block flag -WRITS6: RES 7,(IX+FCBMOD) ; Reset FCB/File Modified flag - PUSH BC ; Save it - CALL CALSEC ; Calculate sector number (128 bytes) - CALL CALST ; Calculate Sector/Track - POP BC ; Get write new block flag - CALL WRITER ; Write record on disk - LD A,(IX+NXTREC) ; Get record counter - CP (IX+FCBREC) ; Compare with next record - JR C,WRITS7 ; If less then jump - INC A ; Increment record count - LD (IX+FCBREC),A ; Save it on next record position - RES 7,(IX+FCBMOD) ; Reset FCB/File Modified flag -WRITS7: LD A,(FUNCT) ; Get function number - CP 20 ; (hfb) - RET C ; Return if < 20 (hfb) - CP 21+1 ; (hfb) - RET NC ; Return if > 21 (hfb) - INC (IX+NXTREC) ; Increment record count - RET ; And return to caller - -WRITS8: LD A,2 ; Set disk full error - JP SAVEA ; And return to caller - - -; Load FCB for Random Read/Write -; Exit : Zero Flag = 1 No Error -; 0 Error Occured - -LDFCB: LD (RDWR),A ; Save Read/Write flag - LD A,(IX+33) ; Get first byte random record - LD D,A ; Save it in D - RES 7,D ; Reset MSB to get next record - RLA ; Shift MSB in carry - LD A,(IX+34) ; Load next byte random record - RLA ; Shift Carry - PUSH AF ; Save it - AND MAXEXT ; Mask next extent - LD C,A ; Save it in C - POP AF ; Get byte - RLA ; Shift 4 times - RLA - RLA - RLA - AND 0FH ; Mask it - LD B,A ; Save data module number - LD A,(IX+35) ; Get next byte random record - LD E,6 ; Set random record to large flag - CP 4 ; Test random record to large - JR NC,LDFCB8 ; Yes then error - RLCA ; Shift 4 times - RLCA - RLCA - RLCA - ADD A,B ; Add byte - LD B,A ; Save data module number in B - LD (IX+NXTREC),D ; Set next record count - LD D,(IX+FCBMOD) ; Get data module number - BIT 6,D ; Test error random record - JR NZ,LDFCB0 ; Yes then jump - LD A,C ; Get new extent number - CP (IX+FCBEXT) ; Compare with FCB - JR NZ,LDFCB0 ; Not equal then open next extent - LD A,B ; Get new data module number - XOR (IX+FCBMOD) ; Compare with data module number - AND MAXMOD ; Mask it - JR Z,LDFCB6 ; Equal then return -LDFCB0: BIT 7,D ; Test FCB modified (write) - JR NZ,LDFCB1 ; No then jump - PUSH DE ; Save registers - PUSH BC - CALL CLOSE ; Close extent - POP BC ; Restore registers - POP DE - LD E,3 ; Set close error - LD A,(PEXIT) ; Get exit code - INC A - JR Z,LDFCB7 ; Error then exit -LDFCB1: CALL SETDME ; Save Data Module and Extent - CALL SEAR15 ; Search next FCB - LD A,(PEXIT) ; Get error code - INC A - JR NZ,LDFCB5 ; No error then exit - LD A,(RDWR) ; Get read/write flag - LD E,4 ; Set read empty record - INC A - JR NZ,LDFCB7 ; Read then error - CALL MAKES ; Make new FCB - LD E,5 ; Set make error - LD A,(PEXIT) ; Get error code - INC A - JR Z,LDFCB7 ; Error then exit - JR LDFCB6 ; No error exit (zero set) - -LDFCB5: CALL OPENF0 ; Open file -LDFCB6: JP OPENX6 ; Set zero flag and clear error code - -LDFCB7: LD (IX+FCBMOD),0C0H ; Set random record error -LDFCB8: LD A,E ; Get error code - LD (PEXIT),A ; And save it - OR A ; Clear zero flag -SETB14: SET 7,(IX+FCBMOD) ; (hfb) get FCB/File Not Modified - RET ; And return to caller - -; Calculate Random Record -; Entry HL=Offset in FCB -; DE=FCB Pointer -; Exit D=LSB Random Record -; C=ISB Random Record -; B=MSB Random Record - -CALRRC: ADD HL,DE ; Pointer to FCB+15 or FCB+32 - LD A,(HL) ; Get record number - LD HL,12 ; Offset to extent number - ADD HL,DE ; Get pointer to extent byte - LD D,A ; Save record number - LD A,(HL) ; Get extent byte - AND MAXEXT ; Mask it 000eeeee - RL D ; Shift MSB in Carry Cy=R, d=rrrrrrr0 - ADC A,0 ; Add Carry 00xeeeex - RRA ; Shift 1 time (16 bits) 000xeeee - RR D ; D=xrrrrrrr - LD C,A ; Save ISB - INC HL ; Increment to data module number - INC HL - LD A,(HL) ; Get data module number 00mmmmmm - RRCA ; Divide module by 16 - RRCA - RRCA - RRCA - PUSH AF ; Save it mmmm00mm - AND 03H ; Mask for maximum module - LD B,A ; Save it 000000mm - POP AF ; Get LSB - AND 0F0H ; Mask it mmmm0000 - ADD A,C ; Add with ISB mmmxeeee - LD C,A ; Save ISB - RET NC ; No carry then return - INC B ; Increment MSB 000000mm - RET ; And return to caller - ; 000000mm mmmxeeee xrrrrrrr - PAGE - IF ZS -;************************************************************************ -;* U n i v e r s a l T i m e / D a t e S u p p o r t * -;************************************************************************ - -; In order to provide time/date support for as many systems as possible, -; a set of universal routines are used. These routines do not do the -; actual stamping, but provide all the data required to method specific -; programs to perform the needed services. To use the DOS services, the -; external handler needs to tie itself into the Time/Date vector table -; in the ZSDOS configuration area. The Get Stamp, Put Stamp, Stamp Last -; Access, Stamp Create, and Stamp Modify routines receive the following -; parameters in the Z80 registers: -; A = Offset to DIR entry [0,20H,40H,60H] -; BC = Address of ZSDOS WRFCB routine -; DE = Pointer to Directory Buffer -; HL = DMA address -; IX = Pointer to FCB passed to DOS -; The directory buffer contains the dir entry for the FCB passed to DOS, -; A contains the offset. The disk has been tested for R/O on all calls -; except get stamp and is R/W. If a CP/M+ style stamping is used, a simple -; call to the address passed in BC is used to update the disk after adding -; the time as required. This call is ALWAYS required. The routines may -; use AF,BC,DE, and HL without restoring them. Four levels of stack are -; available on the DOS stack for use by the functions. All routines must -; exit with a RET instruction, and A=1 if successful, A=0FFH if error. - -; Get/put Timestamps - -CMD102: -CMD103: CALL SELDRV ; Select DU: from FCB - CALL SRCT15 ; Find the FCB - JR Z,DOTDER ; If not found - LD HL,(GETSTV) ; Get time stamp function address - LD A,(FUNCT) - CP 102 ; Get stamp? - JR Z,DOTDR3 ; Yes - LD HL,(PUTSTV) ; Get address of set stamp routine - ; ..fall thru to common code.. -; Enter here for Stamp Last Access, Stamp Create, Stamp Modify - -STAMPT: PUSH HL - CALL CHKRO1 ; Test for disk W/P but avoid error trap - POP HL - JR Z,DOTDER ; No stamp if disk is W/P - -DOTDR3: CALL GETDME ; Get Data Module and Extent Number - JR NZ,DOTDER ; ..Quit if Not Extent 0 of Module 0 - LD A,(SECPNT) ; Offset to FCB in dirbuf - LD DE,(DIRBUF) ; Dir buffer pointer - LD BC,WRFCB ; Address of WRFCB routine - PUSH HL ; Save function vector - LD HL,(DMA) ; Put DMA in HL - RET ; Then vector to routine - -; Time and Date Routines. Like the date stamping routines, the user must -; supply the actual driver routines for time and date. These routines are -; attached to ZSDOS via the vector table in the configuration area. The -; routines are passed the address to Get/Put the Time and Date in the DE -; and IX registers. The routines may use AF,BC, and D without restor- -; ing them. Four levels of stack are available on the DOS stack for use -; by the the functions. All routines must exit with a RET instruction, -; and A=1 if successful, A=0FFH if error. -; In order to better provide for internal DateStamper, the clock routines -; must save the value at DE+5 when called, and return this value to the -; DOS in the E register. In addition, the HL register must be returned -; as the called DE value +5. -; The Time/Date string consists of 6 packed BCD digits arrayed as: -; Byte 00 01 02 03 04 05 -; YY MM DD HH MM SS - -; Set Time/Date from user-supplied buffer string - -CMD99: LD C,1 ; Set parameter to set time/date - DEFB 21H ; ..and fall thru to GSTD - -; Get Time/Date to string whose address is supplied by the user - -CMD98: LD C,0 ; Set parameter to get time/date -GSTD: LD HL,(GSTIME) ; Get time/date get/set routine address - PUSH HL ; ..to stack for pseudo "Jump" -DOTDER: OR 0FFH ; Save 1 T state while setting flags - RET ; Vector to service routine - ENDIF ;Zs - PAGE - IF ~ZS -;--------------------------------------------------------------------- -; Z D D O S T i m e R o u t i n e s -;--------------------------------------------------------------------- -; STIME - Set file's time and date in !!!TIME&.DAT file -; -; Entry: SECPNT and RECDIR set by search for file. -; BC = 10 - set Modify date/time -; BC = 5 - set Last Access date/time -; BC = 0 - set Create date/time, zero modify & access -; -; Exit : Zero Flag Set (Z) if Time Set in !!!TIME&.DAT file -; Zero Flag Reset (NZ) if error or "No Stamp" attribute Set -; -; Note : Only the first extent's stamp is valid. - -STIME: LD A,(TDCHEK) ; See if !!!TIME&.DAT -RETNZ: OR A ; ..file on disk, clear Carry - RET NZ ; No. (NZ) flags error - - BIT 7,(IX+3) ; Datestamper (tm) "no stamp" bit - RET NZ ; Don't stamp this file - - PUSH BC - CALL GETDME ; See if this is Extent 0 of Module 0 - POP BC - RET NZ ; Quit Now if it isn't - - LD B,A ; Zero B - LD A,(FUNCT) ; Get Current Function - CP 102 ; Is it Get Stamp? - JR Z,STIME0 ; ..jump to skip R/O test if so - CALL CHKRO1 ; Else test for Disk R/O w/o Error Exit - JP Z,DOTDER ; ..and Quit if Error - -STIME0: PUSH BC ; Save 0, 5, or 10 - -; 1. Get disk sector number of file's T&D record, save offset in T&D -; sector for later. - - ; Carry cleared from above - LD A,(SECPNT) ; 0-relative dir. sector offset - ; ..of file FCB (0, 32, 64, or 96) - RRA ; Divide by 2 for !!!TIME&.DAT offset - ; ..a = 0, 16, 32, or 48 - LD HL,(RECDIR) ; 0-relative directory sector of FCB - SRL H ; Divide by 2 to get 0-relative - ; ..sector of T&D file in HL - RR L ; Odd directory sector sets Carry - JR NC,STIME1 - ADD A,64 ; Point to 2nd half of record -STIME1: PUSH AF ; Save pointer for T&D record - PUSH HL ; Save !!!TIME&.DAT file sector - LD HL,(NDIR0) ; Get DIR Alloc Bitmap - LD A,(NMASK) ; Get Block Mask - INC A ; +1 = Number of Records/Block - LD E,A ; Save Records/Block in E - LD D,B ; Extent, B is 0 from above - LD B,16 ; Iterate 16 times -STIME2: ADD HL,HL ; Shift next DIR Alloc bit out to Carry - JR NC,STIME2A ; No Add if No Alloc Bit - EX (SP),HL ; Alloc to Stack, Records into HL - ADD HL,DE ; Add another Alloc worth of records - EX (SP),HL ; Records back to stack, Alloc to HL -STIME2A: DJNZ STIME2 ; Loop until all 16 bits done - POP HL ; Restore !!!TIME&.DATE Record Number - -; 2. Read T&D sector from disk. - - CALL STDIR2 ; Set track and sector of T&D file - CALL READDR ; Read it to DIRBUF - -; 3. Check T&D sector. - - CALL STIME6 ; Check checksum - CP (HL) - JR NZ,TDERR ; Report error - -; 4. Get stamp (GetStp) or set stamp in dirbuf, using offset (tdpnt) - - POP AF ; Get record pointer - CALL CALDIR1 ; Get HL = pointer to stamp in DIRBUF - POP BC ; C = 0, 5, or 10 (offset) - LD A,(FUNCT) - CP 102 ; Get stamp? - RET Z ; Yes, just point with HL - CP 103 ; Set stamp from DMA? - JR Z,STIME4 - - ADD HL,BC ; Add offset (0, 5, 10) - PUSH BC ; Save 0, 5, 10 - CALL CMD98A ; Load 6 bytes from clock to HL - POP BC ; Restore entry parm. - INC A ; 0FFH --> 0 on clock error - JR Z,DOTDER ; ..jump to set NZ status on error - LD (HL),E ; Restore HL+5 (restore only if clock) - LD A,C ; Test entry parameter - OR A ; Set create stamp? - JR NZ,STIME5 ; No, write to disk as is - - LD B,10 ; Yes, -STIME3: LD (HL),A ; Zero the - INC HL ; Access and - DJNZ STIME3 ; Modify dates - JR STIME5 ; And write to disk - -STIME4: LD DE,(DMA) ; Setstp get time from DMA - EX DE,HL ; HL points to DMA - ; DE points to stamp in DIRBUF - LD BC,15 ; Copy 15 bytes to DIRBUF - LDIR - ;..fall thru - -; 5. Reset T&D checksum and write stamped sector to disk. - -STIME5: CALL STIME6 ; Get checksum in A, (HL) = chk byte - LD (HL),A ; Update checksum - CALL WRITD1 ; Write DIRBUF to !!!TIME&.DAT file - XOR A ; Set to (Z), no errors - RET ; Stime done. - -; Don't crash pgm on T&D Err, just return with err - -TDERR: POP HL - POP HL ; Clean up the stack -;= JR GSEXIT ; ..and return error - jr DOTDER ; ..and return error - -; ------------------------------------------------------------------ -; CMND102 - Return file's 15 byte stamp at DMA -; Entry: DE --> FCB of file (wildcards allowed) -; Exit : (DMA) holds 10 byte file stamp -; A = 1 if Ok, Else A = 0FFH if File or Datestamp not found -; DMA contents undefined if error. -; -; CMND103 - Set file's 10 byte stamp from DMA -; Entry: DE --> FCB of file (wildcards allowed) -; (DMA) holds 10 byte file stamp -; Exit : A = 1 if File DateStamp updated (Only first extent is valid) -; A = 0FFH if File/Datestamp not found or "No stamp" attribute set - -CMD102: -CMD103: CALL SELDRV ; Select drive from FCB - CALL SRCT15 ; Search file, test found - JR Z,DOTDER ; ..jump error exit if File Not Found - LD A,(FUNCT) ; Get or set? - CP 103 ; Set? - JR Z,SETSTP ; ..jump if yes - - RES 7,(IX+3) ; Get. clear "no stamp" - CALL STIME ; Point to start of stamp - JR NZ,GSEXIT ; ..Exit w/Error if No Stamping allowed - LD BC,15 ; Load 15 bytes - CALL MV2DMA ; Move data to DMA address - JR GSEXIT - -SETSTP: CALL STIME ; Set from DMA - -GSEXIT: JP Z,READS0 ; Jump to set "1" success status if Ok.. - JP RETCFF ; ..else set 0FFH Error status - -; -------- -; Label for DS version - -CMD98A: EX DE,HL ; Prepare for STIME call - -; Get Time/Date to string whose address is supplied by the user - -CMD98: LD C,0 ; Set parameter to get time/date - DEFB 21H ; ..set for fall thru to GSTD - -; Set Time/Date from User-supplied Buffer string - -CMD99: LD C,1 ; Set parameter to Set Time/Date - -; Clock interface. Clock module must be ZDS DateStamper compatible -; Modified to ZDS DateStamper parameter passing - -GSTD: LD HL,(GSTIME) ; Get time/date get/set routine address - PUSH HL -DOTDER: OR 0FFH ; set error return - RET ; Vector to service routine - -;..... -; Subroutine to Check/Update the !!!TIME&.DAT checksum - -; Entry: DIRBUF points to T&D record -; Exit : A holds checksum -; HL points to checksum byte in record - -STIME6: XOR A ; Clear A - LD HL,(DIRBUF) - ;..fall thru to do CheckSum.. -;**************************************************************** -;* NOTE: This routine must fall thru to the CKS127 routine just * -;* after the ENDIF, so this sequence must not be altered * -;**************************************************************** - -;------------------ End time routines ------------------------ - ENDIF - -; Calculate checksum of 127 bytes addressed by HL. Return with HL -; pointing to the 128th byte. - -CKS127: LD B,127 ; Test 1st 127 bytes -CKSLP: ADD A,(HL) ; Sum all bytes to A - INC HL - DJNZ CKSLP - RET - - PAGE -;************************************************************** -;* Z S D O S H i g h R A M D a t a * -;************************************************************** - -; High RAM area. These locations are not stored by an IOP or -; BackGrounder. - -CODEND: - IF ROM - IF $-ZSDOS > 0E00H - *** ZSDOS TOO BIG !!!!! *** - ENDIF ;$-zsdos - DSEG - ELSE - IF ZS - IF $-ZSDOS > 0DF1H - *** ZSDOS TOO BIG !!!!! *** - ENDIF ;$-zsdos -; ORG ZSDOS+0DF1H ; Set here for Internal Path - FILL ((ZSDOS+0DF1H) - $),055H - ELSE - IF $-ZSDOS > 0DF9H - *** ZDDOS TOO BIG !!!!! *** - ENDIF ;$-zsdos -; ORG ZSDOS+0DF9H - FILL ((ZSDOS+0DF9H) - $),055H - ENDIF ;Zs - ENDIF ;Rom -HIRAM: - IF ZS -IPATH: DEFB 1,0 ; Internal Path = Drive A, User 0 - DEFW 00,00 ; ..two more blank entries - DEFB 0 ; ...and ending Null -TDFVCT: DEFW 00 ; Time and date file vector - ELSE -TDCHEK: DEFB 0 ; used by ZDDOS for T&D present flag - ENDIF ;Zs -LOGIN: DEFW 00 ; Login vector -DSKWP: DEFW 00 ; Disk write protect vector -HDLOG: DEFW 00 ; Fixed disk login vector - - IF ROM -FREEMEM EQU BIOS-CODEND - ELSE -FREEMEM EQU HIRAM-CODEND - ENDIF ;Rom - -; Variables for use with BGii - -BGLOWL EQU BGHIRAM-BGLORAM ; Size of Low RAM save -BGHIL EQU BGRAMTOP-BGHIRAM ; Size of Hi RAM save - - END ; End program - \ No newline at end of file diff --git a/branches/s100/Source/zsdos.asm b/branches/s100/Source/zsdos.asm deleted file mode 100644 index 0c76166a..00000000 --- a/branches/s100/Source/zsdos.asm +++ /dev/null @@ -1,39 +0,0 @@ -; -;================================================================================================== -; WRAPPER FOR ZSDOS/ZDDOS FOR N8VEM PROJECT -; WAYNE WARTHEN - 2011-01-09 -;================================================================================================== -; -; THE FOLLOWING MACROS DO THE HEAVY LIFTING TO MAKE THE ZSDOS SOURCE -; COMPATIBLE WITH TASM -; -#DEFINE EQU .EQU -#DEFINE NAME \; -#DEFINE PAGE .PAGE -#DEFINE CSEG .CSEG -#DEFINE DSEG .DSEG -#DEFINE ORG .ORG -#DEFINE END .END -#DEFINE IF .IF -#DEFINE ELSE .ELSE -#DEFINE ENDIF .ENDIF -#DEFINE DEFB .DB -#DEFINE DEFW .DW -#DEFINE FILL .FILL -; -; ZSDOS USES A .LIB FILE FOR CONFIGURATION. SINCE TASM HAS NO SUPPORT FOR THIS -; WE JUST INCLUDE THE FILE HERE. -; -#DEFINE BLD_ZSDOS11 TRUE ; TRUE BUILDS VER 1.1, FALSE BUILDS VER 1.2 -#DEFINE BLD_ZS TRUE ; TRUE FOR ZSDOS BUILD, FALSE FOR ZDDOS BUILD -#DEFINE BLD_ROM FALSE -#INCLUDE "zsdos.lib" -; -; -; ESTABLISH STARTING ADDRESS FOR ZSDOS -; - .ORG 0D800H -; -; NOW INCLUDE THE MAIN SOURCE -; -#INCLUDE "zsdos-gp.z80" \ No newline at end of file diff --git a/branches/s100/Source/zsdos.lib b/branches/s100/Source/zsdos.lib deleted file mode 100644 index a0374525..00000000 --- a/branches/s100/Source/zsdos.lib +++ /dev/null @@ -1,185 +0,0 @@ -; -; WW - CUSTOMIZED FOR N8VEM PROJECT -; - -;..... -; ZSDOS Customization. -HFB, 18 Sept 1987 -; revised 07/17/88 CWC - -FALSE .EQU 0 -TRUE .EQU ~FALSE - -; Set these conditionals before assembly - -;**************************************************************************** -; In the General Public Release version, we have included an equate which -; controls an additional unreleased fix (which only Howard Goldstein found). -; If the following equate is set TRUE, a version 1.1 BDOS will be produced -; which will require no changes to any released utilities. If set to FALSE, -; a version 1.2 BDOS will result, and many support utility libraries and -; overlays will need to be revised to make them function properly. HFB - -;WW - NOW USES BLD_ZSDOS11 TO INHERIT SETTING FROM WRAPPER -ZSDOS11 .EQU BLD_ZSDOS11 ; Set True for Ver 1.1, False for 1.2 - -;**************************************************************************** - -;WW - NOW USES BLD_ZS TO INHERIT SETTING FROM WRAPPER -ZS .EQU BLD_ZS ; Set True for ZSDOS, False for ZDDOS - -;---------- -; Select assembler for ZSDOS. Any modifications to source code must -; support these assemblers at minimum. - -SLR .EQU FALSE ; SLR Z80ASM or SLR180 Assembler, OR ZMAC -ZAS .EQU TRUE ; MITEK/ECHELON ZAS Assembler (3.0 or later) - - IF ZAS - NAME DOS - ENDIF - - IF SLR - .Z80 - NAME ('DOS') - ENDIF - - IF ZAS & ZS - IF ZSDOS11 - .TITLE 'ZSDOS 1.1 - Enhanced CP/M BDOS Replacement' - ELSE ;~Zsdos11 - .TITLE 'ZSDOS 1.2 - Enhanced CP/M BDOS Replacement' - ENDIF ;Zsdos11 - ENDIF - IF ZAS & (~ZS) - IF ZSDOS11 - .TITLE 'ZDDOS 1.1 - Enhanced CP/M BDOS Replacement w/DS' - ELSE ;~Zsdos11 - .TITLE 'ZDDOS 1.2 - Enhanced CP/M BDOS Replacement w/DS' - ENDIF ;Zsdos11 - ENDIF - - IF SLR & ZS - IF ZSDOS11 - TITLE "ZSDOS 1.1 - Enhanced CP/M BDOS Replacement" - ELSE ;~Zsdos11 - TITLE "ZSDOS 1.2 - Enhanced CP/M BDOS Replacement" - ENDIF ;Zsdos11 - ENDIF - IF SLR & (~ZS) - IF ZSDOS11 - TITLE "ZDDOS 1.1 - Enhanced CP/M BDOS Replacement w/DS" - ELSE ;~Zsdos11 - TITLE "ZDDOS 1.2 - Enhanced CP/M BDOS Replacement w/DS" - ENDIF ;Zsdos11 - ENDIF - -;---------- -; P2DOS introduced a search path feature compatible with that used in -; Richard Conn's ZCPR2 and ZCPR3. If a requested file is not located in -; the currently logged Drive/User, the SEARCH routine will sequentially -; scan along the path until either the file is found or the end of the -; path is reached. - - IF ZS -;WW - changed from EQU to #DEFINE to avoid forward reference error in TASM -;PATHAD EQU IPATH ; Set to the desired ZCPR2/3 search path. -#DEFINE PATHAD IPATH - ELSE ; use 0000H to disable path. A short -PATHAD .EQU 00000H ; 3 element internal path is provided - ENDIF ; in ZSDOS. ZDDOS does not use path. - -;---------- -; The WHEEL byte may be sensed from within ZSDOS by setting the following -; address to that of the ZCPR3 WHEEL byte. A value of 0 disables the WHEEL -; byte sensing. - -WHLADR .EQU 00000H ; Set WHEEL byte address (0FDFFH for SB180) - -;---------- -; Some systems, like the Kaypro 4, only recognize changes between single -; and double-sided disks when the system is warm booted; BDOS Function 13 -; (reset disk) will not work. By adding a "hook" to the BIOS of these mach- -; ines and setting RESDSK to TRUE, BDOS functions 13 and 37 will allow changes -; between single and double-sided disks; very handy for disk housekeeping -; utilities such as NSWP, NULU, and cataloging programs. - -; The "hook" is added as follows: Obtain the source to your computer's BIOS. -; Examine the code for WARM BOOT. Somewhere, there should be a call to a rou- -; tine which initializes the disk system after a warm boot, or which detects -; changes between single and double-sided disks. Call this routine DISKINT -; for purposes of discussion. Modify your BIOS's cold boot routine to ini- -; tialize 3 bytes at address SETDSK as "JP DISKINT". The location of SETDSK -; is arbitrary, it may be in your BIOS, or in a reserved spot in CP/M's page 0. - -RESDSK .EQU FALSE - - IF RESDSK -SETDSK .EQU 004BH ; Set to suit your system (bh) - ENDIF ; resdsk (bh) - -;---------- -; The following equate is used to produce separate code and data segments -; for blowing ZSDOS into ROM. Calling BDOS Function 0 will initialize the -; Data Segment to default values. - -ROM .EQU BLD_ROM ; Separate data and code? - -;---------- -; Many ZSDOS features can be controlled while ZSDOS is running by altering -; the FLAG byte. Set the following equate to your desired configuration based -; on your requirements. The individual bit assignments in the FLAG byte are: -; -; Bit - 7 6 5 4 3 2 1 0 -; \ \ \ \ \ \ \ \__Public File Enable (1) / Disable (0) -; \ \ \ \ \ \ \___Public/Path Write Enable (1) / Disable (0) -; \ \ \ \ \ \____Read-Only Enable (1) / Disable (0) -; \ \ \ \ \_____Fast Fixed Disk Relog Enable (1) / Disable (0) -; \ \ \ \______Disk Change Warning Enable (1) / Disable (0) -; \ \ \_______ZCPR2/3 Path Enable (1) / Disable (0) -; \ \________Path without System Enable (1) / Disable (0) -; \_________(Reserved) - -FLGBITS .EQU 01101101B ; PUBLIC On, P/P Write Off, R/O On, - ; Fast Relog On,Disk Change warning Off, - ; Path On, No System path On - -; The operation of Bit 6 represents a deviation from the description of PUBLIC -; Files as given in DDJ Article by Bridger Mitchell and Derek McKay of Plu* -; Perfect Systems. The PUBLIC Specification states that Public Files will NOT -; be found by any wildcard reference except when a "?" is in the FCB+0 byte. -; The code here relaxes that requirement as follows: If we are in the same -; user area as the public file, then don't report the file as PUBLIC, but find -; it. This has a nasty side effect - it allows erasing of PUBLIC files if we -; are in the same area. However, these files also show up on the directory -; (they wouldn't otherwise), so at least we should know we're blasting them. - -;---------- -; Equates for selecting ZSDOS or ZDDOS configurations - -; Since much ZSDOS code must be deleted to embed DateStamper in ZDDOS, the -; following flags do the stripping: -; PICKEY - True = Don't save users' DE register -; CTLREN - True = Add ^R Retype line to cons read, False = No ^R -; UNROLL - True = Inline code for shifts, False = collapse into loops -; UPATH - True = Add User path from OS, False = No OS path search - - IF ZS -CTLREN .EQU TRUE -UNROLL .EQU TRUE -UPATH .EQU TRUE -PICKEY .EQU FALSE - ELSE -CTLREN .EQU FALSE -UNROLL .EQU FALSE -UPATH .EQU FALSE -PICKEY .EQU FALSE - ENDIF - -;---------- -; To Use the Named-COMMON aspect of NZCOM and JETLOADER (tm), the BIOS must -; be referenced from the _BIOS_ name. If operating under this scheme, set -; the ZRL equate to TRUE. With the ZRL equate set to FALSE, a standalone -; .REL file will be produced with no external requirements. - -ZRL .EQU FALSE ; Set True .ZRL file with COMMON for NZCOM, - ; False to produce straight .REL file diff --git a/branches/s100/Support/Clock/LDTIM_N8.COM b/branches/s100/Support/Clock/LDTIM_N8.COM deleted file mode 100644 index 1ce1dfc7..00000000 Binary files a/branches/s100/Support/Clock/LDTIM_N8.COM and /dev/null differ diff --git a/branches/s100/Support/Clock/LDTIM_N8VEM.COM b/branches/s100/Support/Clock/LDTIM_N8VEM.COM deleted file mode 100644 index 1b3e2d10..00000000 Binary files a/branches/s100/Support/Clock/LDTIM_N8VEM.COM and /dev/null differ diff --git a/branches/s100/Support/Clock/LDTIM_SIMH.COM b/branches/s100/Support/Clock/LDTIM_SIMH.COM deleted file mode 100644 index d2959fae..00000000 Binary files a/branches/s100/Support/Clock/LDTIM_SIMH.COM and /dev/null differ diff --git a/branches/s100/Support/Clock/N8CLK.MAC b/branches/s100/Support/Clock/N8CLK.MAC deleted file mode 100644 index 823f8922..00000000 --- a/branches/s100/Support/Clock/N8CLK.MAC +++ /dev/null @@ -1,228 +0,0 @@ - .Z80 -VERS EQU 03 -; -;RTC_BASE EQU 70H ; RTC PORT ON N8VEM/ZETA -RTC_BASE EQU 88H ; RTC PORT ON N8 -; -RTC_DATA EQU 10000000B ; BIT 7 CONTROLS RTC DATA (I/O) LINE -RTC_CLK EQU 01000000B ; BIT 6 CONTROLS RTC CLOCK LINE, 1 = HIGH -RTC_RD EQU 00100000B ; BIT 5 CONTROLS DATA DIRECTION, 1 = READ -RTC_CE EQU 00010000B ; BIT 4 CONTROLS RTC CE LINE, 1 = HIGH (ENABLED) -; - COMMON /_CLKID/ - -DESCST: DEFW 0000 ; Add label here if a static year byte - ; is used by your clock driver. The - ; label should point to the year byte -; 123456789012345678901234 -CLKNAM: DEFB 'N8 DS1302 Clock ' ; Exactly 24 chars in name - DEFB VERS/10+'0','.',VERS MOD 10 +'0',0 -; -DESCR: DEFB 'DS1302 Real-time Clock Driver for N8 Z180',0 -; - COMMON /_PARM_/ -; -PARBAS: DEFW 0 ; # of parameters (Set to 00 if none) - DEFW 0 ; Pointer to STRS (Set to 00 if none) -; - CSEG -; -;------------------------------------------------------------- -; Z S D O S C L O C K H E A D E R -;------------------------------------------------------------- -; Enter: HL = Address to Put Date/Time string -; Exit : Time moved and counter incremented -; A=1 for OK status on exit -; -; Enter: HL points to a 6-byte buffer to Get/Set time -; Exit : A=1 on Success, A=FFH if error -; HL points to last char in buffer -; E contains original seconds (HL+5) - - JP GETTIM ; Get time - JP WRCLK ; Set time -; -BUFSIZE EQU 7 -BUFRTC: -BUFSEC: DEFB 0 ; Second -BUFMIN: DEFB 0 ; Minute -BUFHR: DEFB 0 ; Hour -BUFDT: DEFB 0 ; Date -BUFMON: DEFB 0 ; Month -BUFDAY: DEFB 0 ; Day -BUFYR: DEFB 0 ; Year -; -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; R e a d T h e C l o c k -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -GETTIM: PUSH HL - LD HL,BUFRTC - CALL CLK_RD - - ; COPY DATE/TIME INTO OUTPUT BUFFER - POP HL - LD A,(BUFYR) - LD (HL),A - INC HL - LD A,(BUFMON) - LD (HL),A - INC HL - LD A,(BUFDT) - LD (HL),A - INC HL - LD A,(BUFHR) - LD (HL),A - INC HL - LD A,(BUFMIN) - LD (HL),A - INC HL - LD A,(BUFSEC) - LD (HL),A - LD E,(HL) - - ; RETURN WITH SUCCESS - XOR A - INC A - RET -; -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; S e t T h e C l o c k -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -WRCLK: LD A,(HL) - LD (BUFYR),A - INC HL - LD A,(HL) - LD (BUFMON),A - INC HL - LD A,(HL) - LD (BUFDT),A - INC HL - LD A,(HL) - LD (BUFHR),A - INC HL - LD A,(HL) - LD (BUFMIN),A - INC HL - LD A,(HL) - LD (BUFSEC),A - - PUSH HL - LD HL,BUFRTC - CALL CLK_WR - POP HL - - ; RETURN WITH SUCCESS - XOR A - INC A - RET -; -; BURST READ CLOCK DATA INTO BUFFER AT HL -; -CLK_RD: - LD C,0BFH ; COMMAND = $BF TO BURST READ CLOCK - CALL RTC_CMD ; SEND COMMAND TO RTC - LD B,BUFSIZE ; B IS LOOP COUNTER -CLK_RD1: - PUSH BC ; PRESERVE BC - CALL RTC_GET ; GET NEXT BYTE - LD (HL),A ; SAVE IN BUFFER - INC HL ; INC BUF POINTER - POP BC ; RESTORE BC - DJNZ CLK_RD1 ; LOOP IF NOT DONE - XOR A ; ALL LINES OFF TO CLEAN UP - OUT (RTC_BASE),A ; WRITE TO RTC PORT - RET -; -; BURST WRITE CLOCK DATA FROM BUFFER AT HL -; -CLK_WR: - LD C,08EH ; COMMAND = $8E TO WRITE CONTROL REGISTER - CALL RTC_CMD ; SEND COMMAND - XOR A ; $00 = UNPROTECT - CALL RTC_PUT ; SEND VALUE TO CONTROL REGISTER -; - LD C,0BEH ; COMMAND = $BE TO BURST WRITE CLOCK - CALL RTC_CMD ; SEND COMMAND TO RTC - LD B,BUFSIZE ; B IS LOOP COUNTER -CLK_WR1: - PUSH BC ; PRESERVE BC - LD A,(HL) ; GET NEXT BYTE TO WRITE - CALL RTC_PUT ; PUT NEXT BYTE - INC HL ; INC BUF POINTER - POP BC ; RESTORE BC - DJNZ CLK_WR1 ; LOOP IF NOT DONE - LD A,80H ; ADD CONTROL REG BYTE, $80 = PROTECT ON - CALL RTC_PUT ; WRITE REQUIRED 8TH BYTE - XOR A ; ALL LINES OFF TO CLEAN UP - OUT (RTC_BASE),A ; WRITE TO RTC PORT - RET -; -; SEND COMMAND IN C TO RTC -; -RTC_CMD: - LD A,RTC_RD ; CE LOW TO RESET RTC - OUT (RTC_BASE),A ; WRITE IT - LD A,C ; LOAD COMMAND - CALL RTC_PUT ; WRITE IT - RET -; -; WRITE BYTE IN A TO THE RTC -; -RTC_PUT: - LD B,8 ; LOOP FOR 8 BITS -RTC_PUT1: - RRCA ; ROTATE NEXT BIT TO SEND INTO BIT 7 - LD C,A ; SAVE WORKING VALUE - AND 10000000B ; ISOLATE THE DATA BIT - OR RTC_CE ; ADD CHIP ENABLE, CLOCK HIGH - OUT (RTC_BASE),A ; WRITE TO PORT WITH CLOCK LOW - XOR RTC_CLK ; TURN CLOCK BACK ON - OUT (RTC_BASE),A ; WRITE TO PORT WITH CLOCK HIGH - LD A,C ; RECOVER WORKING VALUE - DJNZ RTC_PUT1 ; LOOP IF NOT DONE - RET -; -; READ BYTE FROM RTC, RETURN VALUE IN A -; -RTC_GET: - LD C,0 ; INITIALIZE WORKING VALUE TO 0 - LD B,8 ; LOOP FOR 8 BITS -RTC_GET1: - LD A,RTC_RD+RTC_CE ; LOWER CLOCK, CE STAYS HI, READ IS ON - OUT (RTC_BASE),A ; WRITE TO RTC PORT - NOP ; SETTLE - IN A,(RTC_BASE) ; READ THE RTC PORT - AND 00000001B ; ISOLATE THE DATA BIT - OR C ; COMBINE WITH WORKING VALUE - RRCA ; ROTATE FOR NEXT BIT - LD C,A ; SAVE WORKING VALUE - LD A,RTC_CLK+RTC_RD+RTC_CE ; CLOCK BACK TO HIGH NOW - OUT (RTC_BASE),A ; WRITE TO RTC PORT - DJNZ RTC_GET1 ; LOOP IF NOT DONE - LD A,C ; GET RESULT INTO A - RET -; -; -; - COMMON /_POST_/ - RET ; This RETURN MUST be present even if no other - ; code is included in this section - - COMMON /_PRE_/ -; -;--------------------------------------------------------------- -; Read clock and wait for seconds to roll - watchdog protected -; Enter with: DE pointing to relocated clock read routine -; HL pointing to base of high module - -TSTRD: JR TSTRD0 ; Jump around address store - - DEFW TSTRD ; Org location of the code - -TSTRD0: SCF - LD A,1 - RET - - END diff --git a/branches/s100/Support/Clock/N8CLK.REL b/branches/s100/Support/Clock/N8CLK.REL deleted file mode 100644 index ad756732..00000000 Binary files a/branches/s100/Support/Clock/N8CLK.REL and /dev/null differ diff --git a/branches/s100/Support/Clock/N8VEMCLK.MAC b/branches/s100/Support/Clock/N8VEMCLK.MAC deleted file mode 100644 index daabf6d5..00000000 --- a/branches/s100/Support/Clock/N8VEMCLK.MAC +++ /dev/null @@ -1,228 +0,0 @@ - .Z80 -VERS EQU 03 -; -RTC_BASE EQU 70H ; RTC PORT ON N8VEM/ZETA -;RTC_BASE EQU 88H ; RTC PORT ON N8 -; -RTC_DATA EQU 10000000B ; BIT 7 CONTROLS RTC DATA (I/O) LINE -RTC_CLK EQU 01000000B ; BIT 6 CONTROLS RTC CLOCK LINE, 1 = HIGH -RTC_RD EQU 00100000B ; BIT 5 CONTROLS DATA DIRECTION, 1 = READ -RTC_CE EQU 00010000B ; BIT 4 CONTROLS RTC CE LINE, 1 = HIGH (ENABLED) -; - COMMON /_CLKID/ - -DESCST: DEFW 0000 ; Add label here if a static year byte - ; is used by your clock driver. The - ; label should point to the year byte -; 123456789012345678901234 -CLKNAM: DEFB 'N8VEM DS1302 Clock ' ; Exactly 24 chars in name - DEFB VERS/10+'0','.',VERS MOD 10 +'0',0 -; -DESCR: DEFB 'DS1302 Real-time Clock Driver for N8VEM Z80',0 -; - COMMON /_PARM_/ -; -PARBAS: DEFW 0 ; # of parameters (Set to 00 if none) - DEFW 0 ; Pointer to STRS (Set to 00 if none) -; - CSEG -; -;------------------------------------------------------------- -; Z S D O S C L O C K H E A D E R -;------------------------------------------------------------- -; Enter: HL = Address to Put Date/Time string -; Exit : Time moved and counter incremented -; A=1 for OK status on exit -; -; Enter: HL points to a 6-byte buffer to Get/Set time -; Exit : A=1 on Success, A=FFH if error -; HL points to last char in buffer -; E contains original seconds (HL+5) - - JP GETTIM ; Get time - JP WRCLK ; Set time -; -BUFSIZE EQU 7 -BUFRTC: -BUFSEC: DEFB 0 ; Second -BUFMIN: DEFB 0 ; Minute -BUFHR: DEFB 0 ; Hour -BUFDT: DEFB 0 ; Date -BUFMON: DEFB 0 ; Month -BUFDAY: DEFB 0 ; Day -BUFYR: DEFB 0 ; Year -; -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; R e a d T h e C l o c k -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -GETTIM: PUSH HL - LD HL,BUFRTC - CALL CLK_RD - - ; COPY DATE/TIME INTO OUTPUT BUFFER - POP HL - LD A,(BUFYR) - LD (HL),A - INC HL - LD A,(BUFMON) - LD (HL),A - INC HL - LD A,(BUFDT) - LD (HL),A - INC HL - LD A,(BUFHR) - LD (HL),A - INC HL - LD A,(BUFMIN) - LD (HL),A - INC HL - LD A,(BUFSEC) - LD (HL),A - LD E,(HL) - - ; RETURN WITH SUCCESS - XOR A - INC A - RET -; -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; S e t T h e C l o c k -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; -WRCLK: LD A,(HL) - LD (BUFYR),A - INC HL - LD A,(HL) - LD (BUFMON),A - INC HL - LD A,(HL) - LD (BUFDT),A - INC HL - LD A,(HL) - LD (BUFHR),A - INC HL - LD A,(HL) - LD (BUFMIN),A - INC HL - LD A,(HL) - LD (BUFSEC),A - - PUSH HL - LD HL,BUFRTC - CALL CLK_WR - POP HL - - ; RETURN WITH SUCCESS - XOR A - INC A - RET -; -; BURST READ CLOCK DATA INTO BUFFER AT HL -; -CLK_RD: - LD C,0BFH ; COMMAND = $BF TO BURST READ CLOCK - CALL RTC_CMD ; SEND COMMAND TO RTC - LD B,BUFSIZE ; B IS LOOP COUNTER -CLK_RD1: - PUSH BC ; PRESERVE BC - CALL RTC_GET ; GET NEXT BYTE - LD (HL),A ; SAVE IN BUFFER - INC HL ; INC BUF POINTER - POP BC ; RESTORE BC - DJNZ CLK_RD1 ; LOOP IF NOT DONE - XOR A ; ALL LINES OFF TO CLEAN UP - OUT (RTC_BASE),A ; WRITE TO RTC PORT - RET -; -; BURST WRITE CLOCK DATA FROM BUFFER AT HL -; -CLK_WR: - LD C,08EH ; COMMAND = $8E TO WRITE CONTROL REGISTER - CALL RTC_CMD ; SEND COMMAND - XOR A ; $00 = UNPROTECT - CALL RTC_PUT ; SEND VALUE TO CONTROL REGISTER -; - LD C,0BEH ; COMMAND = $BE TO BURST WRITE CLOCK - CALL RTC_CMD ; SEND COMMAND TO RTC - LD B,BUFSIZE ; B IS LOOP COUNTER -CLK_WR1: - PUSH BC ; PRESERVE BC - LD A,(HL) ; GET NEXT BYTE TO WRITE - CALL RTC_PUT ; PUT NEXT BYTE - INC HL ; INC BUF POINTER - POP BC ; RESTORE BC - DJNZ CLK_WR1 ; LOOP IF NOT DONE - LD A,80H ; ADD CONTROL REG BYTE, $80 = PROTECT ON - CALL RTC_PUT ; WRITE REQUIRED 8TH BYTE - XOR A ; ALL LINES OFF TO CLEAN UP - OUT (RTC_BASE),A ; WRITE TO RTC PORT - RET -; -; SEND COMMAND IN C TO RTC -; -RTC_CMD: - LD A,RTC_RD ; CE LOW TO RESET RTC - OUT (RTC_BASE),A ; WRITE IT - LD A,C ; LOAD COMMAND - CALL RTC_PUT ; WRITE IT - RET -; -; WRITE BYTE IN A TO THE RTC -; -RTC_PUT: - LD B,8 ; LOOP FOR 8 BITS -RTC_PUT1: - RRCA ; ROTATE NEXT BIT TO SEND INTO BIT 7 - LD C,A ; SAVE WORKING VALUE - AND 10000000B ; ISOLATE THE DATA BIT - OR RTC_CE ; ADD CHIP ENABLE, CLOCK HIGH - OUT (RTC_BASE),A ; WRITE TO PORT WITH CLOCK LOW - XOR RTC_CLK ; TURN CLOCK BACK ON - OUT (RTC_BASE),A ; WRITE TO PORT WITH CLOCK HIGH - LD A,C ; RECOVER WORKING VALUE - DJNZ RTC_PUT1 ; LOOP IF NOT DONE - RET -; -; READ BYTE FROM RTC, RETURN VALUE IN A -; -RTC_GET: - LD C,0 ; INITIALIZE WORKING VALUE TO 0 - LD B,8 ; LOOP FOR 8 BITS -RTC_GET1: - LD A,RTC_RD+RTC_CE ; LOWER CLOCK, CE STAYS HI, READ IS ON - OUT (RTC_BASE),A ; WRITE TO RTC PORT - NOP ; SETTLE - IN A,(RTC_BASE) ; READ THE RTC PORT - AND 00000001B ; ISOLATE THE DATA BIT - OR C ; COMBINE WITH WORKING VALUE - RRCA ; ROTATE FOR NEXT BIT - LD C,A ; SAVE WORKING VALUE - LD A,RTC_CLK+RTC_RD+RTC_CE ; CLOCK BACK TO HIGH NOW - OUT (RTC_BASE),A ; WRITE TO RTC PORT - DJNZ RTC_GET1 ; LOOP IF NOT DONE - LD A,C ; GET RESULT INTO A - RET -; -; -; - COMMON /_POST_/ - RET ; This RETURN MUST be present even if no other - ; code is included in this section - - COMMON /_PRE_/ -; -;--------------------------------------------------------------- -; Read clock and wait for seconds to roll - watchdog protected -; Enter with: DE pointing to relocated clock read routine -; HL pointing to base of high module - -TSTRD: JR TSTRD0 ; Jump around address store - - DEFW TSTRD ; Org location of the code - -TSTRD0: SCF - LD A,1 - RET - - END diff --git a/branches/s100/Support/Clock/N8VEMCLK.REL b/branches/s100/Support/Clock/N8VEMCLK.REL deleted file mode 100644 index 3011f09d..00000000 Binary files a/branches/s100/Support/Clock/N8VEMCLK.REL and /dev/null differ diff --git a/branches/s100/Support/Clock/ReadMe.txt b/branches/s100/Support/Clock/ReadMe.txt deleted file mode 100644 index 0c94e119..00000000 --- a/branches/s100/Support/Clock/ReadMe.txt +++ /dev/null @@ -1,5 +0,0 @@ -This directory contains the source and assembled versions of the ZSystem Clock Drivers for N8VEM & N8. - -The .MAC files can be compiled using M80 with a command line such as "M80 =N8VEMCLK.MAC". - -LDTIM_N8VEM.COM and LDTIM_N8.COM are copies of LDT for N8VEM and N8 respectively. They were constructed useing SETUPZST using the clock drivers included here. They are both setup to load as Resident System Extentions with support for DateStamper style date stamping. \ No newline at end of file diff --git a/branches/s100/Support/Clock/SIMHCLOK.MAC b/branches/s100/Support/Clock/SIMHCLOK.MAC deleted file mode 100644 index ecff5b84..00000000 --- a/branches/s100/Support/Clock/SIMHCLOK.MAC +++ /dev/null @@ -1,81 +0,0 @@ -VERS EQU 03 - .Z80 - - COMMON /_CLKID/ - -DESCST: DEFW 0000 ; Add label here if a static year byte - ; is used by your clock driver. The - ; label should point to the year byte -; 123456789012345678901234 -CLKNAM: DEFB 'Altair Z80 SIMH Clock ' ; Exactly 24 chars in name - DEFB VERS/10+'0','.',VERS MOD 10 +'0',0 - -DESCR: DEFB 'This is the Altair Z80 SIMH clock',0 - - - COMMON /_PARM_/ - -PARBAS: DEFW 0 ; # of parameters (Set to 00 if none) - DEFW 0 ; Pointer to STRS (Set to 00 if none) - - CSEG - -;----------------------------------------------------------- -; Z S D O S C L O C K H E A D E R -;----------------------------------------------------------- -; Enter: HL points to a 6-byte buffer to Get/Set time -; Exit : A=1 on Success, A=FFH if error -; HL points to last char in buffer -; E contains original seconds (HL+5) - -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; R e a d T h e C l o c k -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -SIMHPORT EQU 0FEH -READCLOCK EQU 7 -WRITECLOCK EQU 8 -PARBLOCKSIZE EQU 6 - -PRGBAS: JP GETTIM ; Jump to Read Clock - JP WRCLK ; Jump to Set Clock -GETTIM: LD A,READCLOCK - OUT (SIMHPORT),A - LD BC,256*(PARBLOCKSIZE-1)+SIMHPORT ; B := 5, C := 0FEH - INIR - ; bug fixed by Howard Goldstein (via Lee Bradley), 26-Jul-2007 - LD E,(HL) ; Save original seconds in E - INI ; READ SECONDS - DEC HL - LD A,1 ; Set OK status return - RET - -WRCLK: LD A,WRITECLOCK - OUT (SIMHPORT),A - LD A,L - OUT (SIMHPORT),A - LD A,H - OUT (SIMHPORT),A - LD A,1 - RET - - COMMON /_POST_/ - RET ; This RETURN MUST be present even if no other - ; code is included in this section - - COMMON /_PRE_/ - -;--------------------------------------------------------------- -; Read clock and wait for seconds to roll - watchdog protected -; Enter with: DE pointing to relocated clock read routine -; HL pointing to base of high module - -TSTRD: JR TSTRD0 ; Jump around address store - - DEFW TSTRD ; Org location of the code -TSTRD0: SCF - LD A,1 - RET - - END - \ No newline at end of file diff --git a/branches/s100/Support/Clock/SIMHCLOK.REL b/branches/s100/Support/Clock/SIMHCLOK.REL deleted file mode 100644 index 31e91b38..00000000 Binary files a/branches/s100/Support/Clock/SIMHCLOK.REL and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/ParPortProp.eeprom b/branches/s100/Support/ParPortProp/ParPortProp.eeprom deleted file mode 100644 index 77349c50..00000000 Binary files a/branches/s100/Support/ParPortProp/ParPortProp.eeprom and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/E555_SPKEngine.spin b/branches/s100/Support/ParPortProp/Spin/E555_SPKEngine.spin deleted file mode 100644 index 02e55e87..00000000 --- a/branches/s100/Support/ParPortProp/Spin/E555_SPKEngine.spin +++ /dev/null @@ -1 +0,0 @@ -{{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // E555 Speaker Engine // // Author: Kwabena W. Agyeman // Updated: 7/27/2010 // Designed For: P8X32A // Version: 1.1 // // Copyright (c) 2010 Kwabena W. Agyeman // See end of file for terms of use. // // Update History: // // v1.0 - Original release - 8/26/2009. // v1.1 - Added support for variable pin assignments - 7/27/2010. // // For each included copy of this object only one spin interpreter should access it at a time. // // Nyamekye, /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Speaker Circuit: // // SpeakerPinNumber --- Speaker Driver (Active High). // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }} PUB speakerFrequency(newFrequency, speakerPinNumber) '' 10 Stack Longs '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// '' // Changes the speaker frequency using the SPIN interpreter's counter modules. '' // '' // NewFrequency - The new frequency. Between 0 Hz and 80MHz @ 80MHz. -1 to reset the pin and counter modules. '' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// speakerSetup((newFrequency <> -1), speakerPinNumber) newFrequency := ((newFrequency <# clkfreq) #> 0) result := 1 repeat 32 newFrequency <<= 1 result <-= 1 if(newFrequency => clkfreq) newFrequency -= clkfreq result += 1 frqa := result~ phsb := 0 PUB speakerVolume(newVolume, speakerPinNumber) '' 10 Stack Longs '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// '' // Changes the speaker volume using the SPIN interpreter's counter modules. '' // '' // NewVolume - The new volume. Between 0% and 100%. -1 to reset the pin and counter modules. '' // SpeakerPinNumber - Pin to use to drive the speaker circuit. Between 0 and 31. '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// speakerSetup((newVolume <> -1), speakerPinNumber) frqb := (((100 - ((newVolume <# 100) #> 0)) * constant(posx / 50)) | $7) PRI speakerSetup(activeOrInactive, speakerPinNumber) ' 5 Stack Longs speakerPinNumber := ((speakerPinNumber <# 31) #> 0) dira[speakerPinNumber] := activeOrInactive outa[speakerPinNumber] := false ctra := ((constant(%0_0100 << 26) + speakerPinNumber) & activeOrInactive) ctrb := ((constant(%0_0110 << 26) + speakerPinNumber) & activeOrInactive) {{ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // TERMS OF USE: MIT License /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the // Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// }} \ No newline at end of file diff --git a/branches/s100/Support/ParPortProp/Spin/FullDuplexSerial.spin b/branches/s100/Support/ParPortProp/Spin/FullDuplexSerial.spin deleted file mode 100644 index b248f963..00000000 Binary files a/branches/s100/Support/ParPortProp/Spin/FullDuplexSerial.spin and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/FullDuplexSerialNull.spin b/branches/s100/Support/ParPortProp/Spin/FullDuplexSerialNull.spin deleted file mode 100644 index 7a03e7ab..00000000 Binary files a/branches/s100/Support/ParPortProp/Spin/FullDuplexSerialNull.spin and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/Keyboard.spin b/branches/s100/Support/ParPortProp/Spin/Keyboard.spin deleted file mode 100644 index 67d8b081..00000000 Binary files a/branches/s100/Support/ParPortProp/Spin/Keyboard.spin and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/ParPortProp.spin b/branches/s100/Support/ParPortProp/Spin/ParPortProp.spin deleted file mode 100644 index f788c6ce..00000000 Binary files a/branches/s100/Support/ParPortProp/Spin/ParPortProp.spin and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/Parallax Serial Terminal Null.spin b/branches/s100/Support/ParPortProp/Spin/Parallax Serial Terminal Null.spin deleted file mode 100644 index 982e894c..00000000 Binary files a/branches/s100/Support/ParPortProp/Spin/Parallax Serial Terminal Null.spin and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/Parallax Serial Terminal.spin b/branches/s100/Support/ParPortProp/Spin/Parallax Serial Terminal.spin deleted file mode 100644 index a525a4be..00000000 Binary files a/branches/s100/Support/ParPortProp/Spin/Parallax Serial Terminal.spin and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/VGA_1024.spin b/branches/s100/Support/ParPortProp/Spin/VGA_1024.spin deleted file mode 100644 index 624d7331..00000000 --- a/branches/s100/Support/ParPortProp/Spin/VGA_1024.spin +++ /dev/null @@ -1,703 +0,0 @@ -'' VGA_1024.spin -'' -'' MODIFIED BY VINCE BRIEL FOR POCKETERM FEATURES -'' MODIIFED BY JEFF LEDGER / AKA OLDBITCOLLECTOR -'' - -CON - cols = 80 '128 ' number of screen columns - lcols = cols / 4 ' number of long in columns - rows = 40 '64 ' number of screen rows - chars = rows*cols ' number of screen characters - esc = $CB ' keyboard esc char - rowsnow = 36 ' adjusted for split screen effect - maxChars = rowsnow*cols ' adjusted value for split screen effect - lastChar = maxChars / 4 ' last screen position in longs adjusted for split - lastLine = (rowsnow - 1) * cols ' character position of last row - cols1 = 81 ' adjusted value for 80th character - TURQUOISE = $29 - -OBJ - vga : "vga_Hires_Text" - -VAR - byte screen[chars] ' screen character buffer - byte tmpl[cols] ' temporary line buffer - word colors[rows] ' color specs for each screen row (see ColorPtr description above) - byte cursor[6] ' cursor info array (see CursorPtr description above) - long sync, loc, xloc, yloc ' sync used by VGA routine, others are local screen pointers - long kbdreq ' global val of kbdflag - long BR[8] - long Brate - byte inverse - byte invs - byte state ' Current state of state machine - word pos ' Current Position on the screen - word oldpos ' Previous location of cursor before update - word regionTop, regionBot ' Scroll region top/bottom - long arg0 ' First argument of escape sequence - long arg1 ' Second argument of escape sequence - byte lastc ' Last displayed char - word statpos - long vgabasepin - -PUB start(BasePin) | i, char - vgabasepin := BasePin - -''init screen colors to gold on blue - repeat i from 0 to rows - 1 - colors[i] := $08F0 '$2804 (if you want cyan on blue) - -''init cursor attributes - cursor[2] := %110 ' init cursor to underscore with slow blink - BR[0]:=300 - BR[1]:=1200 - BR[2]:=2400 - BR[3]:=4800 - BR[4]:=9600 - BR[5]:=19200 - BR[6]:=38400 - BR[7]:=57600 - BR[8]:=115200 - xloc := cursor[0] := 0 - yloc := cursor[1] := 0 - loc := xloc + yloc*cols - - pos := 0 - regionTop := 0 - regionBot := 35 * cols - state := 0 - statpos := 37 * cols - -PUB vidon - if (!vga.start(vgabasepin, @screen, @colors, @cursor, @sync)) - return false - - waitcnt(clkfreq * 1 + cnt) 'wait 1 second for cogs to start - - -PUB vidoff - vga.stop - -PUB inv(c) - inverse:=c - -PUB color(colorVal) | i - repeat i from 0 to rows - 1 - colors[i] := $0000 | colorVal - -PUB cursorset(c) | i - i:=%000 - if c == 1 - i:= %001 - if c == 2 - i:= %010 - if c == 3 - i:= %011 - if c == 4 - i:= %101 - if c == 5 - i:= %110 - if c == 6 - i:= %111 - if c == 7 - i:= %000 - cursor[2] := i - -PUB bin(value, digits) - -'' Print a binary number, specify number of digits - - repeat while digits > 32 - outc("0") - digits-- - - value <<= 32 - digits - - repeat digits - outc((value <-= 1) & 1 + "0") - - -PUB clrbtm(ColorVal) | i - repeat i from 36 to rows - 1 'was 35 - colors[i] := $0000 + ColorVal - -PUB cls1(c,screencolor,pcport,ascii,CR) | i,x,y - - longfill(@screen[0], $20202020, chars / 4) - - clrbtm(TURQUOISE) - - inverse := 1 - - statprint(36,0, string(" N8VEM ParPortProp | RomWBW v0.92")) - inverse := 0 - statprint(37,0, string(" ")) - statprint(38,0, string(" ")) - statprint(39,0, string(" ")) - - -{{ - x :=xloc - y := yloc - invs := inverse - ''clrbtm(TURQUOISE) - longfill(@screen, $20202020, chars/4) - xloc := 0 - yloc :=0 - loc := xloc + yloc*cols - repeat 80 - outc(32) - xloc := 0 - yloc :=36 - loc := xloc + yloc*cols - inverse := 1 - str(string(" propIO V 0.91 ")) - inverse := 0 - str(string("Baud Rate: ")) - i:= BR[6] - dec(i) - str(string(" ")) - xloc := 18 - loc := xloc + yloc*cols - str(string("Color ")) - str(string("PC Port: ")) - if pcport == 1 - str(string("OFF ")) - if pcport == 0 - str(string("ON ")) - str(string(" Force 7 bit: ")) - if ascii == 0 - str(string("NO ")) - if ascii == 1 - str(string("YES ")) - str(string(" Cursor CR W/LF: ")) - if CR == 1 - str(string("YES")) - if CR == 0 - str(string("NO ")) - outc(13) - outc(10) - - inverse:=1 - xloc := 6 - loc := xloc + yloc*cols - str(string("F1")) - xloc := 19 - loc := xloc + yloc*cols - str(string("F2")) - xloc := 30 - loc := xloc + yloc*cols - str(string("F3")) - xloc := 46 - loc := xloc + yloc*cols - str(string("F4")) - xloc := 58 - loc := xloc + yloc*cols - str(string("F5")) - xloc := 70 - loc := xloc + yloc*cols - str(string("F6")) - inverse := invs - xloc := cursor[0] := x 'right & left was 0 - yloc := cursor[1] := y 'from top was 1 - loc := xloc + yloc*cols -}} - -PUB clsupdate(c,screencolor,PCPORT,ascii,CR) | i,x,y,locold - - invs := inverse - locold := loc - x := xloc - y := yloc - ''(TURQUOISE) - xloc := 0 - yloc :=36 - loc := xloc + yloc*cols - inverse := 1 - str(string(" propIO V 0.81 ")) - inverse := 0 - xloc := 0 - yloc :=37 - loc := xloc + yloc*cols - str(string("Baud Rate: ")) - i:= BR[6] - dec(i) - str(string(" ")) - xloc := 18 - loc := xloc + yloc*cols - - str(string("Color ")) - str(string("PC Port: ")) - if pcport == 1 - str(string("OFF ")) - if pcport == 0 - str(string("ON ")) - str(string(" Force 7 bit: ")) - if ascii == 0 - str(string("NO ")) - if ascii == 1 - str(string("YES ")) - str(string(" Cursor CR W/LF: ")) - if CR == 1 - str(string("YES")) - if CR == 0 - str(string("NO ")) - xloc := 0 - yloc :=38 - loc := xloc + yloc*cols - inverse:=1 - xloc := 6 - loc := xloc + yloc*cols - str(string("F1")) - xloc := 19 - loc := xloc + yloc*cols - str(string("F2")) - xloc := 30 - loc := xloc + yloc*cols - str(string("F3")) - xloc := 46 - loc := xloc + yloc*cols - str(string("F4")) - xloc := 58 - loc := xloc + yloc*cols - str(string("F5")) - xloc := 70 - loc := xloc + yloc*cols - str(string("F6")) - inverse := invs - xloc := cursor[0] := x - yloc := cursor[1] := y -' loc := xloc + yloc*cols - loc := locold - -PUB dec(value) | i - -'' Print a decimal number - - if value < 0 - -value - outc("-") - - i := 1_000_000_000 - - repeat 10 - if value => i - outc(value/i + "0") - value //= i - result~~ - elseif result or i == 1 - outc("0") - i /= 10 - -PUB hex(value, digits) - -'' Print a hexadecimal number, specify number of digits - - repeat while digits > 8 - outc("0") - digits-- - - value <<= (8 - digits) << 2 - - repeat digits - outc(lookupz((value <-= 4) & $f : "0".."9", "A".."F")) - - -PUB str(string_ptr) - -'' Print a zero terminated string - - repeat strsize(string_ptr) - process_char(byte[string_ptr++]) - -PUB statprint(r, c, str1) | x, ptr - - ptr := r * cols + c - repeat x from 0 to STRSIZE(str1) - 1 - putc(ptr++, BYTE[str1 + x]) - -PUB statnum(r, c, num1) | i, ptr - - ptr := r * cols + c - - if num1 < 0 - -num1 - putc(ptr++,"-") - - i := 1_000_000_000 - - repeat 10 - if num1 => i - putc(ptr++, (num1/i +"0")) - num1 //= i - result~~ - elseif result or i == 1 - putc(ptr++, "0") - i /= 10 - -PUB putc(position, c) - if inverse - c |= $80 - screen[position] := c - -PUB cls - longfill (@screen, $20202020, lastChar) - -PUB fullcls - longfill(@screen, $20202020, 800) - -PUB setInverse(val) - inverse := val - -PUB setInv(c) - if c == 7 - setInverse(1) - else - setInverse(0) - -PUB clEOL(position) | count - count := cols - (position // cols) - bytefill(@screen + position, $20, count) - -PUB clBOL(position) | count - count := position // cols - bytefill(@screen + position - count, $20, count) - -PUB delLine(position) | src, count - position -= position // cols - - src := position + cols - - count := (maxChars - src) / 4 - - if count > 0 - longmove(@screen + position, @screen + src, count) - - longfill(@screen + lastLine, $20202020, lcols) - -PUB clEOS(position) - cleol(position) - position += cols - (position // cols) - repeat while position < maxChars - longfill(@screen + position, $20202020, lcols) - pos += cols - -PUB setCursorPos(position) - cursor[0] := position // cols - cursor[1] := position / cols - -PUB insLine(position) | base, nxt - base := position - (position // cols) - position := lastLine - repeat while position > base - nxt := position - cols - longmove(@screen + position, @screen + nxt, lcols) - position := nxt - clEOL(base) - -PUB insChar(position) | count - count := (cols - (position // cols)) - 1 - bytemove(@tmpl, @screen + position, count) - screen[position] := " " - bytemove(@screen + position + 1, @tmpl, count) - -PUB delChar(position) | count - count := (cols - (position // cols)) - 1 - bytemove(@screen + position, @screen + position + 1, count) - screen[position + count] := " " - -PRI inRegion : answer - answer := (pos => regionTop) AND (pos < regionBot) - -PRI scrollUp - delLine(regionTop) - if regionBot < maxChars - insLine(regionBot) - -PRI scrollDown - if regionBot < maxChars - delLine(regionBot) - insLine(regionTop) - -PRI ansi(c) | x, defVal - - state := 0 - - if (c <> "r") AND (c <> "J") AND (c <> "m") AND (c <> "K") - if arg0 == -1 - arg0 := 1 - if arg1 == -1 - arg1 := 1 - - case c - "@": - repeat while arg0-- > 0 - insChar(pos) - - "b": - repeat while arg0-- > 0 - outc(lastc) - - "d": - if (arg0 < 1) OR (arg0 > rows) - arg0 := rows - pos := ((arg0 - 1) * cols) + (pos // cols) - - "m": - setInv(arg0) - if arg1 <> -1 - setInv(arg1) - - "r": - if arg0 < 1 - arg0 := 1 - elseif arg0 > cols - arg0 := cols - if arg1 < 1 - arg1 := 1 - elseif arg1 > cols - arg1 := cols - if arg1 < arg0 - arg1 := arg0 - - regionTop := (arg0 - 1) * cols - regionBot := arg1 * cols - pos := 0 - - "A": - repeat while arg0-- > 0 - pos -= cols - if pos < 0 - pos += cols - return - - "B": - repeat while arg0-- > 0 - pos += cols - if pos => maxChars - pos -= cols - return - - "C": - repeat while arg0-- > 0 - pos += 1 - if pos => maxChars - pos -= 1 - return - - "D": - repeat while arg0-- > 0 - pos -= 1 - if pos < 0 - pos := 0 - return - - "G": - if (arg0 < 1) OR (arg0 > cols) - arg0 := cols - pos := (pos - (pos // cols)) + (arg0 - 1) - - "H", "f": - if arg0 =< 0 - arg0 := 1 - if arg1 =< 0 - arg1 := 1 - pos := (cols * (arg0 - 1)) + (arg1 - 1) - if pos < 0 - pos := 0 - if pos => maxChars - pos := maxChars - 1 - - "J": - if arg0 == 1 - clBOL(pos) - x := pos - cols - x -= x // cols - repeat while x => 0 - clEOL(x) - x -= cols - return - - if arg0 == 2 - pos := 0 - - clEOL(pos) - x := pos + cols - x -= (x // cols) - repeat while x < maxChars - clEOL(x) - x += cols - - "K": - if arg0 == -1 - clEOL(pos) - elseif arg0 == 1 - clBOL(pos) - else - clEOL(pos - (pos // cols)) - - "L": - if inRegion - repeat while arg0-- > 0 - if regionBot < maxChars - delLine(regionBot) - insLine(pos) - - "M": - if inRegion - repeat while arg0-- > 0 - delLine(pos) - if regionBot < maxChars - insLine(regionBot) - - "P": - repeat while arg0-- - delChar(pos) - -PRI outc(c) - - putc(pos++, lastc := c) - if pos == regionBot - scrollUp - pos -= cols - elseif pos == maxChars - pos := lastLine - -PUB process_char(c) - - case state - - 0: - if c > 127 - c := $20 - - if c => $20 - outc(c) - setCursorPos(pos) - return - - if c == $1B - state := 1 - return - - if c == $0D - pos := pos - (pos // cols) - setCursorPos(pos) - return - - if c == $0A - if inRegion - pos += cols - if pos => regionBot - scrollUp - pos -= cols - else - pos += cols - if pos => maxChars - pos -= cols - setCursorPos(pos) - return - - if c == 9 - pos += (8 - (pos // 8)) - - if pos => maxChars - pos := lastLine - delLine(0) - - setCursorPos(pos) - return - - if c == 8 - if pos > 0 - pos -= 1 - setCursorPos(pos) - return - - 1: - case c - "[": - arg0 := arg1 := -1 - state := 2 - return - - "P": - pos += cols - if pos => maxChars - pos -= cols - - "K": - if pos > 0 - pos -= 1 - - "H": - pos -= cols - if pos < 0 - pos += cols - - "D": - if inRegion - scrollUp - - "M": - if inRegion - scrollDown - - "G": - pos := 0 - - "(": - state := 5 - return - - state := 0 - return - - 2: - if (c => "0") AND (c =< "9") - if arg0 == -1 - arg0 := c - "0" - else - arg0 := (arg0 * 10) + (c - "0") - return - - if c == ";" - state := 3 - return - - ansi(c) - setCursorPos(pos) - return - - 3: - if (c => "0") AND (c =< "9") - if arg1 == -1 - arg1 := c - "0" - else - arg1 := (arg1 * 10) + (c - "0") - return - - if c == ";" - state := 4 - return - - ansi(c) - setCursorPos(pos) - return - - 4: - if (c => "0") AND (c =< "9") - return - - if c == ";" - return - ansi(c) - setCursorPos(pos) - return - - 5: - state := 0 - return - - return \ No newline at end of file diff --git a/branches/s100/Support/ParPortProp/Spin/VGA_HiRes_Text.spin b/branches/s100/Support/ParPortProp/Spin/VGA_HiRes_Text.spin deleted file mode 100644 index 5b892316..00000000 Binary files a/branches/s100/Support/ParPortProp/Spin/VGA_HiRes_Text.spin and /dev/null differ diff --git a/branches/s100/Support/ParPortProp/Spin/safe_spi.spin b/branches/s100/Support/ParPortProp/Spin/safe_spi.spin deleted file mode 100644 index a63cb229..00000000 --- a/branches/s100/Support/ParPortProp/Spin/safe_spi.spin +++ /dev/null @@ -1,920 +0,0 @@ -{{ - SPI interface routines for SD & SDHC & MMC cards - - Jonathan "lonesock" Dummer - version 0.3.0 2009 July 19 - - Using multiblock SPI mode exclusively. - - This is the "SAFE" version...uses - * 1 instruction per bit writes - * 2 instructions per bit reads - - For the fsrw project: - fsrw.sf.net -}} - -CON - ' possible card types - type_MMC = 1 - type_SD = 2 - type_SDHC = 3 - - ' Error codes - ERR_CARD_NOT_RESET = -1 - ERR_3v3_NOT_SUPPORTED = -2 - ERR_OCR_FAILED = -3 - ERR_BLOCK_NOT_LONG_ALIGNED = -4 - '... - ' These errors are for the assembly engine...they are negated inside, and need to be <= 511 - ERR_ASM_NO_READ_TOKEN = 100 - ERR_ASM_BLOCK_NOT_WRITTEN = 101 - ' NOTE: errors -128 to -255 are reserved for reporting R1 response errors - '... - ERR_SPI_ENGINE_NOT_RUNNING = -999 - ERR_CARD_BUSY_TIMEOUT = -1000 - - ' SDHC/SD/MMC command set for SPI - CMD0 = $40+0 ' GO_IDLE_STATE - CMD1 = $40+1 ' SEND_OP_COND (MMC) - ACMD41 = $C0+41 ' SEND_OP_COND (SDC) - CMD8 = $40+8 ' SEND_IF_COND - CMD9 = $40+9 ' SEND_CSD - CMD10 = $40+10 ' SEND_CID - CMD12 = $40+12 ' STOP_TRANSMISSION - CMD13 = $40+13 ' SEND_STATUS - ACMD13 = $C0+13 ' SD_STATUS (SDC) - CMD16 = $40+16 ' SET_BLOCKLEN - CMD17 = $40+17 ' READ_SINGLE_BLOCK - CMD18 = $40+18 ' READ_MULTIPLE_BLOCK - CMD23 = $40+23 ' SET_BLOCK_COUNT (MMC) - ACMD23 = $C0+23 ' SET_WR_BLK_ERASE_COUNT (SDC) - CMD24 = $40+24 ' WRITE_BLOCK - CMD25 = $40+25 ' WRITE_MULTIPLE_BLOCK - CMD55 = $40+55 ' APP_CMD - CMD58 = $40+58 ' READ_OCR - CMD59 = $40+59 ' CRC_ON_OFF - - ' buffer size for my debug cmd log - 'LOG_SIZE = 256<<1 - -{ -VAR - long SPI_engine_cog - ' these are used for interfacing with the assembly engine | temporary initialization usage - long SPI_command ' "t", "r", "w", 0 =>done, <0 => error | pin mask - long SPI_block_index ' which 512-byte block to read/write | cnt at init - long SPI_buffer_address ' where to get/put the data in Hub RAM | unused -'} -DAT -'' I'm placing these variables in a DAT section to make this driver a singleton. -'' If for some reason you really need more than one driver (e.g. if you have more -'' than a single SD socket), move these back into VAR. -SPI_engine_cog long 0 -' these are used for interfacing with the assembly engine | temporary initialization usage -SPI_command long 0 ' "t", "r", "w", 0 =>done, <0 => error | unused -SPI_block_index long 0 ' which 512-byte block to read/write | cnt at init -SPI_buffer_address long 0 ' where to get/put the data in Hub RAM | unused - -{ -VAR - ' for debug ONLY - byte log_cmd_resp[LOG_SIZE+1] -PUB get_log_pointer - return @log_cmd_resp -'} - -PUB start( basepin ) -{{ - This is a compatibility wrapper, and requires that the pins be - both consecutive, and in the order DO CLK DI CS. -}} - return start_explicit( basepin, basepin+1, basepin+2, basepin+3 ) - -PUB readblock( block_index, buffer_address ) - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - if (buffer_address & 3) - abort ERR_BLOCK_NOT_LONG_ALIGNED - SPI_block_index := block_index - SPI_buffer_address := buffer_address - SPI_command := "r" - repeat while SPI_command == "r" - if SPI_command < 0 - abort SPI_command - -PUB writeblock( block_index, buffer_address ) - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - if (buffer_address & 3) - abort ERR_BLOCK_NOT_LONG_ALIGNED - SPI_block_index := block_index - SPI_buffer_address := buffer_address - SPI_command := "w" - repeat while SPI_command == "w" - if SPI_command < 0 - abort SPI_command - -PUB get_seconds - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - SPI_command := "t" - repeat while SPI_command == "t" - ' secods are in SPI_block_index, remainder is in SPI_buffer_address - return SPI_block_index - -PUB get_milliseconds : ms - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - SPI_command := "t" - repeat while SPI_command == "t" - ' secods are in SPI_block_index, remainder is in SPI_buffer_address - ms := SPI_block_index * 1000 - ms += SPI_buffer_address * 1000 / clkfreq - -PUB start_explicit( DO, CLK, DI, CS ) : card_type | tmp, i -{{ - Do all of the card initialization in SPIN, then hand off the pin - information to the assembly cog for hot SPI block R/W action! -}} - ' Start from scratch - stop - ' clear my log buffer - { - bytefill( @log_cmd_resp, 0, LOG_SIZE+1 ) - dbg_ptr := @log_cmd_resp - dbg_end := dbg_ptr + LOG_SIZE - '} - ' wait ~4 milliseconds - waitcnt( 500 + (clkfreq>>8) + cnt ) - ' (start with cog variables, _BEFORE_ loading the cog) - pinDO := DO - maskDO := |< DO - pinCLK := CLK - pinDI := DI - maskDI := |< DI - maskCS := |< CS - adrShift := 9 ' block = 512 * index, and 512 = 1<<9 - ' pass the output pin mask via the command register - maskAll := maskCS | (| 74 clocks - outa |= maskAll - repeat 4096 - outa[CLK]~~ - outa[CLK]~ - ' time-hack - SPI_block_index := cnt - ' reset the card - tmp~ - repeat i from 0 to 9 - if tmp <> 1 - tmp := send_cmd_slow( CMD0, 0, $95 ) - if (tmp & 4) - ' the card said CMD0 ("go idle") was invalid, so we're possibly stuck in read or write mode - if i & 1 - ' exit multiblock read mode - repeat 4 - read_32_slow ' these extra clocks are required for some MMC cards - send_slow( $FD, 8 ) ' stop token - read_32_slow - repeat while read_slow <> $FF - else - ' exit multiblock read mode - send_cmd_slow( CMD12, 0, $61 ) - if tmp <> 1 - ' the reset command failed! - crash( ERR_CARD_NOT_RESET ) - ' Is this a SD type 2 card? - if send_cmd_slow( CMD8, $1AA, $87 ) == 1 - ' Type2 SD, check to see if it's a SDHC card - tmp := read_32_slow - ' check the supported voltage - if (tmp & $1FF) <> $1AA - crash( ERR_3v3_NOT_SUPPORTED ) - ' try to initialize the type 2 card with the High Capacity bit - repeat while send_cmd_slow( ACMD41, |<30, $77 ) - ' the card is initialized, let's read back the High Capacity bit - if send_cmd_slow( CMD58, 0, $FD ) <> 0 - crash( ERR_OCR_FAILED ) - ' get back the data - tmp := read_32_slow - ' check the bit - if tmp & |<30 - card_type := type_SDHC - adrShift := 0 - else - card_type := type_SD - else - ' Either a type 1 SD card, or it's MMC, try SD 1st - if send_cmd_slow( ACMD41, 0, $E5 ) < 2 - ' this is a type 1 SD card (1 means busy, 0 means done initializing) - card_type := type_SD - repeat while send_cmd_slow( ACMD41, 0, $E5 ) - else - ' mark that it's MMC, and try to initialize - card_type := type_MMC - repeat while send_cmd_slow( CMD1, 0, $F9 ) - ' some SD or MMC cards may have the wrong block size, set it here - send_cmd_slow( CMD16, 512, $15 ) - ' card is mounted, make sure the CRC is turned off - send_cmd_slow( CMD59, 0, $91 ) - ' check the status - 'send_cmd_slow( CMD13, 0, $0D ) - ' done with the SPI bus for now - outa |= maskCS - ' set my counter modes for super fast SPI operation - ' writing: NCO single-ended mode, output on DI - writeMode := (%00100 << 26) | (DI << 0) - ' reading - 'readMode := (%11000 << 26) | (DO << 0) | (CLK << 9) - ' clock - 'clockLineMode := (%00110 << 26) | (CLK << 0) ' DUTY, 25% duty cycle - ' clock - clockLineMode := (%00100 << 26) | (CLK << 0) ' NCO, 50% duty cycle - ' how many bytes (8 clocks, >>3) fit into 1/2 of a second (>>1), 4 clocks per instruction (>>2)? - N_in8_500ms := clkfreq >> constant(1+2+3) - ' how long should we wait before auto-exiting any multiblock mode? - idle_limit := 125 ' ms, NEVER make this > 1000 - idle_limit := clkfreq / (1000 / idle_limit) ' convert to counts - ' Hand off control to the assembly engine's cog - bufAdr := @SPI_buffer_address - sdAdr := @SPI_block_index - SPI_command := 0 ' just make sure it's not 1 - ' start my driver cog and wait till I hear back that it's done - SPI_engine_cog := cognew( @SPI_engine_entry, @SPI_command ) + 1 - if( SPI_engine_cog == 0 ) - crash( ERR_SPI_ENGINE_NOT_RUNNING ) - repeat while SPI_command <> -1 - ' and we no longer need to control any pins from here - dira &= !maskAll - ' the return variable is card_type - -PUB release -{{ - I do not want to abort if the cog is not - running, as this is called from stop, which - is called from start/ [8^) -}} - if SPI_engine_cog - SPI_command := "z" - repeat while SPI_command == "z" - -PUB stop -{{ - kill the assembly driver cog. -}} - release - if SPI_engine_cog - cogstop( SPI_engine_cog~ - 1 ) - -PRI crash( abort_code ) -{{ - In case of Bad Things(TM) happening, - exit as gracefully as possible. -}} - ' and we no longer need to control any pins from here - dira &= !maskAll - ' and report our error - abort abort_code - -PRI send_cmd_slow( cmd, val, crc ) : reply | time_stamp -{{ - Send down a command and return the reply. - Note: slow is an understatement! - Note: this uses the assembly DAT variables for pin IDs, - which means that if you run this multiple times (say for - multiple SD cards), these values will change for each one. - But this is OK as all of these functions will be called - during the initialization only, before the PASM engine is - running. -}} - ' if this is an application specific command, handle it - if (cmd & $80) - ' ACMD is the command sequense of CMD55-CMD - cmd &= $7F - reply := send_cmd_slow( CMD55, 0, $65 ) - if (reply > 1) - return reply - ' the CS line needs to go low during this operation - outa |= maskCS - outa &= !maskCS - ' give the card a few cocks to finish whatever it was doing - read_32_slow - ' send the command byte - send_slow( cmd, 8 ) - ' send the value long - send_slow( val, 32 ) - ' send the CRC byte - send_slow( crc, 8 ) - ' is this a CMD12?, if so, stuff byte - if cmd == CMD12 - read_slow - ' read back the response (spec declares 1-8 reads max for SD, MMC is 0-8) - time_stamp := 9 - repeat - reply := read_slow - while( reply & $80 ) and ( time_stamp-- ) - ' done, and 'reply' is already pre-loaded - { - if dbg_ptr < (dbg_end-1) - byte[dbg_ptr++] := cmd - byte[dbg_ptr++] := reply - if (cmd&63) == 13 - ' get the second byte - byte[dbg_ptr++] := cmd - byte[dbg_ptr++] := read_slow - '} - -PRI send_slow( value, bits_to_send ) - value ><= bits_to_send - repeat bits_to_send - outa[pinCLK]~ - outa[pinDI] := value - value >>= 1 - outa[pinCLK]~~ - -PRI read_32_slow : r - repeat 4 - r <<= 8 - r |= read_slow - -PRI read_slow : r -{{ - Read back 8 bits from the card -}} - ' we need the DI line high so a read can occur - outa[pinDI]~~ - ' get 8 bits (remember, r is initialized to 0 by SPIN) - repeat 8 - outa[pinCLK]~ - outa[pinCLK]~~ - r += r + ina[pinDO] - ' error check - if( (cnt - SPI_block_index) > (clkfreq << 2) ) - crash( ERR_CARD_BUSY_TIMEOUT ) - -DAT -{{ - This is the assembly engine for doing fast block - reads and writes. This is *ALL* it does! -}} -ORG 0 -SPI_engine_entry - ' Counter A drives data out - mov ctra,writeMode - ' Counter B will always drive my clock line - mov ctrb,clockLineMode - ' set our output pins to match the pin mask - mov dira,maskAll - ' handshake that we now control the pins - neg user_request,#1 - wrlong user_request,par - ' start my seconds' counter here - mov last_time,cnt - -waiting_for_command - ' update my seconds counter, but also track the idle - ' time so we can to release the card after timeout. - call #handle_time - ' read the command, and make sure it's from the user (> 0) - rdlong user_request,par - cmps user_request,#0 wz,wc -if_be jmp #waiting_for_command - ' handle our card based commands - cmp user_request,#"r" wz -if_z jmp #read_ahead - cmp user_request,#"w" wz -if_z jmp #write_behind - cmp user_request,#"z" wz -if_z jmp #release_card - ' time requests are handled differently - cmp user_request,#"t" wz ' time -if_z wrlong seconds,sdAdr ' seconds goes into the SD index register -if_z wrlong dtime,bufAdr ' the remainder goes into the buffer address register - ' in all other cases, clear the user's request - mov user_request,#0 - wrlong user_request,par - jmp #waiting_for_command - - -release_card - mov user_cmd,#"z" ' request a release - neg lastIndexPlus,#1 ' reset the last block index - neg user_idx,#1 ' and make this match it - call #handle_command - mov user_request,user_cmd - wrlong user_request,par - jmp #waiting_for_command - -read_ahead - rdlong user_idx,sdAdr - ' if the correct block is not already loaded, load it - mov tmp1,user_idx - add tmp1,#1 - cmp tmp1,lastIndexPlus wz -if_z cmp lastCommand,#"r" wz -if_z jmp #:get_on_with_it - mov user_cmd,#"r" - call #handle_command -:get_on_with_it - ' copy the data up into Hub RAM - movi transfer_long,#%000010_000 'set to wrlong - call #hub_cog_transfer - ' signify that the data is ready, Spin can continue - mov user_request,user_cmd - wrlong user_request,par - ' request the next block - mov user_cmd,#"r" - add user_idx,#1 - call #handle_command - ' done - jmp #waiting_for_command - -write_behind - rdlong user_idx,sdAdr - ' copy data in from Hub RAM - movi transfer_long,#%000010_001 'set to rdlong - call #hub_cog_transfer - ' signify that we have the data, Spin can continue - mov user_request,user_cmd - wrlong user_request,par - ' write out the block - mov user_cmd,#"w" - call #handle_command - ' done - jmp #waiting_for_command - -{{ - Set user_cmd and user_idx before calling this -}} -handle_command - ' Can we stay in the old mode? (address = old_address+1) && (old mode == new_mode) - cmp lastIndexPlus,user_idx wz -if_z cmp user_cmd,lastCommand wz -if_z jmp #:execute_block_command - ' we fell through, must exit the old mode! (except if the old mode was "release") - cmp lastCommand,#"w" wz -if_z call #stop_mb_write - cmp lastCommand,#"r" wz -if_z call #stop_mb_read - ' and start up the new mode! - cmp user_cmd,#"w" wz -if_z call #start_mb_write - cmp user_cmd,#"r" wz -if_z call #start_mb_read - cmp user_cmd,#"z" wz -if_z call #release_DO -:execute_block_command - ' track the (new) last index and command - mov lastIndexPlus,user_idx - add lastIndexPlus,#1 - mov lastCommand,user_cmd - ' do the block read or write or terminate! - cmp user_cmd,#"w" wz -if_z call #write_single_block - cmp user_cmd,#"r" wz -if_z call #read_single_block - cmp user_cmd,#"z" wz -if_z mov user_cmd,#0 - ' done -handle_command_ret - ret - -{=== these PASM functions get me in and out of multiblock mode ===} -release_DO - ' we're already out of multiblock mode, so - ' deselect the card and send out some clocks - or outa,maskCS - call #in8 - call #in8 - ' if you are using pull-up resistors, and need all - ' lines tristated, then uncomment the following line. - ' for Cluso99 - 'mov dira,#0 -release_DO_ret - ret - -start_mb_read - movi block_cmd,#CMD18<<1 - call #send_SPI_command_fast -start_mb_read_ret - ret - -stop_mb_read - movi block_cmd,#CMD12<<1 - call #send_SPI_command_fast - call #busy_fast -stop_mb_read_ret - ret - -start_mb_write - movi block_cmd,#CMD25<<1 - call #send_SPI_command_fast -start_mb_write_ret - ret - -stop_mb_write - call #busy_fast - ' only some cards need these extra clocks - mov tmp1,#16 -:loopity - call #in8 - djnz tmp1,#:loopity - ' done with hack - movi phsa,#$FD<<1 - call #out8 - call #in8 ' stuff byte - call #busy_fast -stop_mb_write_ret - ret - -send_SPI_command_fast - ' make sure we have control of the output lines - mov dira,maskAll - ' make sure the CS line transitions low - or outa,maskCS - andn outa,maskCS - ' 8 clocks - call #in8 - ' send the data - mov phsa,block_cmd ' do which ever block command this is (already in the top 8 bits) - call #out8 ' write the byte - mov phsa,user_idx ' read in the desired block index - shl phsa,adrShift ' this will multiply by 512 (bytes/sector) for MMC and SD - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - ' bogus CRC value - call #in8 ' in8 looks like out8 with $FF - ' CMD12 requires a stuff byte - shr block_cmd,#24 - cmp block_cmd,#CMD12 wz -if_z call #in8 ' 8 clocks - ' get the response - mov tmp1,#9 -:cmd_response - call #in8 - test readback,#$80 wc,wz -if_c djnz tmp1,#:cmd_response -if_nz neg user_cmd,readback - ' done -send_SPI_command_fast_ret - ret - - -busy_fast - mov tmp1,N_in8_500ms -:still_busy - call #in8 - cmp readback,#$FF wz -if_nz djnz tmp1,#:still_busy -busy_fast_ret - ret - - -out8 - andn outa,maskDI - 'movi phsb,#%11_0000000 - mov phsb,#0 - movi frqb,#%01_0000000 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - mov frqb,#0 - ' don't shift out the final bit...already sent, but be aware - ' of this when sending consecutive bytes (send_cmd, for e.g.) -out8_ret - ret - -{ -in8 - or outa,maskDI - mov ctra,readMode - ' Start my clock - mov frqa,#1<<7 - mov phsa,#0 - movi phsb,#%11_0000000 - movi frqb,#%01_0000000 - ' keep reading in my value, one bit at a time! (Kuneko - "Wh) - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - mov frqb,#0 ' stop the clock - mov readback,phsa - mov frqa,#0 - mov ctra,writeMode -in8_ret - ret -} -in8 - neg phsa,#1' DI high - mov readback,#0 - ' set up my clock, and start it - movi phsb,#%011_000000 - movi frqb,#%001_000000 - ' keep reading in my value - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - mov frqb,#0 ' stop the clock - rcl readback,#1 - mov phsa,#0 'DI low -in8_ret - ret - - -' this is called more frequently than 1 Hz, and -' is only called when the user command is 0. -handle_time - mov tmp1,cnt ' get the current timestamp - add idle_time,tmp1 ' add the current time to my idle time counter - sub idle_time,last_time ' subtract the last time from my idle counter (hence delta) - add dtime,tmp1 ' add to my accumulator, - sub dtime,last_time ' and subtract the old (adding delta) - mov last_time,tmp1 ' update my "last timestamp" - rdlong tmp1,#0 ' what is the clock frequency? - cmpsub dtime,tmp1 wc ' if I have more than a second in my accumulator - addx seconds,#0 ' then add it to "seconds" - ' this part is to auto-release the card after a timeout - cmp idle_time,idle_limit wz,wc -if_b jmp #handle_time_ret ' don't clear if we haven't hit the limit - mov user_cmd,#"z" ' we can't overdo it, the command handler makes sure - neg lastIndexPlus,#1 ' reset the last block index - neg user_idx,#1 ' and make this match it - call #handle_command ' release the card, but don't mess with the user's request register -handle_time_ret - ret - -hub_cog_transfer -' setup for all 4 passes - mov ctrb,clockXferMode - mov frqb,#1 - rdlong buf_ptr,bufAdr - mov ops_left,#4 - movd transfer_long,#speed_buf -four_transfer_passes - ' sync to the Hub RAM access - rdlong tmp1,tmp1 - ' how many long to move on this pass? (512 bytes / 4)longs / 4 passes - mov tmp1,#(512 / 4 / 4) - ' get my starting address right (phsb is incremented 1 per clock, so 16 each Hub access) - mov phsb,buf_ptr - ' write the longs, stride 4...low 2 bits of phsb are ignored -transfer_long - rdlong 0-0,phsb - add transfer_long,incDest4 - djnz tmp1,#transfer_long - ' go back to where I started, but advanced 1 long - sub transfer_long,decDestNminus1 - ' offset my Hub pointer by one long per pass - add buf_ptr,#4 - ' do all 4 passes - djnz ops_left,#four_transfer_passes - ' restore the counter mode - mov frqb,#0 - mov phsb,#0 - mov ctrb,clockLineMode -hub_cog_transfer_ret - ret - - -read_single_block - ' where am I sending the data? - movd :store_read_long,#speed_buf - mov ops_left,#128 - ' wait until the card is ready - mov tmp1,N_in8_500ms -:get_resp - call #in8 - cmp readback,#$FE wz -if_nz djnz tmp1,#:get_resp -if_nz neg user_cmd,#ERR_ASM_NO_READ_TOKEN -if_nz jmp #read_single_block_ret - ' set DI high - neg phsa,#1 - ' read the data - mov ops_left,#128 -:read_loop - mov tmp1,#4 - movi phsb,#%011_000000 -:in_byte - ' Start my clock - movi frqb,#%001_000000 - ' keep reading in my value, BACKWARDS! (Brilliant idea by Tom Rokicki!) - test maskDO,ina wc - rcl readback,#8 - test maskDO,ina wc - muxc readback,#2 - test maskDO,ina wc - muxc readback,#4 - test maskDO,ina wc - muxc readback,#8 - test maskDO,ina wc - muxc readback,#16 - test maskDO,ina wc - muxc readback,#32 - test maskDO,ina wc - muxc readback,#64 - test maskDO,ina wc - mov frqb,#0 ' stop the clock - muxc readback,#128 - ' go back for more - djnz tmp1,#:in_byte - ' make it...NOT backwards [8^) - rev readback,#0 -:store_read_long - mov 0-0,readback ' due to some counter weirdness, we need this mov - add :store_read_long,const512 - djnz ops_left,#:read_loop - - ' set DI low - mov phsa,#0 - - ' now read 2 trailing bytes (CRC) - call #in8 ' out8 is 2x faster than in8 - call #in8 ' and I'm not using the CRC anyway - ' give an extra 8 clocks in case we pause for a long time - call #in8 ' in8 looks like out8($FF) - - ' all done successfully - mov idle_time,#0 - mov user_cmd,#0 -read_single_block_ret - ret - -write_single_block - ' where am I getting the data? (all 512 bytes / 128 longs of it?) - movs :write_loop,#speed_buf - ' read in 512 bytes (128 longs) from Hub RAM and write it to the card - mov ops_left,#128 - ' just hold your horses - call #busy_fast - ' $FC for multiblock, $FE for single block - movi phsa,#$FC<<1 - call #out8 - mov phsb,#0 ' make sure my clock accumulator is right - 'movi phsb,#%11_0000000 -:write_loop - ' read 4 bytes - mov phsa,speed_buf - add :write_loop,#1 - ' a long in LE order is DCBA - rol phsa,#24 ' move A7 into position, so I can do the swizzled version - movi frqb,#%010000000 ' start the clock (remember A7 is already in place) - rol phsa,#1 ' A7 is going out, at the end of this instr, A6 is in place - rol phsa,#1 ' A5 - rol phsa,#1 ' A4 - rol phsa,#1 ' A3 - rol phsa,#1 ' A2 - rol phsa,#1 ' A1 - rol phsa,#1 ' A0 - rol phsa,#17 ' B7 - rol phsa,#1 ' B6 - rol phsa,#1 ' B5 - rol phsa,#1 ' B4 - rol phsa,#1 ' B3 - rol phsa,#1 ' B2 - rol phsa,#1 ' B1 - rol phsa,#1 ' B0 - rol phsa,#17 ' C7 - rol phsa,#1 ' C6 - rol phsa,#1 ' C5 - rol phsa,#1 ' C4 - rol phsa,#1 ' C3 - rol phsa,#1 ' C2 - rol phsa,#1 ' C1 - rol phsa,#1 ' C0 - rol phsa,#17 ' D7 - rol phsa,#1 ' D6 - rol phsa,#1 ' D5 - rol phsa,#1 ' D4 - rol phsa,#1 ' D3 - rol phsa,#1 ' D2 - rol phsa,#1 ' D1 - rol phsa,#1 ' D0 will be in place _after_ this instruction - mov frqb,#0 ' shuts the clock off, _after_ this instruction - djnz ops_left,#:write_loop - ' write out my two (bogus, using $FF) CRC bytes - call #in8 - call #in8 - ' now read response (I need this response, so can't spoof using out8) - call #in8 - and readback,#$1F - cmp readback,#5 wz -if_z mov user_cmd,#0 ' great -if_nz neg user_cmd,#ERR_ASM_BLOCK_NOT_WRITTEN ' oops - ' send out another 8 clocks - call #in8 - ' all done - mov idle_time,#0 -write_single_block_ret - ret - - -{=== Assembly Interface Variables ===} -pinDO long 0 ' pin is controlled by a counter -pinCLK long 0 ' pin is controlled by a counter -pinDI long 0 ' pin is controlled by a counter -maskDO long 0 ' mask for reading the DO line from the card -maskDI long 0 ' mask for setting the pin high while reading -maskCS long 0 ' mask = (1< 32 - outc("0") - digits-- - - value <<= 32 - digits - - repeat digits - outc((value <-= 1) & 1 + "0") - - -PUB clrbtm(ColorVal) | i - repeat i from 36 to rows - 1 'was 35 - colors[i] := $0000 + ColorVal - -PUB cls1(c,screencolor,pcport,ascii,CR) | i,x,y - - longfill(@screen[0], $20202020, chars / 4) - - clrbtm(TURQUOISE) - - inverse := 1 - - statprint(36,0, string(" N8VEM ParPortProp | RomWBW v0.92")) - inverse := 0 - statprint(37,0, string(" ")) - statprint(38,0, string(" ")) - statprint(39,0, string(" ")) - - -{{ - x :=xloc - y := yloc - invs := inverse - ''clrbtm(TURQUOISE) - longfill(@screen, $20202020, chars/4) - xloc := 0 - yloc :=0 - loc := xloc + yloc*cols - repeat 80 - outc(32) - xloc := 0 - yloc :=36 - loc := xloc + yloc*cols - inverse := 1 - str(string(" propIO V 0.91 ")) - inverse := 0 - str(string("Baud Rate: ")) - i:= BR[6] - dec(i) - str(string(" ")) - xloc := 18 - loc := xloc + yloc*cols - str(string("Color ")) - str(string("PC Port: ")) - if pcport == 1 - str(string("OFF ")) - if pcport == 0 - str(string("ON ")) - str(string(" Force 7 bit: ")) - if ascii == 0 - str(string("NO ")) - if ascii == 1 - str(string("YES ")) - str(string(" Cursor CR W/LF: ")) - if CR == 1 - str(string("YES")) - if CR == 0 - str(string("NO ")) - outc(13) - outc(10) - - inverse:=1 - xloc := 6 - loc := xloc + yloc*cols - str(string("F1")) - xloc := 19 - loc := xloc + yloc*cols - str(string("F2")) - xloc := 30 - loc := xloc + yloc*cols - str(string("F3")) - xloc := 46 - loc := xloc + yloc*cols - str(string("F4")) - xloc := 58 - loc := xloc + yloc*cols - str(string("F5")) - xloc := 70 - loc := xloc + yloc*cols - str(string("F6")) - inverse := invs - xloc := cursor[0] := x 'right & left was 0 - yloc := cursor[1] := y 'from top was 1 - loc := xloc + yloc*cols -}} - -PUB clsupdate(c,screencolor,PCPORT,ascii,CR) | i,x,y,locold - - invs := inverse - locold := loc - x := xloc - y := yloc - ''(TURQUOISE) - xloc := 0 - yloc :=36 - loc := xloc + yloc*cols - inverse := 1 - str(string(" propIO V 0.81 ")) - inverse := 0 - xloc := 0 - yloc :=37 - loc := xloc + yloc*cols - str(string("Baud Rate: ")) - i:= BR[6] - dec(i) - str(string(" ")) - xloc := 18 - loc := xloc + yloc*cols - - str(string("Color ")) - str(string("PC Port: ")) - if pcport == 1 - str(string("OFF ")) - if pcport == 0 - str(string("ON ")) - str(string(" Force 7 bit: ")) - if ascii == 0 - str(string("NO ")) - if ascii == 1 - str(string("YES ")) - str(string(" Cursor CR W/LF: ")) - if CR == 1 - str(string("YES")) - if CR == 0 - str(string("NO ")) - xloc := 0 - yloc :=38 - loc := xloc + yloc*cols - inverse:=1 - xloc := 6 - loc := xloc + yloc*cols - str(string("F1")) - xloc := 19 - loc := xloc + yloc*cols - str(string("F2")) - xloc := 30 - loc := xloc + yloc*cols - str(string("F3")) - xloc := 46 - loc := xloc + yloc*cols - str(string("F4")) - xloc := 58 - loc := xloc + yloc*cols - str(string("F5")) - xloc := 70 - loc := xloc + yloc*cols - str(string("F6")) - inverse := invs - xloc := cursor[0] := x - yloc := cursor[1] := y -' loc := xloc + yloc*cols - loc := locold - -PUB dec(value) | i - -'' Print a decimal number - - if value < 0 - -value - outc("-") - - i := 1_000_000_000 - - repeat 10 - if value => i - outc(value/i + "0") - value //= i - result~~ - elseif result or i == 1 - outc("0") - i /= 10 - -PUB hex(value, digits) - -'' Print a hexadecimal number, specify number of digits - - repeat while digits > 8 - outc("0") - digits-- - - value <<= (8 - digits) << 2 - - repeat digits - outc(lookupz((value <-= 4) & $f : "0".."9", "A".."F")) - - -PUB str(string_ptr) - -'' Print a zero terminated string - - repeat strsize(string_ptr) - process_char(byte[string_ptr++]) - -PUB statprint(r, c, str1) | x, ptr - - ptr := r * cols + c - repeat x from 0 to STRSIZE(str1) - 1 - putc(ptr++, BYTE[str1 + x]) - -PUB statnum(r, c, num1) | i, ptr - - ptr := r * cols + c - - if num1 < 0 - -num1 - putc(ptr++,"-") - - i := 1_000_000_000 - - repeat 10 - if num1 => i - putc(ptr++, (num1/i +"0")) - num1 //= i - result~~ - elseif result or i == 1 - putc(ptr++, "0") - i /= 10 - -PUB putc(position, c) - if inverse - c |= $80 - screen[position] := c - -PUB cls - longfill (@screen, $20202020, lastChar) - -PUB fullcls - longfill(@screen, $20202020, 800) - -PUB setInverse(val) - inverse := val - -PUB setInv(c) - if c == 7 - setInverse(1) - else - setInverse(0) - -PUB clEOL(position) | count - count := cols - (position // cols) - bytefill(@screen + position, $20, count) - -PUB clBOL(position) | count - count := position // cols - bytefill(@screen + position - count, $20, count) - -PUB delLine(position) | src, count - position -= position // cols - - src := position + cols - - count := (maxChars - src) / 4 - - if count > 0 - longmove(@screen + position, @screen + src, count) - - longfill(@screen + lastLine, $20202020, lcols) - -PUB clEOS(position) - cleol(position) - position += cols - (position // cols) - repeat while position < maxChars - longfill(@screen + position, $20202020, lcols) - pos += cols - -PUB setCursorPos(position) - cursor[0] := position // cols - cursor[1] := position / cols - -PUB insLine(position) | base, nxt - base := position - (position // cols) - position := lastLine - repeat while position > base - nxt := position - cols - longmove(@screen + position, @screen + nxt, lcols) - position := nxt - clEOL(base) - -PUB insChar(position) | count - count := (cols - (position // cols)) - 1 - bytemove(@tmpl, @screen + position, count) - screen[position] := " " - bytemove(@screen + position + 1, @tmpl, count) - -PUB delChar(position) | count - count := (cols - (position // cols)) - 1 - bytemove(@screen + position, @screen + position + 1, count) - screen[position + count] := " " - -PRI inRegion : answer - answer := (pos => regionTop) AND (pos < regionBot) - -PRI scrollUp - delLine(regionTop) - if regionBot < maxChars - insLine(regionBot) - -PRI scrollDown - if regionBot < maxChars - delLine(regionBot) - insLine(regionTop) - -PRI ansi(c) | x, defVal - - state := 0 - - if (c <> "r") AND (c <> "J") AND (c <> "m") AND (c <> "K") - if arg0 == -1 - arg0 := 1 - if arg1 == -1 - arg1 := 1 - - case c - "@": - repeat while arg0-- > 0 - insChar(pos) - - "b": - repeat while arg0-- > 0 - outc(lastc) - - "d": - if (arg0 < 1) OR (arg0 > rows) - arg0 := rows - pos := ((arg0 - 1) * cols) + (pos // cols) - - "m": - setInv(arg0) - if arg1 <> -1 - setInv(arg1) - - "r": - if arg0 < 1 - arg0 := 1 - elseif arg0 > cols - arg0 := cols - if arg1 < 1 - arg1 := 1 - elseif arg1 > cols - arg1 := cols - if arg1 < arg0 - arg1 := arg0 - - regionTop := (arg0 - 1) * cols - regionBot := arg1 * cols - pos := 0 - - "A": - repeat while arg0-- > 0 - pos -= cols - if pos < 0 - pos += cols - return - - "B": - repeat while arg0-- > 0 - pos += cols - if pos => maxChars - pos -= cols - return - - "C": - repeat while arg0-- > 0 - pos += 1 - if pos => maxChars - pos -= 1 - return - - "D": - repeat while arg0-- > 0 - pos -= 1 - if pos < 0 - pos := 0 - return - - "G": - if (arg0 < 1) OR (arg0 > cols) - arg0 := cols - pos := (pos - (pos // cols)) + (arg0 - 1) - - "H", "f": - if arg0 =< 0 - arg0 := 1 - if arg1 =< 0 - arg1 := 1 - pos := (cols * (arg0 - 1)) + (arg1 - 1) - if pos < 0 - pos := 0 - if pos => maxChars - pos := maxChars - 1 - - "J": - if arg0 == 1 - clBOL(pos) - x := pos - cols - x -= x // cols - repeat while x => 0 - clEOL(x) - x -= cols - return - - if arg0 == 2 - pos := 0 - - clEOL(pos) - x := pos + cols - x -= (x // cols) - repeat while x < maxChars - clEOL(x) - x += cols - - "K": - if arg0 == -1 - clEOL(pos) - elseif arg0 == 1 - clBOL(pos) - else - clEOL(pos - (pos // cols)) - - "L": - if inRegion - repeat while arg0-- > 0 - if regionBot < maxChars - delLine(regionBot) - insLine(pos) - - "M": - if inRegion - repeat while arg0-- > 0 - delLine(pos) - if regionBot < maxChars - insLine(regionBot) - - "P": - repeat while arg0-- - delChar(pos) - -PRI outc(c) - - putc(pos++, lastc := c) - if pos == regionBot - scrollUp - pos -= cols - elseif pos == maxChars - pos := lastLine - -PUB process_char(c) - - case state - - 0: - if c > 127 - c := $20 - - if c => $20 - outc(c) - setCursorPos(pos) - return - - if c == $1B - state := 1 - return - - if c == $0D - pos := pos - (pos // cols) - setCursorPos(pos) - return - - if c == $0A - if inRegion - pos += cols - if pos => regionBot - scrollUp - pos -= cols - else - pos += cols - if pos => maxChars - pos -= cols - setCursorPos(pos) - return - - if c == 9 - pos += (8 - (pos // 8)) - - if pos => maxChars - pos := lastLine - delLine(0) - - setCursorPos(pos) - return - - if c == 8 - if pos > 0 - pos -= 1 - setCursorPos(pos) - return - - 1: - case c - "[": - arg0 := arg1 := -1 - state := 2 - return - - "P": - pos += cols - if pos => maxChars - pos -= cols - - "K": - if pos > 0 - pos -= 1 - - "H": - pos -= cols - if pos < 0 - pos += cols - - "D": - if inRegion - scrollUp - - "M": - if inRegion - scrollDown - - "G": - pos := 0 - - "(": - state := 5 - return - - state := 0 - return - - 2: - if (c => "0") AND (c =< "9") - if arg0 == -1 - arg0 := c - "0" - else - arg0 := (arg0 * 10) + (c - "0") - return - - if c == ";" - state := 3 - return - - ansi(c) - setCursorPos(pos) - return - - 3: - if (c => "0") AND (c =< "9") - if arg1 == -1 - arg1 := c - "0" - else - arg1 := (arg1 * 10) + (c - "0") - return - - if c == ";" - state := 4 - return - - ansi(c) - setCursorPos(pos) - return - - 4: - if (c => "0") AND (c =< "9") - return - - if c == ";" - return - ansi(c) - setCursorPos(pos) - return - - 5: - state := 0 - return - - return \ No newline at end of file diff --git a/branches/s100/Support/PropIO/Spin/VGA_HiRes_Text.spin b/branches/s100/Support/PropIO/Spin/VGA_HiRes_Text.spin deleted file mode 100644 index 5b892316..00000000 Binary files a/branches/s100/Support/PropIO/Spin/VGA_HiRes_Text.spin and /dev/null differ diff --git a/branches/s100/Support/PropIO/Spin/safe_spi.spin b/branches/s100/Support/PropIO/Spin/safe_spi.spin deleted file mode 100644 index a63cb229..00000000 --- a/branches/s100/Support/PropIO/Spin/safe_spi.spin +++ /dev/null @@ -1,920 +0,0 @@ -{{ - SPI interface routines for SD & SDHC & MMC cards - - Jonathan "lonesock" Dummer - version 0.3.0 2009 July 19 - - Using multiblock SPI mode exclusively. - - This is the "SAFE" version...uses - * 1 instruction per bit writes - * 2 instructions per bit reads - - For the fsrw project: - fsrw.sf.net -}} - -CON - ' possible card types - type_MMC = 1 - type_SD = 2 - type_SDHC = 3 - - ' Error codes - ERR_CARD_NOT_RESET = -1 - ERR_3v3_NOT_SUPPORTED = -2 - ERR_OCR_FAILED = -3 - ERR_BLOCK_NOT_LONG_ALIGNED = -4 - '... - ' These errors are for the assembly engine...they are negated inside, and need to be <= 511 - ERR_ASM_NO_READ_TOKEN = 100 - ERR_ASM_BLOCK_NOT_WRITTEN = 101 - ' NOTE: errors -128 to -255 are reserved for reporting R1 response errors - '... - ERR_SPI_ENGINE_NOT_RUNNING = -999 - ERR_CARD_BUSY_TIMEOUT = -1000 - - ' SDHC/SD/MMC command set for SPI - CMD0 = $40+0 ' GO_IDLE_STATE - CMD1 = $40+1 ' SEND_OP_COND (MMC) - ACMD41 = $C0+41 ' SEND_OP_COND (SDC) - CMD8 = $40+8 ' SEND_IF_COND - CMD9 = $40+9 ' SEND_CSD - CMD10 = $40+10 ' SEND_CID - CMD12 = $40+12 ' STOP_TRANSMISSION - CMD13 = $40+13 ' SEND_STATUS - ACMD13 = $C0+13 ' SD_STATUS (SDC) - CMD16 = $40+16 ' SET_BLOCKLEN - CMD17 = $40+17 ' READ_SINGLE_BLOCK - CMD18 = $40+18 ' READ_MULTIPLE_BLOCK - CMD23 = $40+23 ' SET_BLOCK_COUNT (MMC) - ACMD23 = $C0+23 ' SET_WR_BLK_ERASE_COUNT (SDC) - CMD24 = $40+24 ' WRITE_BLOCK - CMD25 = $40+25 ' WRITE_MULTIPLE_BLOCK - CMD55 = $40+55 ' APP_CMD - CMD58 = $40+58 ' READ_OCR - CMD59 = $40+59 ' CRC_ON_OFF - - ' buffer size for my debug cmd log - 'LOG_SIZE = 256<<1 - -{ -VAR - long SPI_engine_cog - ' these are used for interfacing with the assembly engine | temporary initialization usage - long SPI_command ' "t", "r", "w", 0 =>done, <0 => error | pin mask - long SPI_block_index ' which 512-byte block to read/write | cnt at init - long SPI_buffer_address ' where to get/put the data in Hub RAM | unused -'} -DAT -'' I'm placing these variables in a DAT section to make this driver a singleton. -'' If for some reason you really need more than one driver (e.g. if you have more -'' than a single SD socket), move these back into VAR. -SPI_engine_cog long 0 -' these are used for interfacing with the assembly engine | temporary initialization usage -SPI_command long 0 ' "t", "r", "w", 0 =>done, <0 => error | unused -SPI_block_index long 0 ' which 512-byte block to read/write | cnt at init -SPI_buffer_address long 0 ' where to get/put the data in Hub RAM | unused - -{ -VAR - ' for debug ONLY - byte log_cmd_resp[LOG_SIZE+1] -PUB get_log_pointer - return @log_cmd_resp -'} - -PUB start( basepin ) -{{ - This is a compatibility wrapper, and requires that the pins be - both consecutive, and in the order DO CLK DI CS. -}} - return start_explicit( basepin, basepin+1, basepin+2, basepin+3 ) - -PUB readblock( block_index, buffer_address ) - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - if (buffer_address & 3) - abort ERR_BLOCK_NOT_LONG_ALIGNED - SPI_block_index := block_index - SPI_buffer_address := buffer_address - SPI_command := "r" - repeat while SPI_command == "r" - if SPI_command < 0 - abort SPI_command - -PUB writeblock( block_index, buffer_address ) - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - if (buffer_address & 3) - abort ERR_BLOCK_NOT_LONG_ALIGNED - SPI_block_index := block_index - SPI_buffer_address := buffer_address - SPI_command := "w" - repeat while SPI_command == "w" - if SPI_command < 0 - abort SPI_command - -PUB get_seconds - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - SPI_command := "t" - repeat while SPI_command == "t" - ' secods are in SPI_block_index, remainder is in SPI_buffer_address - return SPI_block_index - -PUB get_milliseconds : ms - if SPI_engine_cog == 0 - abort ERR_SPI_ENGINE_NOT_RUNNING - SPI_command := "t" - repeat while SPI_command == "t" - ' secods are in SPI_block_index, remainder is in SPI_buffer_address - ms := SPI_block_index * 1000 - ms += SPI_buffer_address * 1000 / clkfreq - -PUB start_explicit( DO, CLK, DI, CS ) : card_type | tmp, i -{{ - Do all of the card initialization in SPIN, then hand off the pin - information to the assembly cog for hot SPI block R/W action! -}} - ' Start from scratch - stop - ' clear my log buffer - { - bytefill( @log_cmd_resp, 0, LOG_SIZE+1 ) - dbg_ptr := @log_cmd_resp - dbg_end := dbg_ptr + LOG_SIZE - '} - ' wait ~4 milliseconds - waitcnt( 500 + (clkfreq>>8) + cnt ) - ' (start with cog variables, _BEFORE_ loading the cog) - pinDO := DO - maskDO := |< DO - pinCLK := CLK - pinDI := DI - maskDI := |< DI - maskCS := |< CS - adrShift := 9 ' block = 512 * index, and 512 = 1<<9 - ' pass the output pin mask via the command register - maskAll := maskCS | (| 74 clocks - outa |= maskAll - repeat 4096 - outa[CLK]~~ - outa[CLK]~ - ' time-hack - SPI_block_index := cnt - ' reset the card - tmp~ - repeat i from 0 to 9 - if tmp <> 1 - tmp := send_cmd_slow( CMD0, 0, $95 ) - if (tmp & 4) - ' the card said CMD0 ("go idle") was invalid, so we're possibly stuck in read or write mode - if i & 1 - ' exit multiblock read mode - repeat 4 - read_32_slow ' these extra clocks are required for some MMC cards - send_slow( $FD, 8 ) ' stop token - read_32_slow - repeat while read_slow <> $FF - else - ' exit multiblock read mode - send_cmd_slow( CMD12, 0, $61 ) - if tmp <> 1 - ' the reset command failed! - crash( ERR_CARD_NOT_RESET ) - ' Is this a SD type 2 card? - if send_cmd_slow( CMD8, $1AA, $87 ) == 1 - ' Type2 SD, check to see if it's a SDHC card - tmp := read_32_slow - ' check the supported voltage - if (tmp & $1FF) <> $1AA - crash( ERR_3v3_NOT_SUPPORTED ) - ' try to initialize the type 2 card with the High Capacity bit - repeat while send_cmd_slow( ACMD41, |<30, $77 ) - ' the card is initialized, let's read back the High Capacity bit - if send_cmd_slow( CMD58, 0, $FD ) <> 0 - crash( ERR_OCR_FAILED ) - ' get back the data - tmp := read_32_slow - ' check the bit - if tmp & |<30 - card_type := type_SDHC - adrShift := 0 - else - card_type := type_SD - else - ' Either a type 1 SD card, or it's MMC, try SD 1st - if send_cmd_slow( ACMD41, 0, $E5 ) < 2 - ' this is a type 1 SD card (1 means busy, 0 means done initializing) - card_type := type_SD - repeat while send_cmd_slow( ACMD41, 0, $E5 ) - else - ' mark that it's MMC, and try to initialize - card_type := type_MMC - repeat while send_cmd_slow( CMD1, 0, $F9 ) - ' some SD or MMC cards may have the wrong block size, set it here - send_cmd_slow( CMD16, 512, $15 ) - ' card is mounted, make sure the CRC is turned off - send_cmd_slow( CMD59, 0, $91 ) - ' check the status - 'send_cmd_slow( CMD13, 0, $0D ) - ' done with the SPI bus for now - outa |= maskCS - ' set my counter modes for super fast SPI operation - ' writing: NCO single-ended mode, output on DI - writeMode := (%00100 << 26) | (DI << 0) - ' reading - 'readMode := (%11000 << 26) | (DO << 0) | (CLK << 9) - ' clock - 'clockLineMode := (%00110 << 26) | (CLK << 0) ' DUTY, 25% duty cycle - ' clock - clockLineMode := (%00100 << 26) | (CLK << 0) ' NCO, 50% duty cycle - ' how many bytes (8 clocks, >>3) fit into 1/2 of a second (>>1), 4 clocks per instruction (>>2)? - N_in8_500ms := clkfreq >> constant(1+2+3) - ' how long should we wait before auto-exiting any multiblock mode? - idle_limit := 125 ' ms, NEVER make this > 1000 - idle_limit := clkfreq / (1000 / idle_limit) ' convert to counts - ' Hand off control to the assembly engine's cog - bufAdr := @SPI_buffer_address - sdAdr := @SPI_block_index - SPI_command := 0 ' just make sure it's not 1 - ' start my driver cog and wait till I hear back that it's done - SPI_engine_cog := cognew( @SPI_engine_entry, @SPI_command ) + 1 - if( SPI_engine_cog == 0 ) - crash( ERR_SPI_ENGINE_NOT_RUNNING ) - repeat while SPI_command <> -1 - ' and we no longer need to control any pins from here - dira &= !maskAll - ' the return variable is card_type - -PUB release -{{ - I do not want to abort if the cog is not - running, as this is called from stop, which - is called from start/ [8^) -}} - if SPI_engine_cog - SPI_command := "z" - repeat while SPI_command == "z" - -PUB stop -{{ - kill the assembly driver cog. -}} - release - if SPI_engine_cog - cogstop( SPI_engine_cog~ - 1 ) - -PRI crash( abort_code ) -{{ - In case of Bad Things(TM) happening, - exit as gracefully as possible. -}} - ' and we no longer need to control any pins from here - dira &= !maskAll - ' and report our error - abort abort_code - -PRI send_cmd_slow( cmd, val, crc ) : reply | time_stamp -{{ - Send down a command and return the reply. - Note: slow is an understatement! - Note: this uses the assembly DAT variables for pin IDs, - which means that if you run this multiple times (say for - multiple SD cards), these values will change for each one. - But this is OK as all of these functions will be called - during the initialization only, before the PASM engine is - running. -}} - ' if this is an application specific command, handle it - if (cmd & $80) - ' ACMD is the command sequense of CMD55-CMD - cmd &= $7F - reply := send_cmd_slow( CMD55, 0, $65 ) - if (reply > 1) - return reply - ' the CS line needs to go low during this operation - outa |= maskCS - outa &= !maskCS - ' give the card a few cocks to finish whatever it was doing - read_32_slow - ' send the command byte - send_slow( cmd, 8 ) - ' send the value long - send_slow( val, 32 ) - ' send the CRC byte - send_slow( crc, 8 ) - ' is this a CMD12?, if so, stuff byte - if cmd == CMD12 - read_slow - ' read back the response (spec declares 1-8 reads max for SD, MMC is 0-8) - time_stamp := 9 - repeat - reply := read_slow - while( reply & $80 ) and ( time_stamp-- ) - ' done, and 'reply' is already pre-loaded - { - if dbg_ptr < (dbg_end-1) - byte[dbg_ptr++] := cmd - byte[dbg_ptr++] := reply - if (cmd&63) == 13 - ' get the second byte - byte[dbg_ptr++] := cmd - byte[dbg_ptr++] := read_slow - '} - -PRI send_slow( value, bits_to_send ) - value ><= bits_to_send - repeat bits_to_send - outa[pinCLK]~ - outa[pinDI] := value - value >>= 1 - outa[pinCLK]~~ - -PRI read_32_slow : r - repeat 4 - r <<= 8 - r |= read_slow - -PRI read_slow : r -{{ - Read back 8 bits from the card -}} - ' we need the DI line high so a read can occur - outa[pinDI]~~ - ' get 8 bits (remember, r is initialized to 0 by SPIN) - repeat 8 - outa[pinCLK]~ - outa[pinCLK]~~ - r += r + ina[pinDO] - ' error check - if( (cnt - SPI_block_index) > (clkfreq << 2) ) - crash( ERR_CARD_BUSY_TIMEOUT ) - -DAT -{{ - This is the assembly engine for doing fast block - reads and writes. This is *ALL* it does! -}} -ORG 0 -SPI_engine_entry - ' Counter A drives data out - mov ctra,writeMode - ' Counter B will always drive my clock line - mov ctrb,clockLineMode - ' set our output pins to match the pin mask - mov dira,maskAll - ' handshake that we now control the pins - neg user_request,#1 - wrlong user_request,par - ' start my seconds' counter here - mov last_time,cnt - -waiting_for_command - ' update my seconds counter, but also track the idle - ' time so we can to release the card after timeout. - call #handle_time - ' read the command, and make sure it's from the user (> 0) - rdlong user_request,par - cmps user_request,#0 wz,wc -if_be jmp #waiting_for_command - ' handle our card based commands - cmp user_request,#"r" wz -if_z jmp #read_ahead - cmp user_request,#"w" wz -if_z jmp #write_behind - cmp user_request,#"z" wz -if_z jmp #release_card - ' time requests are handled differently - cmp user_request,#"t" wz ' time -if_z wrlong seconds,sdAdr ' seconds goes into the SD index register -if_z wrlong dtime,bufAdr ' the remainder goes into the buffer address register - ' in all other cases, clear the user's request - mov user_request,#0 - wrlong user_request,par - jmp #waiting_for_command - - -release_card - mov user_cmd,#"z" ' request a release - neg lastIndexPlus,#1 ' reset the last block index - neg user_idx,#1 ' and make this match it - call #handle_command - mov user_request,user_cmd - wrlong user_request,par - jmp #waiting_for_command - -read_ahead - rdlong user_idx,sdAdr - ' if the correct block is not already loaded, load it - mov tmp1,user_idx - add tmp1,#1 - cmp tmp1,lastIndexPlus wz -if_z cmp lastCommand,#"r" wz -if_z jmp #:get_on_with_it - mov user_cmd,#"r" - call #handle_command -:get_on_with_it - ' copy the data up into Hub RAM - movi transfer_long,#%000010_000 'set to wrlong - call #hub_cog_transfer - ' signify that the data is ready, Spin can continue - mov user_request,user_cmd - wrlong user_request,par - ' request the next block - mov user_cmd,#"r" - add user_idx,#1 - call #handle_command - ' done - jmp #waiting_for_command - -write_behind - rdlong user_idx,sdAdr - ' copy data in from Hub RAM - movi transfer_long,#%000010_001 'set to rdlong - call #hub_cog_transfer - ' signify that we have the data, Spin can continue - mov user_request,user_cmd - wrlong user_request,par - ' write out the block - mov user_cmd,#"w" - call #handle_command - ' done - jmp #waiting_for_command - -{{ - Set user_cmd and user_idx before calling this -}} -handle_command - ' Can we stay in the old mode? (address = old_address+1) && (old mode == new_mode) - cmp lastIndexPlus,user_idx wz -if_z cmp user_cmd,lastCommand wz -if_z jmp #:execute_block_command - ' we fell through, must exit the old mode! (except if the old mode was "release") - cmp lastCommand,#"w" wz -if_z call #stop_mb_write - cmp lastCommand,#"r" wz -if_z call #stop_mb_read - ' and start up the new mode! - cmp user_cmd,#"w" wz -if_z call #start_mb_write - cmp user_cmd,#"r" wz -if_z call #start_mb_read - cmp user_cmd,#"z" wz -if_z call #release_DO -:execute_block_command - ' track the (new) last index and command - mov lastIndexPlus,user_idx - add lastIndexPlus,#1 - mov lastCommand,user_cmd - ' do the block read or write or terminate! - cmp user_cmd,#"w" wz -if_z call #write_single_block - cmp user_cmd,#"r" wz -if_z call #read_single_block - cmp user_cmd,#"z" wz -if_z mov user_cmd,#0 - ' done -handle_command_ret - ret - -{=== these PASM functions get me in and out of multiblock mode ===} -release_DO - ' we're already out of multiblock mode, so - ' deselect the card and send out some clocks - or outa,maskCS - call #in8 - call #in8 - ' if you are using pull-up resistors, and need all - ' lines tristated, then uncomment the following line. - ' for Cluso99 - 'mov dira,#0 -release_DO_ret - ret - -start_mb_read - movi block_cmd,#CMD18<<1 - call #send_SPI_command_fast -start_mb_read_ret - ret - -stop_mb_read - movi block_cmd,#CMD12<<1 - call #send_SPI_command_fast - call #busy_fast -stop_mb_read_ret - ret - -start_mb_write - movi block_cmd,#CMD25<<1 - call #send_SPI_command_fast -start_mb_write_ret - ret - -stop_mb_write - call #busy_fast - ' only some cards need these extra clocks - mov tmp1,#16 -:loopity - call #in8 - djnz tmp1,#:loopity - ' done with hack - movi phsa,#$FD<<1 - call #out8 - call #in8 ' stuff byte - call #busy_fast -stop_mb_write_ret - ret - -send_SPI_command_fast - ' make sure we have control of the output lines - mov dira,maskAll - ' make sure the CS line transitions low - or outa,maskCS - andn outa,maskCS - ' 8 clocks - call #in8 - ' send the data - mov phsa,block_cmd ' do which ever block command this is (already in the top 8 bits) - call #out8 ' write the byte - mov phsa,user_idx ' read in the desired block index - shl phsa,adrShift ' this will multiply by 512 (bytes/sector) for MMC and SD - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - rol phsa,#1 - call #out8 ' move out the 1st MSB ' - ' bogus CRC value - call #in8 ' in8 looks like out8 with $FF - ' CMD12 requires a stuff byte - shr block_cmd,#24 - cmp block_cmd,#CMD12 wz -if_z call #in8 ' 8 clocks - ' get the response - mov tmp1,#9 -:cmd_response - call #in8 - test readback,#$80 wc,wz -if_c djnz tmp1,#:cmd_response -if_nz neg user_cmd,readback - ' done -send_SPI_command_fast_ret - ret - - -busy_fast - mov tmp1,N_in8_500ms -:still_busy - call #in8 - cmp readback,#$FF wz -if_nz djnz tmp1,#:still_busy -busy_fast_ret - ret - - -out8 - andn outa,maskDI - 'movi phsb,#%11_0000000 - mov phsb,#0 - movi frqb,#%01_0000000 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - rol phsa,#1 - mov frqb,#0 - ' don't shift out the final bit...already sent, but be aware - ' of this when sending consecutive bytes (send_cmd, for e.g.) -out8_ret - ret - -{ -in8 - or outa,maskDI - mov ctra,readMode - ' Start my clock - mov frqa,#1<<7 - mov phsa,#0 - movi phsb,#%11_0000000 - movi frqb,#%01_0000000 - ' keep reading in my value, one bit at a time! (Kuneko - "Wh) - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - shr frqa,#1 - mov frqb,#0 ' stop the clock - mov readback,phsa - mov frqa,#0 - mov ctra,writeMode -in8_ret - ret -} -in8 - neg phsa,#1' DI high - mov readback,#0 - ' set up my clock, and start it - movi phsb,#%011_000000 - movi frqb,#%001_000000 - ' keep reading in my value - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - rcl readback,#1 - test maskDO,ina wc - mov frqb,#0 ' stop the clock - rcl readback,#1 - mov phsa,#0 'DI low -in8_ret - ret - - -' this is called more frequently than 1 Hz, and -' is only called when the user command is 0. -handle_time - mov tmp1,cnt ' get the current timestamp - add idle_time,tmp1 ' add the current time to my idle time counter - sub idle_time,last_time ' subtract the last time from my idle counter (hence delta) - add dtime,tmp1 ' add to my accumulator, - sub dtime,last_time ' and subtract the old (adding delta) - mov last_time,tmp1 ' update my "last timestamp" - rdlong tmp1,#0 ' what is the clock frequency? - cmpsub dtime,tmp1 wc ' if I have more than a second in my accumulator - addx seconds,#0 ' then add it to "seconds" - ' this part is to auto-release the card after a timeout - cmp idle_time,idle_limit wz,wc -if_b jmp #handle_time_ret ' don't clear if we haven't hit the limit - mov user_cmd,#"z" ' we can't overdo it, the command handler makes sure - neg lastIndexPlus,#1 ' reset the last block index - neg user_idx,#1 ' and make this match it - call #handle_command ' release the card, but don't mess with the user's request register -handle_time_ret - ret - -hub_cog_transfer -' setup for all 4 passes - mov ctrb,clockXferMode - mov frqb,#1 - rdlong buf_ptr,bufAdr - mov ops_left,#4 - movd transfer_long,#speed_buf -four_transfer_passes - ' sync to the Hub RAM access - rdlong tmp1,tmp1 - ' how many long to move on this pass? (512 bytes / 4)longs / 4 passes - mov tmp1,#(512 / 4 / 4) - ' get my starting address right (phsb is incremented 1 per clock, so 16 each Hub access) - mov phsb,buf_ptr - ' write the longs, stride 4...low 2 bits of phsb are ignored -transfer_long - rdlong 0-0,phsb - add transfer_long,incDest4 - djnz tmp1,#transfer_long - ' go back to where I started, but advanced 1 long - sub transfer_long,decDestNminus1 - ' offset my Hub pointer by one long per pass - add buf_ptr,#4 - ' do all 4 passes - djnz ops_left,#four_transfer_passes - ' restore the counter mode - mov frqb,#0 - mov phsb,#0 - mov ctrb,clockLineMode -hub_cog_transfer_ret - ret - - -read_single_block - ' where am I sending the data? - movd :store_read_long,#speed_buf - mov ops_left,#128 - ' wait until the card is ready - mov tmp1,N_in8_500ms -:get_resp - call #in8 - cmp readback,#$FE wz -if_nz djnz tmp1,#:get_resp -if_nz neg user_cmd,#ERR_ASM_NO_READ_TOKEN -if_nz jmp #read_single_block_ret - ' set DI high - neg phsa,#1 - ' read the data - mov ops_left,#128 -:read_loop - mov tmp1,#4 - movi phsb,#%011_000000 -:in_byte - ' Start my clock - movi frqb,#%001_000000 - ' keep reading in my value, BACKWARDS! (Brilliant idea by Tom Rokicki!) - test maskDO,ina wc - rcl readback,#8 - test maskDO,ina wc - muxc readback,#2 - test maskDO,ina wc - muxc readback,#4 - test maskDO,ina wc - muxc readback,#8 - test maskDO,ina wc - muxc readback,#16 - test maskDO,ina wc - muxc readback,#32 - test maskDO,ina wc - muxc readback,#64 - test maskDO,ina wc - mov frqb,#0 ' stop the clock - muxc readback,#128 - ' go back for more - djnz tmp1,#:in_byte - ' make it...NOT backwards [8^) - rev readback,#0 -:store_read_long - mov 0-0,readback ' due to some counter weirdness, we need this mov - add :store_read_long,const512 - djnz ops_left,#:read_loop - - ' set DI low - mov phsa,#0 - - ' now read 2 trailing bytes (CRC) - call #in8 ' out8 is 2x faster than in8 - call #in8 ' and I'm not using the CRC anyway - ' give an extra 8 clocks in case we pause for a long time - call #in8 ' in8 looks like out8($FF) - - ' all done successfully - mov idle_time,#0 - mov user_cmd,#0 -read_single_block_ret - ret - -write_single_block - ' where am I getting the data? (all 512 bytes / 128 longs of it?) - movs :write_loop,#speed_buf - ' read in 512 bytes (128 longs) from Hub RAM and write it to the card - mov ops_left,#128 - ' just hold your horses - call #busy_fast - ' $FC for multiblock, $FE for single block - movi phsa,#$FC<<1 - call #out8 - mov phsb,#0 ' make sure my clock accumulator is right - 'movi phsb,#%11_0000000 -:write_loop - ' read 4 bytes - mov phsa,speed_buf - add :write_loop,#1 - ' a long in LE order is DCBA - rol phsa,#24 ' move A7 into position, so I can do the swizzled version - movi frqb,#%010000000 ' start the clock (remember A7 is already in place) - rol phsa,#1 ' A7 is going out, at the end of this instr, A6 is in place - rol phsa,#1 ' A5 - rol phsa,#1 ' A4 - rol phsa,#1 ' A3 - rol phsa,#1 ' A2 - rol phsa,#1 ' A1 - rol phsa,#1 ' A0 - rol phsa,#17 ' B7 - rol phsa,#1 ' B6 - rol phsa,#1 ' B5 - rol phsa,#1 ' B4 - rol phsa,#1 ' B3 - rol phsa,#1 ' B2 - rol phsa,#1 ' B1 - rol phsa,#1 ' B0 - rol phsa,#17 ' C7 - rol phsa,#1 ' C6 - rol phsa,#1 ' C5 - rol phsa,#1 ' C4 - rol phsa,#1 ' C3 - rol phsa,#1 ' C2 - rol phsa,#1 ' C1 - rol phsa,#1 ' C0 - rol phsa,#17 ' D7 - rol phsa,#1 ' D6 - rol phsa,#1 ' D5 - rol phsa,#1 ' D4 - rol phsa,#1 ' D3 - rol phsa,#1 ' D2 - rol phsa,#1 ' D1 - rol phsa,#1 ' D0 will be in place _after_ this instruction - mov frqb,#0 ' shuts the clock off, _after_ this instruction - djnz ops_left,#:write_loop - ' write out my two (bogus, using $FF) CRC bytes - call #in8 - call #in8 - ' now read response (I need this response, so can't spoof using out8) - call #in8 - and readback,#$1F - cmp readback,#5 wz -if_z mov user_cmd,#0 ' great -if_nz neg user_cmd,#ERR_ASM_BLOCK_NOT_WRITTEN ' oops - ' send out another 8 clocks - call #in8 - ' all done - mov idle_time,#0 -write_single_block_ret - ret - - -{=== Assembly Interface Variables ===} -pinDO long 0 ' pin is controlled by a counter -pinCLK long 0 ' pin is controlled by a counter -pinDI long 0 ' pin is controlled by a counter -maskDO long 0 ' mask for reading the DO line from the card -maskDI long 0 ' mask for setting the pin high while reading -maskCS long 0 ' mask = (1< - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/branches/s100/Support/ZSDOS/NZCOMPAT.HEX b/branches/s100/Support/ZSDOS/NZCOMPAT.HEX deleted file mode 100644 index e0caa8e0..00000000 --- a/branches/s100/Support/ZSDOS/NZCOMPAT.HEX +++ /dev/null @@ -1,11 +0,0 @@ -:10028000FE01281FFE032803FEFFC0CDD802C8CD03 -:10029000BF02C021030011000113131A1B1B0947E1 -:1002A0000E03E9CDD802C8CDBF02C0210900094E16 -:1002B000234678B12804606918F501FCFF18D7605F -:1002C00069210F000911D502C506031ABE200423B7 -:1002D0001310F8C1C9504348110101211700194EEC -:1002E000234604EB7E23666FAFED42D0210000A7CA -:0102F000C944 -:00000001FF -8' 23 6 INC HL - 538 01A9' 10 \ No newline at end of file diff --git a/branches/s100/Support/ZSDOS/PUTBG.COM b/branches/s100/Support/ZSDOS/PUTBG.COM deleted file mode 100644 index 970e2d8a..00000000 Binary files a/branches/s100/Support/ZSDOS/PUTBG.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/PUTDS.COM b/branches/s100/Support/ZSDOS/PUTDS.COM deleted file mode 100644 index c0ceba64..00000000 Binary files a/branches/s100/Support/ZSDOS/PUTDS.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/README.1ST b/branches/s100/Support/ZSDOS/README.1ST deleted file mode 100644 index e56c7f46..00000000 --- a/branches/s100/Support/ZSDOS/README.1ST +++ /dev/null @@ -1,30 +0,0 @@ -README.1ST -- Last-minute news for ZSDOS Distribution Disk. - -12/3/88 - -COPY.UPD updates information about COPY.COM. Please mark -your user manual with the changes. - -User 1 contains files for Apple ][ CP/M systems. - -ZSDOS is published by: - -Plu*Perfect Systems -410 23rd St. -Santa Monica CA 90402 -(213)-393-6105 (evenings) -messages may be left on Ladera Z-Node: -(213)-670-9465 (300/1200/2400) - -and is also available from: - -Sage Microsystems East -1435 Centre St. -Newton MA 02159 -(617)965-3552 (9am-1130pm) -(617)965-7259 (300/1200/2400 bps) password: DDT - - -BGii corresponds most closely to these ZCPR34 options: - -full \ No newline at end of file diff --git a/branches/s100/Support/ZSDOS/README.2ND b/branches/s100/Support/ZSDOS/README.2ND deleted file mode 100644 index d3c4332f..00000000 --- a/branches/s100/Support/ZSDOS/README.2ND +++ /dev/null @@ -1,165 +0,0 @@ -GETTINÇ STARTED. - - The natural human inclination is to start using products -before wading through the instructions. We understand that and -have developed some rather simple steps to provide initial ZSDOS -capabilities rather painlessly. This will provide the inducement -to read the appropriate sections of the manual for a complete -customized installation. Merely follow the steps listed here, -then read the manual at your liesure to learn how to tailor the -ZSDOS system to you particular needs and desires. These instruc -tions cite the relevant paragraphs in the manual in case a more -detailed description is desired. - -1® LOADINÇ THÅ DOS These steps are written around the full- -featured ZSDOS version of the Operating System to demonstrate all -of the power, and provide procedures for systems already using -either type of Time Stamping supported by ZSDOS. It is recom -mended that these steps be followed initially, followed by a -later installation with ZDDOS if either a minimal memory configu -ration is desired, or only DateStamper-type File Stamping is -desired. The differences between ZSDOS and ZDDOS are briefly -described in Section 1 of the manual. - - A. DO YOU OPERATE UNDER NZ-COM? (3.1.2) - If No, Go To Step B. - If Yes, - - Rename ZSDOS.ZRL to NZDOS.ZRL and replace your - existing NZDOS.ZRL with this new file. Reinstall - NZCOM and load the system. - - Go to Step 2. - - B. DO YOU HAVE Plu*Perfect Systems' JETLDR? (3.1.3) - If No, Go To Step C. - If Yes, - - Type: - JETLDR ZSDOS.ZRL - - Go to Step 2. - - C. ARE YOU USING AN SB-180/FX-180 with XBIOS? (3.1.4) - If No, Go To Step D. - If Yes, - - Enter SYSBLD with your current system model. - Select Menu 1.1, and change the DOS name to - ZSDOS.ZRL. Exit SYSBLD, and "XBOOT" the new image. - - Go to Step 2. - - D. YOU ARE INSTALLING TO A BOOTABLE SYSTEM IMAGE. (3.1.1) - - (1) Create a system image file with MOVCPM, MOVZSYS or - whatever facility you computer uses (ONEAC ON! - image is already in this form). Save the moved - system image to a disk file remembering the name. - - - (2) Call the ZSDOS Installation tool in absolute mode - (3.1.1.1) with: - INSTALOS /A - Read in the image created above, and select option - 2 to replace the DOS. Load the ZSDOS.ZRL file and - answer 'N' (No) to the prompt asking whether to - configure default options. Select menu option 4 to - exit the program and save the new image. - - (3) Install the new image on your system boot tracks - with the SYSGEN utility provided with your computer. - WARNING: PERFORM THIS STEP ON A WORKING DISK, NOT A - MASTER DISK. Reboot your system from this disk and - you will be operating under ZSDOS. - - -2. You should have completed installation of one of the forms in -step 1 at this point, and have ZSDOS up and running. To see what -Time Stamps can do for your system, two files have been pre- -configured on the distribution disk. LDTIMD.COM is an RSX form -of DateStamper with the Relative clock. LDTIMP.COM is an RSX form -of P2DOS stamping also with the Relative clock. If you are -unfamiliar with the two methods, a brief comparison is: - - Stamp Method Advantages Disadvantages - ------------ ---------- ------------- - DateStamper(tm) Wide acceptance Slight Time penalty - Uses Only 1 Dir Stamp file can be - entry erased - Offers Last Access - stamp - - P2DOS (CP/M Plus) Fast Uses 1/4 of Dir - Entries - -If you do NOT want Date/Time Stamp or clock support, go to -Step 3, otherwise activate one of the two programs by entering -either LDTIMD or LDTIMP (see LDTIM, 3.2.3). Then Set the clock -using TD.COM (4.6). - -To see the effect of stamping, prepare a disk for stamping with -PUTDS.COM (3.2.4) if you selected LDTIMD, or INITDIR.COM (3.2.5) -if you selected LDTIMP. Copy or edit some files and note the -effect with ZXD (4.11). You will probably want to tailor the -stamping to your system clock or other parameters now, so please -read Section 3 of the manual for details. - - -3. FINAL TOUCHES. After you have completed whichever of the above -steps you elected, we recommend highly that you read at least -Sections 1 and 2 of the manual to learn the power that ZSDOS can -bring to 8-bit computers. Learn to use the tools provided with -the ZSDOS distribution package to customize the Operating System -to your own requirements and desires. All tools listed below -operate equally well under ZSDOS and ZDDOS unless specifically -noted. Briefly, the tools are: - - - COPY - Copy single or groups of files between disk drives -and/or user areas preserving date/time stamps (Modification of -ZCPR tool MCOPY). (4.1) - - DATSWEEP (ZDDOS or ZSDOS with DateStamper only) - -Plu*Perfect's full-featured screen-oriented disk and file utility -(4.2). - - FILEATTR - Display/Set attributes of individual or groups of -files. (4.3) - - FILEDATE (ZDDOS or ZSDOS with DateStamper only) - Full fea -tured Disk directory lister that permits elaborate selective -listing based on DateStamper-style Date/Time files. (4.4) - - INITDIR - Initialize a disk directory for P2DOS (CP/M Plus) -type Date/Time Stamping. (3.2.5) - - PUTDS - Initialize a disk for DateStamper type Date/Time -Stamping (licensed Plu*Perfect utility). (3.2.4) - - RELOG - Resets Hard Disk Login vectors. Primarily for use -in more elaborate Hard Disk systems which swap logical Hard -Drives, or use removeable-media, but are defined as Fixed Drives. -(4.5) - - TD - Display/Set an installed clock via ZSDOS/ZDDOS. (4.6) - - ZCAL - Display a brief calendar of current or any desired -month. (4.7) - - ZCNFG - Configuration utility to set defaults, such as US or -European date displays, in COPY, FILEATTR, FILEDATE, TD, and ZXD. - - ZPATH (ZSDOS only) - Permits setting the Internal DOS path -as well as a ZCPR3 path (Modification of ZCPR tool PATH). (4.9) - - ZSCONFIG - Basic configuration program for both ZSDOS and -ZDDOS. Operates in both interactive and command-line driven -modes wih the latter being ideal for customizing the System from -a STARTUP file under ZCPR3 environments. Options vary between -ZSDOS and ZDDOS. (4.10) - - ZXD - Directory lister for DateStamper and/or P2DOS (CP/M -Plus) Date/Time stamping methods (Extensive modification of ZCPR -tool XD III). (4.11) - \ No newline at end of file diff --git a/branches/s100/Support/ZSDOS/RELOG.COM b/branches/s100/Support/ZSDOS/RELOG.COM deleted file mode 100644 index 13ffc62e..00000000 Binary files a/branches/s100/Support/ZSDOS/RELOG.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/SETTERM.COM b/branches/s100/Support/ZSDOS/SETTERM.COM deleted file mode 100644 index eca19bf9..00000000 Binary files a/branches/s100/Support/ZSDOS/SETTERM.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/SETUPZST.COM b/branches/s100/Support/ZSDOS/SETUPZST.COM deleted file mode 100644 index 35e4b589..00000000 Binary files a/branches/s100/Support/ZSDOS/SETUPZST.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/STAMPS.DAT b/branches/s100/Support/ZSDOS/STAMPS.DAT deleted file mode 100644 index 23cd9bd7..00000000 Binary files a/branches/s100/Support/ZSDOS/STAMPS.DAT and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/TD.CFG b/branches/s100/Support/ZSDOS/TD.CFG deleted file mode 100644 index ab44bab9..00000000 Binary files a/branches/s100/Support/ZSDOS/TD.CFG and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/TD.COM b/branches/s100/Support/ZSDOS/TD.COM deleted file mode 100644 index 552aba67..00000000 Binary files a/branches/s100/Support/ZSDOS/TD.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/TERMBASE.DAT b/branches/s100/Support/ZSDOS/TERMBASE.DAT deleted file mode 100644 index 358d61c0..00000000 Binary files a/branches/s100/Support/ZSDOS/TERMBASE.DAT and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/TESTCLOK.COM b/branches/s100/Support/ZSDOS/TESTCLOK.COM deleted file mode 100644 index d547e2b8..00000000 Binary files a/branches/s100/Support/ZSDOS/TESTCLOK.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/USERCLOK.TEM b/branches/s100/Support/ZSDOS/USERCLOK.TEM deleted file mode 100644 index 619215d5..00000000 --- a/branches/s100/Support/ZSDOS/USERCLOK.TEM +++ /dev/null @@ -1,185 +0,0 @@ - TITLE "Clock module name - (REL clock name here)" - SUBTTL "Description of Clock Module" -;================================================================ -; Place brief description and machine clock I/O parameters here -; along with any version and date data -;================================================================ - -VERS EQU 01 - .Z80 - NAME CCLOK ; Change this to no more than 6-char - ; name for the REL driver module - - MACLIB CLOCK.LIB ; Some useful equates are here - -; This first section contains identification information for the driver -; The information is not placed in the clock driver code section, but are -; located in a different area located by the _CLKID Named Common directive. - - COMMON /_CLKID/ - -DESCST: DEFW 0000 ; Add label here if a static year byte - ; is used by your clock driver. The - ; label should point to the year byte - -CLKNAM: DEFB 'Myclock ' ; Exactly 24 chars in name - DEFB VERS/10+'0','.',VERS MOD 10 +'0',0 - -DESCR: DEFB ' This description may be longer than the brief',CR,LF - DEFB ' name string above, and must be null-terminated',0 - - IF [$-DESCST] > 256 - OVER2 ; This must be less than or equal to 256 bytes - ENDIF - - PAGE - SUBTTL "Configurable Clock Hardware Parameters" -;--------------------------------------------------------------------- -; This section contains any configurable parameters needed for the -; clock driver. They must be structured in the manner shown in order -; for the loader to properly match and set the values. -; The values in this section are not loaded in the same code section -; as the actual driver code, but are located in another base referenced -; by the _PARM_ Named Common directive. - - COMMON /_PARM_/ - -PARBAS: DEFW NPARAMS ; # of parameters (Set to 00 if none) - DEFW STRS ; Pointer to STRS (Set to 00 if none) -NP0: -XYR EQU $+1 - DEFB BYTE ; EXAMPLE! - This shows a byte value - DEFW 88H ; " - ..and default value in Set - -XPORT EQU $+1 - DEFB WORD ; EXAMPLE! - This shows a 16-bit value - DEFW 0F013H ; " - ..and default value in Set - -NPARAMS EQU ($-NP0)/3 - -STRS: DEFB 'Default Year',0 ; EXAMPLE! - Text prompt for XYR - DEFB 'Default Port',0 ; EXAMPLE! - Text prompt for XPORT - - PAGE - SUBTTL "Clock Code - SB180 HeartBeat" -;------------------------------------------------------------------ -; This section should contain the actual Clock Driver code, and all -; entries here are located in the CSEG, or Code Segment. - - CSEG - -; Add any needed equates here if they are not included in CLOCK.LIB - -TIMOFF EQU 36H ; EXAMPLE! - Bios offset for clock ptr - -;----------------------------------------------------------- -; Z S D O S C L O C K H E A D E R -;----------------------------------------------------------- -; Enter: HL points to a 6-byte buffer to Get/Set time -; Exit : A=1 on Success, A=FFH if error -; HL points to last char in buffer -; NOTE: If clock Set is not included, comment these two jumps -; out to save a few bytes. The loader, SETUPZST, uses -; these two jumps to recognize a full ZSDOS clock and -; modify the interface code. - -PRGBAS: JP GETTIM ; Jump to Read Clock - JP WRCLK ; Jump to Set Clock - -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; R e a d T h e C l o c k -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Clock READ code starts here. - -GETTIM: ; The work of reading the clock - ; goes here. Values needing to be set - ; during installation are referenced as: -;YPORT1 EQU $+1 -; LD BC,0000 ; EXAMPLE! - this will set a 16-bit value -; ; in the configuration process -;YYR EQU $+1 ; EXAMPLE! - This will set an 8-bit value -; LD A,00 ; in the configuration process - -; ... Place the meat of the driver in this section ... - -OKRET: LD A,01 ; Set OK status return - RET - -ERRET: OR 0FFH ; Set Error code if needed - RET - -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; S e t T h e C l o c k -;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Clock Set code placed here if needed. If Clock Setting -; is not being added, comment out this section to save a -; byte of code. - -WRCLK: - RET - - PAGE - SUBTTL "Run-Time Configuration of Ports and Masks" -;------------------------------------------------------------- -; This code installs configurable items into the clock module -; Enter with DE pointing to the physical base address of the -; relocatable module. DE MUST BE USED TO SET VALUES IN -; THE CSEG PORTION OF CODE! -; NOTE: Code in this section is not added to the actual clock -; driver, but placed in a different area referenced to -; the common base _POST_. - - COMMON /_POST_/ - -; Values in the _PARM_, _POST_ and _PRE_ sections may be loaded -; and saved directly, since their addresses are constant from -; linkage through execution. Setting or reading values in the -; CSEG must be indirect based on the value in the DE register -; pair. The following examples show how to access the various -; sections. -; -; LD A,(XYR) ; EXAMPLE - Get byte from _PARM_ directly -; LD HL,YYR ; " - Begin offset into CSEG indirectly -; ADD HL,DE ; " - HL now addresses relocated loc'n -; LD (HL),A ; " - ..so value can be stored -; -; Likewise, 16-bit values must be accessed indirectly, and may use -; the BC register pair as transfer storage. -; -; LD BC,(XPORT) ; EXAMPLE - Get word from _PARM_ directly -; LD HL,YPORT1 ; " - Begin offset into CSEG indirectly -; ADD HL,DE ; " - HL now addresses relocated loc'n -; LD (HL),C ; " - ..so value can be saved.. -; INC HL ; " - ...a byte.. -; LD (HL),B ; " - ....at a time.. -; -; LD (YPORT2),BC ; EXAMPLE - Values can be stored directly into -; " - other sections such as _PRE_ - - RET ; This RETURN MUST be present even if no other - ; code is included in this section - - - PAGE - SUBTTL "Pre-Execution Clock Checks (Check for ticking)" -;---------------------------------------------------------------- -; This module is executed just prior to installing the module to -; insure that a valid clock is present -; Enter with DE pointing to base of relocated clock code segment - - COMMON /_PRE_/ - -; Optional final setup of the clock module may go here. Examples of such -; code would be installation-dependant items such as physical RAM location -; for the driver module. If any code is added here, the DE register pair -; MUST be preserved to properly inter PRECLOCK code (If included). - -;YPORT2 EQU $+1 ; EXAMPLE - just to show accessing method -; LD BC,0000 ; " - ..from _POST_ code. - - INCLUDE PRECLOCK.LIB ; This section of code merely calls the - ; clock and waits an arbitrary period of - ; time (>> 1 second) to see if the time - ; changes. It returns an error if not. - END - \ No newline at end of file diff --git a/branches/s100/Support/ZSDOS/ZCAL.COM b/branches/s100/Support/ZSDOS/ZCAL.COM deleted file mode 100644 index a5add241..00000000 Binary files a/branches/s100/Support/ZSDOS/ZCAL.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZCNFG.COM b/branches/s100/Support/ZSDOS/ZCNFG.COM deleted file mode 100644 index ae423dc5..00000000 Binary files a/branches/s100/Support/ZSDOS/ZCNFG.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZCNFG24.CFG b/branches/s100/Support/ZSDOS/ZCNFG24.CFG deleted file mode 100644 index 1bfe49bf..00000000 Binary files a/branches/s100/Support/ZSDOS/ZCNFG24.CFG and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZDDOS.HEX b/branches/s100/Support/ZSDOS/ZDDOS.HEX deleted file mode 100644 index aaa41d74..00000000 --- a/branches/s100/Support/ZSDOS/ZDDOS.HEX +++ /dev/null @@ -1,254 +0,0 @@ -:0A0A0600C39BE423E723E723E72363 -:100A1000E7000000006DEBF12CF12CF12CF1EBF173 -:100A2000EBF1EBF10000000000000000000080008E -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000005A44444F5320312E3120436F7010 -:100A70007972696768742028632920313938372CE6 -:100A800038382020432E572E436F7472696C6C20C7 -:100A90002620482E462E426F776572AF476F672239 -:100AA0004CE4224EE4ED7361E4319BE4DDE5D5DDF9 -:100AB000E1DD225DE4DD225FE421BDE7E579324B33 -:100AC000E4FE0C380DFE31380DFE62D8FE68D0D63B -:100AD000314F2185E8E521E2E409097E23666F4B69 -:100AE0007BE9A1E750E53BE615F212F20FF25AE579 -:100AF00091E58EE5ACE695E58EE699E8E1E752E909 -:100B000042EE8FEB38E85FE86FE846EF87EF8DEE57 -:100B10007AE8C0E882E824ECBCE8D8EAB4E891E8D6 -:100B2000C4E8D3E83CEF7CEFDFE8E7E8F1E788E8EA -:100B3000B8E87CEF88E888E888E888E8CFE888E8C3 -:100B4000C8E8B0E8E2F1E5F18CE889E8B8F1B8F17D -:100B5000CD75E5D8E5CD3BE6E1C91C28141C280677 -:100B60001C2812C30CF23A29E4B73E01CC06F2A7C6 -:100B7000C9CD66E5C82129E47E3600B7CC09F2FE6E -:100B80000DC8FE0AC8FE09C8FE08C8FE20C9320307 -:100B9000003A0300C93A26E43227E413AF1213D512 -:100BA000CD75E5D1219FE5E52A5DE44E23FE0D28B4 -:100BB00074FE0A2870FE7F2804FE0820367EA7C82F -:100BC0001B35D54623EB2126E44E237E2B770418D4 -:100BD000051ACD6AE61310F979964771D1D50E083A -:100BE000C5CD0CF20E20CD0CF23E08CD3BE6C11077 -:100BF000EDD1C9FE152804FE18200AAFB6C8E5CD10 -:100C0000C0E5E118F6FE1020072128E47E2F77C901 -:100C100012E5CD2AE6E1347EB9280A3D1A13C0FE5A -:100C200003C0C3A1E7E13E0D1811FE20300DFE09FF -:100C3000280DF53E5ECD4EE6F1C640FE09200F3E82 -:100C400020CD4EE63A26E4E60720F43E09C9C5D594 -:100C50004FC5CD8EE6C1C5CD0CF2C1C53A28E4B76B -:100C6000C40FF2C179D1C12126E434FE7F2815FEDC -:100C700020D0FE092811FE08280A34FE0A2805FEA5 -:100C80000DC036023535C93E0786E6F877C9CD6610 -:100C9000E5C8CD75E5FE13200ACD09F2FE0320EE6E -:100CA000C3A1E73229E43E01C91120E71AFE24C896 -:100CB00013CD3BE618F6016400CDC4E60E0ACDC4A0 -:100CC000E601010116FF149130FC81F57AB0280786 -:100CD000477AC630CD54E5F1C94368616E676564F3 -:100CE0002442616420536563746F72244E6F204404 -:100CF000726976652446696C6520572F50245A44E2 -:100D0000444F53206572726F72206F6E20240D0A5B -:100D100043616C6C3A2024202046696C653A20249B -:100D20000D0A243A5CE44F0F385CC5D5CDA9E61115 -:100D3000FEE6CDACE63A2BE4C641CD3BE61114E726 -:100D4000CDACE6D1CDACE6110EE7CDACE63A4BE446 -:100D5000CDB6E63A4EE4A72829C1C5DDE53A4BE415 -:100D6000FE132004CDC6EAE31117E7CDACE6E10699 -:100D70000B233E03B83E2ECC54E57EE67FCD54E5F2 -:100D800010EFCDA9E6C13E0490200D212CE47E2B6E -:100D9000BE2805C5CD59E9C1CB4920183E01903088 -:100DA00005AF325CE4C7CD71E5A720FACD75E5FE4D -:100DB00003C018ED7867A7C82EFF224CE43A4EE432 -:100DC000B7280C3A2DE4DD77003A2CE4CD59E9ED53 -:100DD0007B61E4DD2A99E42A4CE4ED5B5FE47D4429 -:100DE000C9218000222EE4CD28ECAF322BE411FF84 -:100DF000FFCD27E83A15E4CB57200621FCF1CD3092 -:100E0000E83A4BE4FE0D21FEF1C430E83A2BE4F55C -:100E1000000000F1CD59E93A57E41869237E2BD63A -:100E200024C03D3257E4C97B2F5F7A2F5721FAF156 -:100E30007BA677237AA677C9CDF7E8DD7E00D63F7B -:100E4000280DDD7E0EFE3F2804DD360E003E0FCD60 -:100E5000DDEC2A34E4018000ED5B2EE4EDB0C9DD69 -:100E60002A58E4DD225DE4CDF7E8CDF4EC18E3CDBB -:100E7000F7E8CD57EC3A5AE4180BCDF7E8CDC2EDC0 -:100E800018F33A2BE4324CE4C93215E43A15E4186D -:100E9000F4CDF7E8CDEDED18DC212200FE44202B47 -:100EA0003A25E4A728256311E1F1ED535FE4181B0F -:100EB000211144DD2AFCF1DD2AFEF1DD2A3AE4DDD0 -:100EC0002AFAF1DD2A36E4DD2A2EE4224CE4C93286 -:100ED0005CE4C9212AE43C7E28AB7BE61F77C9CDC0 -:100EE00005E9CD16EE188E212000CD07F1DD722127 -:100EF000DD7122DD7023C93A5CE4A720082A5DE495 -:100F0000010D0009773EFF324EE43A2BE45F2A5D83 -:100F1000E47E322DE4FE3F2839DDE5DD2A5DE4E69E -:100F20000FE528025E1DCD52E9E1DD7E0DCB7F206D -:100F3000073A2AE41802DDE5DD2A5DE4E61FDD77E5 -:100F400000F680DD770DDDE1C92A0BE4060411EC23 -:100F5000E6E93A2BE4322CE47B2AFAF1E60F47C4A7 -:100F600039EAEB212BE4CB432802BEC877D54FCD1D -:100F70001BF27CB528D31130E4010200EDB022321F -:100F8000E40E06091134E40E08EDB02A36E40E0F23 -:100F9000EDB0D1CB43C0CD1FEAEB2AFAF1CD30EA58 -:100FA00022FAF13A15E4CB5F282A2A47E47CB54FB0 -:100FB0002AFEF17BA56F7AA4B53EFF28013C47B11C -:100FC000C8AF676FB0280A79B720092AFEF1CD3083 -:100FD000EA22FEF12A41E4CD37EA444D2A3AE4E51B -:100FE000545D13AF77EDB0E1ED5B45E47323722AF6 -:100FF00032E4772377CDD1EA3EFFCD05EBCDF1EAA0 -:10100000CA17E8CDC6EA7EFEE528EDFE2128E9CD27 -:101010001CE80E01CD6DECCDF8EAD4E9EA18D9212F -:101020000000EB2101003A2BE4B72804293D20FC05 -:101030007AB4677BB56FC90603CB3CCB1D10FAC9E8 -:101040002A54E40602CD39EA2252E4EB210000EDF5 -:101050004B3CE43E11B7ED423F380209B7CB13CB0E -:10106000123D2804ED6A18EDE52A49E419444DCDF6 -:101070001EF2C1ED5B30E4CD30F2444DC321F2DD10 -:101080006E20CB153A40E4DDA60C673A3EE44704F7 -:10109000CD39EA507D2A5DE40E10094F093A42E449 -:1010A000B75E2805095E23562B7AB3C92100003AA2 -:1010B0003EE447EB29CB1310FBEB3A3FE4DDA620DF -:1010C000B35FC9CD96EC3A56E42A34E4856FD02458 -:1010D000C921FFFF2254E4C92AFCF1CD22EA22FCF7 -:1010E000F1ED5B43E42A32E42313722B73C9CDDBA9 -:1010F000EC2A54E47CA53CC92A32E4ED5B54E47B41 -:1011000096237A9EC94F2A54E4232254E4ED5B438C -:10111000E47B957A9C38BA7D0F0F0FE6603256E477 -:10112000C0C5CD40EACD00EC2A54E47CB520112A9C -:1011300034E4060B234ECBB98110F9D69132F9F184 -:10114000C12A47E4ED5B52E4AFED52C8D82A34E43B -:10115000CDF2F1862A38E4190C200277C9BEC83ACC -:1011600015E4CB67060011D9E6C423E7CD1FEAEBEF -:10117000CD27E8CD0CE8CDD1EAAF1889CD27F218FC -:1011800003CD2AF2B7C8060111E1E62A09E4E9CD48 -:1011900005E9DDCB0E7EC0CDC2ECCDEEEAC8CDC3F5 -:1011A000EA01100009EB2A5DE409EB4134351A2805 -:1011B00004BEC204EF77132310F211ECFF19DD7E99 -:1011C0000CBE380877232323DD7E0F77CDF1EBCDDE -:1011D0002EEF280DC5010000CD28EFCDEEEAC12885 -:1011E0000DC5CDF1EB2A1CE40E0ACD8CEEC1C3284F -:1011F000EFCDC6EA010B0009CBBEDDCB0BBE180854 -:10120000CD2EECCD7CEB1820CDC6EA3E0DCDCCEA40 -:101210003600CD40EA0EFFCD41EBCD2EEC0E01CDD8 -:1012200081EB1804ED532EE4ED4B2EE41804ED4B46 -:1012300034E4C324F27BE6073C4FEBCD37EA47EDBD -:101240005B3AE4197E0710FD41C9C5CD35ECE6FED9 -:10125000D1B30F10FD77C9CDA8EDCDC3EA36E52394 -:101260007ED62420033257E423CBBE0E00CDC6EA3F -:1012700011100019435E2316003A42E4B728030513 -:1012800056237AB3280DE5C52A41E4B7ED52D44A76 -:10129000ECC1E110E0C9CDC6EA11080019ED5B13FD -:1012A000E41AA72004CB7E201023CB7E200BDDCBBD -:1012B000077EC83A15E4E602C02A0FE4060311F5DA -:1012C000E6E9CDCFECC0060211FAE62A0DE4E92AE0 -:1012D000FCF1CD22EAED52C93E0C213E0F325BE417 -:1012E0003EFF325AE4DD2258E4CDD1EA2A47E47CBD -:1012F000B5C418F2AF676F2250E4DDCB07BECD0551 -:10130000EBCDF1EA280EED5B58E41AFEE52807D58F -:10131000CDF8EAD1306CCDC6EA7EFE2128D60E008B -:101320003A5BE44778B728601AEE3FE67F283C79BD -:10133000B720233A15E41F301D2323CB7E2B2B2807 -:10134000151AFEE52810AEE67F281A3EFF3251E45A -:10135000DDCB07FE180F79FE0D280AFE0C1A2811A6 -:10136000AEE67F208F13230C0518B93D3250E418E8 -:10137000F4AECD77ED18ECC5473A40E42FE61FA058 -:10138000C1C9CDD1EAC304EF2A50E47CA520D4CD55 -:10139000F8EAD4E9EA2A52E4225FE43A54E4E603A4 -:1013A000324CE4AF325AE4C9CDC2ECCDD8ECCDF129 -:1013B000EAE1C8E5E521BAEDE3E9CD08ECCDF4ECCE -:1013C00018ECCDA8EDCD96EC2A5DE411100019EBD8 -:1013D000CDC6EA2323CBBE2B2B060B23131AE67FA5 -:1013E000FE3F20017E17CB161F7710EFC9CDA8ED69 -:1013F000DDE5D1CDC6EA060B23133E04B8200EE589 -:101400002A13E47EE1A72005CB7EC2B9EC1ACB16E5 -:1014100017CB1E10E3C901000051CDEDE8CDD8EC8B -:10142000CDF1EAC8CDC6EAEB210F00CD07F17ADD98 -:10143000962179DD9E2278DD9E23D4EDE8CDF4EC73 -:1014400018DECDF7E8DD360E00CDEEEAC8DD7E070A -:10145000F5DD7E0CF5CDC6EA7EF680DDE5D1012016 -:1014600000EDB0DD770DCD02F1DD460CDD4E0FF164 -:10147000DD770CB828040E00CB19DD710FF1DDCB40 -:10148000071617DDCB071E0E052A18E4E9CDF7E88D -:10149000DD360E00CDC2EC2A5DE47EF536E53E0178 -:1014A000CDDDECF1DD7700CDF1EAC82A5DE4CD1C9D -:1014B000E8110F00190611AF772310FCDDCB07BE32 -:1014C000DDCB0BBECDC6EADDE5D1EB012000EDB0F2 -:1014D000CD08ECCD02F10E00C32CF1DDCB0E7E2049 -:1014E00008CD92EB3A4CE43CC8CD0FEF3813CDEE6B -:1014F000EA20163A4FE4B72808CD94EECDF1EA2061 -:101500000BCD02F13EFFC385E8CD4DEEAF18F7CD10 -:101510002EEFCB7037C00C79E61F4F20070478E61A -:101520003F4737C8DD362000DD710CDD700EDD4E23 -:101530000CDD460E79CD77EDCBB8B0C9CD05E9AF5E -:10154000CD7EF02804C9CD05E9AF324FE4DD7E2021 -:10155000FE802809DDBE0F38073E0118A9CD71EFC6 -:10156000CD7FEA28F4CDACEACD4FEACD7CEBC36C5D -:10157000F0CDDBEE3A4CE4B7C8E118DDCD05E93E2D -:10158000FFCD7EF02804C9CD05E93EFF324FE4CD02 -:10159000C2ECDDCB097E200ECDAEEC2A13E47EA793 -:1015A0002007DDCB087EC2B9ECDDCB207EC471EF15 -:1015B000CD7FEAC24BF0E579B728043DCD95EA62CC -:1015C0006B7AB3280B1BE5D5CD35EC1F3020D1E16C -:1015D000ED4B41E47D917C98300E23D5E5EBCD3584 -:1015E000EC1F300AE1D118D97AB320D51807371784 -:1015F000CD52ECD1E1E17AB3287FDDCB0EBE733A58 -:1016000042E4B7280223720E023A3FE4DDA6202806 -:10161000020E003A4BE4D6282033D52A34E4068063 -:10162000772310FCCDACEA3A3FE447042FA35F0ECA -:1016300002E5D5C5CD4FEACD2EECC1C5CD81EBC1BC -:10164000D1E10E001C10EACD28ECD10E00DDCB0E4E -:10165000BEC5CDACEACD4FEAC1CD81EBDD7E20DD4C -:10166000BE0F38083CDD770FDDCB0EBE3A4BE4FEF3 -:1016700014D8FE16D0DD3420C93E02C385E8324FAF -:10168000E4DD7E2157CBBA17DD7E2217F5E61F4F2A -:10169000F117171717E60F47DD7E231E06FE0430ED -:1016A0005C070707078047DD7220DD560ECB7220EE -:1016B0000E79DDBE0C200878DDAE0EE63F2837CB74 -:1016C0007A200FD5C5CD92EBC1D11E033A4CE43C34 -:1016D0002827CD28EFCDDBEC3A4CE43C20153A4FDF -:1016E000E41E043C2013CD94EE1E053A4CE43C2845 -:1016F000081803CD4DEEC30CEFDD360EC07B324C27 -:10170000E4B7DDCB0EFEC9197E210C0019577EE629 -:101710001FCB12CE001FCB1A4F23237E0F0F0F0FAC -:10172000F5E60347F1E6F0814FD004C93AF9F1B785 -:10173000C0DDCB037EC0C5CD2EEFC1C0473A4BE420 -:10174000FE662806CDCFECCAEBF1C53A56E41F2A57 -:1017500052E4CB3CCB1D3002C640F5E52A45E43AC5 -:101760003FE43C5F500610293003E319E310F8E131 -:10177000CD4BEACD00ECCDEEF1BE2038F1CDC9EA7B -:10178000C13A4BE4FE66C8FE67281609C5CDE1F1F3 -:10179000C13C28577379B72012060A772310FC182A -:1017A0000AED5B2EE4EB010F00EDB0CDEEF177CD4D -:1017B0001AECAFC9E1E11833CDF7E8CDEEEA282BFA -:1017C0003A4BE4FE672811DDCB03BECD2CF1200B94 -:1017D000010F00CD58E81803CD2CF1CA59EFC3040E -:1017E000EFEB0E00210E012A16E4E5F6FFC9AF2A41 -:1017F00034E4067F862310FCC900000000000000CE -:10322000005581AA0A000000000000000000000014 -:10323000000000001209100901001001A8AAAAAAA2 -:10324000AAAAAAAAAAAAAAAAAAAA8400204188402D -:103250000000800444040000000110000821000068 -:103260000208100010008000480010420402000014 -:1032700000001108240808080100400000000000B8 -:10328000000000002040929044922480402400825C -:103290001020400010410090204844224022482045 -:1032A0000949400220800004000012084412929054 -:1032B0009048480004224044442422001210008216 -:1032C00000121140000108080008910822000201C4 -:1032D00041200091241004000020494200088290FF -:1032E000240042120001000084040400000842424D -:1032F00040208480000002102009402491000944ED -:103300000011018090040280888044000249244119 -:10331000082402120101100000400224901009004C -:1033200024841012820812200420001280800008D9 -:103330000004010101002008112412801049080234 -:103340000902040104002000008000000040100871 -:103350009004922444248190900404000080200072 -:10336000041000904420009010088000000100002C -:10337000008840020422010040002404480821483B -:1033800008090200000080400411008084244940A4 -:1033900008420224008124400004080001000400C7 -:1033A0000208202040024042000290080040002015 -:1033B0000100000000000000804090040121200175 -:1033C00001000000004000824022024002002481EF -:1033D00008800000102002240420202401020200A2 -:0000000000 - \ No newline at end of file diff --git a/branches/s100/Support/ZSDOS/ZDDOS.ZRL b/branches/s100/Support/ZSDOS/ZDDOS.ZRL deleted file mode 100644 index 800f2a33..00000000 Binary files a/branches/s100/Support/ZSDOS/ZDDOS.ZRL and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZPATH.COM b/branches/s100/Support/ZSDOS/ZPATH.COM deleted file mode 100644 index 5c0aa503..00000000 Binary files a/branches/s100/Support/ZSDOS/ZPATH.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZSCONFIG.COM b/branches/s100/Support/ZSDOS/ZSCONFIG.COM deleted file mode 100644 index 2cc26074..00000000 Binary files a/branches/s100/Support/ZSDOS/ZSCONFIG.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZSDOS.HEX b/branches/s100/Support/ZSDOS/ZSDOS.HEX deleted file mode 100644 index 7b32bc49..00000000 --- a/branches/s100/Support/ZSDOS/ZSDOS.HEX +++ /dev/null @@ -1,254 +0,0 @@ -:0A0A0600C39BE44CE74CE74CE74CBF -:100A1000E7F1F100006DDDF1DDF1DDF1DDF1DDF19A -:100A2000DDF1DDF1000000000000000000008000AA -:100A300000000000000000000000000000000000B6 -:100A400000000000000000000000000000000000A6 -:100A50000000000000000000000000000000000096 -:100A60000000005A53444F5320312E3120436F7001 -:100A70007972696768742028632920313938372CE6 -:100A800038382020432E572E436F7472696C6C20C7 -:100A90002620482E462E426F776572AF476F672239 -:100AA0004CE4224EE4ED7361E4319BE4DDE5D5DDF9 -:100AB000E1DD225DE4DD225FE421E6E7E579324B0A -:100AC000E4FE0C380DFE31380DFE62D8FE68D0D63B -:100AD000314F21BBE8E521E2E409097E23666F4B33 -:100AE0007BE9CAE750E564E615F212F20FF25AE527 -:100AF00091E58EE5D5E695E5B7E6CFE80AE87AE92F -:100B0000B4EEA8EB6EE895E8A5E8BEEFFFEF02EFC4 -:100B1000B0E8E8E8B8E833ECE4E803EBDCE8C7E881 -:100B2000ECE8FBE8B4EFF4EF07E90FE91AE8BEE8F8 -:100B3000E0E8F4EFBEE8BEE8BEE8BEE8F7E8BEE8ED -:100B4000F0E8D8E8D7F1D4F1C2E8BFE8A4F1A4F105 -:100B5000CD75E5D8E5CD64E6E1C91C28141C28064E -:100B60001C2812C30CF23A29E4B73E01CC06F2A7C6 -:100B7000C9CD66E5C82129E47E3600B7CC09F2FE6E -:100B80000DC8FE0AC8FE09C8FE08C8FE20C9320307 -:100B9000003A0300C93A26E43227E413AF1213D512 -:100BA000CD75E5D1219FE5E52A5DE44E23FE0D28B4 -:100BB00002FE0ACA4EE6FE7F2804FE0820367EA703 -:100BC000C81B35D54623EB2126E44E237E2B770424 -:100BD00018051ACD93E61310F979964771D1D50E01 -:100BE00008C5CD0CF20E20CD0CF23E08CD64E6C156 -:100BF00010EDD1C9FE152804FE18200AAFB6C8E5CD -:100C0000CDC1E5E118F6FE122024E5CDD2E621267D -:100C1000E4360023463E20041803CD64E610FBE1D1 -:100C20004623EB0418051ACD53E61310F9C9FE103C -:100C300020072128E47E2F77C912E5CD53E6E13461 -:100C40007EB9280A3D1A13C0FE03C0C3CAE7E13EBD -:100C50000D1811FE20300DFE09280DF53E5ECD77F2 -:100C6000E6F1C640FE09200F3E20CD77E63A26E4A5 -:100C7000E60720F43E09C9C5D54FC5CDB7E6C1C5C5 -:100C8000CD0CF2C1C53A28E4B7C40FF2C179D1C185 -:100C90002126E434FE7F2815FE20D0FE092811FE0F -:100CA00008280A34FE0A2805FE0DC036023535C96B -:100CB0003E0786E6F877C9CD66E5C8CD75E5FE1333 -:100CC000200ACD09F2FE0320EEC3CAE73229E43E32 -:100CD00001C91149E71AFE24C813CD64E618F601CC -:100CE0006400CDEDE60E0ACDEDE601010116FF141C -:100CF0009130FC81F57AB02807477AC630CD54E5AB -:100D0000F1C94368616E676564244261642053657C -:100D100063746F72244E6F2044726976652446694D -:100D20006C6520572F50245A53444F5320657272DC -:100D30006F72206F6E20240D0A43616C6C3A202480 -:100D4000202046696C653A20240D0A243A5CE44F61 -:100D50000F385CC5D5CDD2E61127E7CDD5E63A2BC5 -:100D6000E4C641CD64E6113DE7CDD5E6D1CDD5E66B -:100D70001137E7CDD5E63A4BE4CDDFE63A4EE4A7AE -:100D80002829C1C5DDE53A4BE4FE132004CDF1EA84 -:100D9000E31140E7CDD5E6E1060B233E03B83E2E36 -:100DA000CC54E57EE67FCD54E510EFCDD2E6C13ED2 -:100DB0000490200D212CE47E2BBE2805C5CD81E9B1 -:100DC000C1CB4920183E01903005AF325CE4C7CD5D -:100DD00071E5A720FACD75E5FE03C018ED7867A789 -:100DE000C82EFF224CE43A4EE4B7280C3A2DE4DD3D -:100DF00077003A2CE4CD81E9ED7B61E4DD2A99E4CA -:100E00002A4CE4ED5B5FE47D44C9218000222EE49E -:100E1000CD37ECAF322BE411FFFFCD5DE83A15E49E -:100E2000CB57200621FCF1CD66E83A4BE4FE0D21BC -:100E3000FEF1C466E82AFEF1CD58EAEB21F8F1CDC7 -:100E400066E83A2BE4F5000000F1CD81E93A57E479 -:100E50001869237E2BD624C03D3257E4C97B2F5F0F -:100E60007A2F5721FAF17BA677237AA677C9CD1F6F -:100E7000E9DD7E00D63F280DDD7E0EFE3F2804DD35 -:100E8000360E003E0FCDF3EC2A34E4018000ED5B1A -:100E90002EE4EDB0C9DD2A58E4DD225DE4CD1FE982 -:100EA000CD0AED18E3CD1FE9CD6DEC3A5AE4180BED -:100EB000CD1FE9CDD7ED18F33A2BE4324CE4C9321B -:100EC00015E43A15E418F4CD1FE9CD02EE18DC2143 -:100ED0002200ED535FE4181B211153DD2AFCF1DDE4 -:100EE0002AFEF1DD2A3AE4DD2AFAF1DD2A36E4DDD4 -:100EF0002A2EE4224CE4C9325CE4C9212AE43C7E77 -:100F000028B97BE61F77C9CD2DE9CD2BEE189C21A2 -:100F10002000CD7FF1DD7221DD7122DD7023C93A21 -:100F20005CE4A720082A5DE4010D0009773EFF324A -:100F30004EE43A2BE45F2A5DE47E322DE4FE3F2846 -:100F400039DDE5DD2A5DE4E60FE528025E1DCD7A98 -:100F5000E9E1DD7E0DCB7F20073A2AE41802DDE5CA -:100F6000DD2A5DE4E61FDD7700F680DD770DDDE14B -:100F7000C92A0BE406041115E7E93A2BE4322CE404 -:100F80007B2AFAF1E60F47C461EAEB212BE4CB435D -:100F90002802BEC877D54FCD1BF27CB528D31130BF -:100FA000E4010200EDB02232E40E06091134E40E31 -:100FB00008EDB02A36E40E0FEDB0D1CB43C0CD47DB -:100FC000EAEB2AFAF1CD58EA22FAF13A15E4CB5FBE -:100FD000282A2A47E47CB54F2AFEF17BA56F7AA424 -:100FE000B53EFF28013C47B1C8AF676FB0280A790A -:100FF000B720092AFEF1CD58EA22FEF12A41E4CDBC -:101000005FEA444D2A3AE4E5545D13AF77EDB0E171 -:10101000ED5B45E47323722A32E4772377CDFCEA53 -:101020003EFFCD30EBCD1CEBCA4DE8CDF1EA7EFEA4 -:10103000E528EDFE2128E9CD52E80E01CD83ECCD67 -:1010400023EBD414EB18D9210000EB2101003A2B3B -:10105000E4B72804293D20FC7AB4677BB56FC90644 -:1010600003CB3CCB1D10FAC92A54E4CB3CCB1DCB9F -:101070003CCB1D2252E4EB210000ED4B3CE43E1141 -:10108000B7ED423F380209B7CB13CB123D2804ED30 -:101090006A18EDE52A49E419444DCD1EF2C1ED5B15 -:1010A00030E4CD30F2444DC321F2DD6E20CB153A51 -:1010B00040E4DDA60C673A3EE44704CD61EA507D8A -:1010C0002A5DE40E10094F093A42E4B75E2805098B -:1010D0005E23562B7AB3C92100003A3EE447EB2940 -:1010E000CB1310FBEB3A3FE4DDA620B35FC9CDACD8 -:1010F000EC3A56E42A34E4856FD024C921FFFF225C -:1011000054E4C92AFCF1CD4AEA22FCF1ED5B43E448 -:101110002A32E42313722B73C9CDF1EC2A54E47CF8 -:10112000A53CC92A32E4ED5B54E47B96237A9EC940 -:101130004F2A54E4232254E4ED5B43E47B957A9CEC -:1011400038BA7D0F0F0FE6603256E4C0C5CD68EAAD -:10115000CD3DECCD95EBCD37ECC12A47E4ED5B52AC -:10116000E4AFED52C8D82A34E4CDE0F1862A38E461 -:10117000190C200277C9BEC83A15E4CB67060011E6 -:1011800002E7C44CE7CD47EAEBCD5DE8CD35E8CDCD -:10119000FCEAAF189BCD27F21803CD2AF2B7C80698 -:1011A00001110AE72A09E4E9CD2DE9DDCB0E7EC065 -:1011B000CDD8ECCD19EBC8CDEEEA01100009EB2A31 -:1011C0005DE409EB4134351A2804BEC27AEF771387 -:1011D0002310F211ECFF19DD7E0CBE3808772323B3 -:1011E00023DD7E0F77CD08ECCDA6EF280DC50100DD -:1011F00000CD9EEFCD19EBC1280BC5CD08EC2A1C04 -:10120000E4CDB9F1C1C39EEFCDF1EA010B0009CBEA -:10121000BEDDCB0BBE1800CDF1EA3E0DCDF7EA36B0 -:1012200000CD68EA0EFFCD5AEBCD3DEC0E01CD9A14 -:10123000EB1804ED532EE4ED4B2EE41804ED4B3483 -:10124000E4C324F27BE6073C4FCB3ACB1BCB3ACB33 -:101250001BCB3ACB1B472A3AE4197E0710FD41C944 -:10126000C5CD44ECE6FED1B30F10FD77C9CDBDED81 -:10127000CDEEEA36E5237ED62420033257E423CB95 -:10128000BE0E00CDF1EA11100019435E2316003A9C -:1012900042E4B728030556237AB3280DE5C52A4151 -:1012A000E4B7ED52D460ECC1E110E0C9CDF1EA1130 -:1012B000080019ED5B13E41AA72004CB7E2010234D -:1012C000CB7E200BDDCB077EC83A15E4E602C02AB0 -:1012D0000FE40603111EE7E9CDE5ECC00602112379 -:1012E000E72A0DE4E92AFCF1CD4AEAED52C93E0CA9 -:1012F000213E0F325BE43EFF325AE4DD2258E4CD5A -:10130000FCEA2A47E47CB5C418F2AF676F2250E4C8 -:10131000DDCB07BECD30EBCD1CEB280EED5B58E4EA -:101320001AFEE52807D5CD23EBD1306BCDF1EA7E4F -:10133000FE2128D60E003A5BE44778B7285F1AEE04 -:101340003FE67F283B79B720223A15E41F301C2363 -:1013500023CB7E2B2B28141AFEE5280FAEE67F2820 -:10136000193EFF3251E4CDAFEE180F79FE0D280A79 -:10137000FE0C1A2811AEE67F209013230C0518BA34 -:101380003D3250E418F4AECD8CED18ECC5473A4030 -:10139000E42FE61FA0C1C9CDFCEAC37AEF2A50E4CE -:1013A0007CA520D4CD23EBD414EB2A52E4225FE4B5 -:1013B0003A54E4E603324CE4AF325AE4C9CDD8ECF7 -:1013C000CDEEECCD1CEBE1C8E5E521CFEDE3E9CDB9 -:1013D00017ECCD0AED18ECCDBDEDCDACEC2A5DE4FB -:1013E00011100019EBCDF1EA2323CBBE2B2B060BFA -:1013F00023131AE67FFE3F20017E17CB161F7710BE -:10140000EFC9CDBDEDDDE5D1CDF1EA060B23133EED -:1014100004B8200EE52A13E47EE1A72005CB7EC2A6 -:10142000CFEC1ACB1617CB1E10E3C901000051CD2B -:1014300015E9CDEEECCD1CEBC8CDF1EAEB210F00A8 -:10144000CD7FF17ADD962179DD9E2278DD9E23D451 -:1014500015E9CD0AED18DECD19EBC03A15E4CB6FD6 -:10146000C82A11E47CB5C87E23B7CA97EDE67FFE93 -:101470002420043A2CE43C3DE5CD81E9E17E23E6DD -:101480007FFE2420033A2AE4E61FE5CD5EE9CD196C -:10149000EBE128D3E5CDF1EA110A0019CB7E3A152C -:1014A000E41717E1380228BF3A2BE43C322DE4DD83 -:1014B000CB07FEC9CD1FE9DD360E00CD57EECD1CA2 -:1014C000EBC8DD7E07F5DD7E0CF5CDF1EA7EF6801A -:1014D000DDE5D1012000EDB0DD770DCD7AF1DD46FF -:1014E0000CDD4E0FF1DD770CB828040E00CB19DDB2 -:1014F000710FF1DDCB071617DDCB071E2A18E4C3E9 -:10150000B9F1CD1FE9DD360E00CDD8EC2A5DE47EC1 -:10151000F536E53E01CDF3ECF1DD7700CD1CEBC8EF -:101520002A5DE4CD52E8110F00190611AF772310A0 -:10153000FCDDCB07BEDDCB0BBECDF1EADDE5D1EBAB -:10154000012000EDB0CD17ECCD7AF12A1AE4C3B931 -:10155000F1DDCB0E7E2008CDABEB3A4CE43CC8CDA0 -:1015600085EF3813CD19EB20163A4FE4B72808CD94 -:1015700009EFCD1CEB200BCD7AF13EFFC3BBE8CDCC -:10158000C2EEAF18F7CDA6EFCB7037C00C79E61FCF -:101590004F20070478E63F4737C8DD362000DD716D -:1015A0000CDD700EA7C9DD4E0CDD460E79CD8CED3D -:1015B000CBB8B0C9CD2DE9AFCDF6F02804C9CD2DFB -:1015C000E9AF324FE4DD7E20FE802809DDBE0F3812 -:1015D000073E0118A7CDE9EFCDAAEA28F4CDD7EA56 -:1015E000CD7AEACD95EBC3E4F0CD51EF3A4CE4B7B8 -:1015F000C8E118DDCD2DE93EFFCDF6F02804C9CDB8 -:101600002DE93EFF324FE4CDD8ECDDCB097E200E34 -:10161000CDC4EC2A13E47EA72007DDCB087EC2CF21 -:10162000ECDDCB207EC4E9EFCDAAEAC2C3F0E579B8 -:10163000B728043DCDC0EA626B7AB3280B1BE5D511 -:10164000CD44EC1F3020D1E1ED4B41E47D917C98FD -:10165000300E23D5E5EBCD44EC1F300AE1D118D98B -:101660007AB320D518073717CD68ECD1E1E17AB30A -:10167000287FDDCB0EBE733A42E4B7280223720EF8 -:10168000023A3FE4DDA62028020E003A4BE4D628B9 -:101690002033D52A34E40680772310FCCDD7EA3AEC -:1016A0003FE447042FA35F0E02E5D5C5CD7AEACD0E -:1016B0003DECC1C5CD9AEBC1D1E10E001C10EACDC5 -:1016C00037ECD10E00DDCB0EBEC5CDD7EACD7AEA20 -:1016D000C1CD9AEBDD7E20DDBE0F38083CDD770FF3 -:1016E000DDCB0EBE3A4BE4FE14D8FE16D0DD34201E -:1016F000C93E02C3BBE8324FE4DD7E2157CBBA17A7 -:10170000DD7E2217F5E61F4FF117171717E60F4773 -:10171000DD7E231E06FE04305C070707078047DDD9 -:101720007220DD560ECB72200E79DDBE0C200878BB -:10173000DDAE0EE63F2837CB7A200FD5C5CDABEB1B -:10174000C1D11E033A4CE43C2827CD9EEFCDF1ECED -:101750003A4CE43C20153A4FE41E043C2013CD09DA -:10176000EF1E053A4CE43C28081803CDC2EEC382B4 -:10177000EFDD360EC07B324CE4B7DDCB0EFEC9196F -:101780007E210C0019577EE61FCB12CE001FCB1A0C -:101790004F23237E0F0F0F0FF5E60347F1E6F0818D -:1017A0004FD004C9CD1FE9CD19EB28312A1EE43AE8 -:1017B0004BE4FE66280A2A20E4E5CDE5ECE1281D8D -:1017C000CDA6EF20183A56E4ED5B34E40117ECE5C2 -:1017D0002A2EE4C90E01210E002A16E4E5F6FFC9FF -:1017E000067F862310FCC9000000000000000000F6 -:1017F00000010000000000000000000000000000E8 -:10322000005585AA0A000000000000000000000010 -:10323000000000001209100901001001A8AAAAAAA2 -:10324000AAAAAAAAAAAAAAAAAAAA8400204188402D -:10325000000080044404200000022000104200000E -:103260000420011000021020002000000190002026 -:103270008408040000000022104810101002008092 -:103280000000000000000000004080242189244943 -:103290000081480004214080002082002041908865 -:1032A0004480449040129244129000082000010093 -:1032B00080040291842424241212204044442422B5 -:1032C000001210008200121140000108080008914D -:1032D000082200020141200091241004000020492E -:1032E00042000882902400421200010000042020C5 -:1032F0000000401012020221040400108000490066 -:1033000022890448200288080084241101890004CD -:1033100092488210480424020220000080044820C1 -:1033200089040042080941040900000108800420C2 -:10333000200002004140400000084204890420446B -:1033400012824082004100010008000020010000BC -:10335000080201924092848824101292800000009A -:1033600010048000020092080400122208102008B5 -:103370008020810001444020011000200000004016 -:1033800012488040240000088024011242081242A2 -:10339000820000000080400411008084244940081D -:1033A00042022400812440000408000100040002BD -:1033B0000820204002404200029008004000200106 -:1033C0000000000000000080409004012120010165 -:1033D0000000000040420211844804080000000080 -:0000000000 - \ No newline at end of file diff --git a/branches/s100/Support/ZSDOS/ZSDOS.ZRL b/branches/s100/Support/ZSDOS/ZSDOS.ZRL deleted file mode 100644 index e43d1b0a..00000000 Binary files a/branches/s100/Support/ZSDOS/ZSDOS.ZRL and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZSVSTAMP.CIM b/branches/s100/Support/ZSDOS/ZSVSTAMP.CIM deleted file mode 100644 index 4756dfac..00000000 Binary files a/branches/s100/Support/ZSDOS/ZSVSTAMP.CIM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZSVSTAMP.COM b/branches/s100/Support/ZSDOS/ZSVSTAMP.COM deleted file mode 100644 index 026d5d7a..00000000 Binary files a/branches/s100/Support/ZSDOS/ZSVSTAMP.COM and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZSVSTAMP.DOC b/branches/s100/Support/ZSDOS/ZSVSTAMP.DOC deleted file mode 100644 index 2a8a7c1e..00000000 --- a/branches/s100/Support/ZSDOS/ZSVSTAMP.DOC +++ /dev/null @@ -1,118 +0,0 @@ - ZSVSTAMP USAGE NOTES - - - -1.0 INTRODUCTION - - ZSVSTAMP is a utility program that saves the create -date/time stamp of a given file in memory. At a later time, -ZSVSTAMP can restore the create stamp to a file. This can be -useful when modifying a file with an editor that actually creates -a new copy of the file rather than modifying it in place. -ZSVSTAMP allows the original creation date of the document to be -retained. - - In order to support all types of date stamping under ZSDOS, -ZSVSTAMP uses the get/set stamp functions of ZSDOS (or ZDDOS) and -thus may only be run under these operating systems. It also -requires ZCPR3 with multiple command line, external FCB and -message buffer. If an attempt is made to run ZSVSTAMP on a -system that does not meet these requirements, the program will -abort with an error message. - - - -2.0 OPERATION - - ZSVSTAMP has two modes of operation -- Manual and Automatic. - - - -2.1 Automatic Mode - - This mode is the most commonly used. It is extremely well -suited for use in alias scripts and can make the whole process of -saving and restoring date stamps virtually transparent to the -user. The syntax is: - - ZSVSTAMP approg [ufn] - -where "approg" is the program, such as an editor, that you wish -to run and "ufn" is an unambiguous file name to be modified by -"approg." When a command of this type is given, ZSVSTAMP saves -"ufn"'s creation date in protected memory. It then causes -"approg" to be run, and when "approg" finishes, ZSVSTAMP is -automatically run again to restore the original create stamp to -"ufn." If "ufn" does not exist, or if the disk does not support -date stamping, ZSVSTAMP displays a warning message and -immediately passes control to "approg" without attempting to save -a stamp. In this situation, ZSVSTAMP is not rerun when "approg" -completes execution. - - Some editors allow a syntax such as - - EDIT oldfile newfile - -When ZSVSTAMP is invoked with more than one parameter following -the application name, no stamps are saved or restored. This -feature can be disabled if desired, (see the section on -customization). - - - -2.2 Manual Mode - - Manual mode can be used to save or restore a file's create -stamp. The syntax is: - - ZSVSTAMP ufn /G or /S - -to Get or Save a file's create stamp, or: - - ZSVSTAMP ufn /P or /R - -to Put or Restore a saved stamp back onto a file. - - - -3.0 CUSTOMIZING ZSVSTAMP - -There are five configuration flags located near the beginning of -the program. Each flag is preceeded by an ASCII string to help -identify its function. These flags may be patched to customize -ZSVSTAMP as desired. - - The first four flags determine whether or not various -warning messages can be displayed when ZSVSTAMP is being run in -Automatic Mode. Setting a flag to 0 disables its associated -message; any other value enables the message. The flags are -labeled "NOSTMP," "NOFILE," "READERR," and "UPDTERR," and they -affect the "Disk has no time/date stamps," "File not found," -"Can't read time/date stamp," and "Can't update time/date stamp" -messages respectively. The program is distributed with all four -messages enabled. Please note that these flags have no effect in -Manual Mode where error messages are always enabled. - - The fifth and final configuration flag is labeled -"REPLALWS." It determines what ZSVSTAMP will do when more than -one parameter follows the application name in an Automatic Mode -command. If the byte following the "REPLALWS" label equals 0, -ZSVSTAMP checks to see if there is more than one parameter -following the application program name. If there is, ZSVSTAMP -simply exits to the application without saving or updating any -stamps. (This is the default setting in the distributed -version.) If the "REPLALWS" flag is non-zero, no such check is -made. - - - -4.0 CONTACTING THE AUTHOR - - Howard Goldstein may be contacted at: - - Newton Centre Z-Node, (Z-Node 3): 617/965-7259 - - Ladera Z-Node, (Z-Node 2): 213/670-9465 - - Home phone, (voice): 203/787-1918 - \ No newline at end of file diff --git a/branches/s100/Support/ZSDOS/ZXD.CFG b/branches/s100/Support/ZSDOS/ZXD.CFG deleted file mode 100644 index f202ae59..00000000 Binary files a/branches/s100/Support/ZSDOS/ZXD.CFG and /dev/null differ diff --git a/branches/s100/Support/ZSDOS/ZXD.COM b/branches/s100/Support/ZSDOS/ZXD.COM deleted file mode 100644 index 20395673..00000000 Binary files a/branches/s100/Support/ZSDOS/ZXD.COM and /dev/null differ diff --git a/branches/s100/Support/vdu.rom b/branches/s100/Support/vdu.rom deleted file mode 100644 index 6452286c..00000000 Binary files a/branches/s100/Support/vdu.rom and /dev/null differ diff --git a/branches/s100/Tools/Win32 Disk Imager.exe b/branches/s100/Tools/Win32 Disk Imager.exe deleted file mode 100644 index bff00365..00000000 Binary files a/branches/s100/Tools/Win32 Disk Imager.exe and /dev/null differ diff --git a/branches/s100/Tools/altairz80.exe b/branches/s100/Tools/altairz80.exe deleted file mode 100644 index 5fbaaf41..00000000 Binary files a/branches/s100/Tools/altairz80.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/cpmchattr.exe b/branches/s100/Tools/cpmtools/cpmchattr.exe deleted file mode 100644 index 79d9d6d6..00000000 Binary files a/branches/s100/Tools/cpmtools/cpmchattr.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/cpmchmod.exe b/branches/s100/Tools/cpmtools/cpmchmod.exe deleted file mode 100644 index 8f657dca..00000000 Binary files a/branches/s100/Tools/cpmtools/cpmchmod.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/cpmcp.exe b/branches/s100/Tools/cpmtools/cpmcp.exe deleted file mode 100644 index 600e4529..00000000 Binary files a/branches/s100/Tools/cpmtools/cpmcp.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/cpmls.exe b/branches/s100/Tools/cpmtools/cpmls.exe deleted file mode 100644 index eeecf540..00000000 Binary files a/branches/s100/Tools/cpmtools/cpmls.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/cpmrm.exe b/branches/s100/Tools/cpmtools/cpmrm.exe deleted file mode 100644 index a61e7022..00000000 Binary files a/branches/s100/Tools/cpmtools/cpmrm.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/cygncurses-8.dll b/branches/s100/Tools/cpmtools/cygncurses-8.dll deleted file mode 100644 index 4a2c5328..00000000 Binary files a/branches/s100/Tools/cpmtools/cygncurses-8.dll and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/cygwin1.dll b/branches/s100/Tools/cpmtools/cygwin1.dll deleted file mode 100644 index 37e6d8da..00000000 Binary files a/branches/s100/Tools/cpmtools/cygwin1.dll and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/diskdefs b/branches/s100/Tools/cpmtools/diskdefs deleted file mode 100644 index 2e1f5725..00000000 --- a/branches/s100/Tools/cpmtools/diskdefs +++ /dev/null @@ -1,341 +0,0 @@ -diskdef ibm-3740 - seclen 128 - tracks 77 - sectrk 26 - blocksize 1024 - maxdir 64 - skew 6 - boottrk 2 - os p2dos -end - -diskdef 4mb-hd - seclen 128 - tracks 1024 - sectrk 32 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 0 - os p2dos -end - -diskdef pcw - seclen 512 - tracks 40 - sectrk 9 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 1 - os 3 -end - -diskdef pc1.2m - seclen 512 - tracks 80 - # this format uses 15 sectors per track, but 30 per cylinder - sectrk 30 - blocksize 4096 - maxdir 256 - skew 1 - boottrk 0 - os 3 -end - -# CP/M 86 on 1.44MB floppies -diskdef cpm86-144feat - seclen 512 - tracks 160 - sectrk 18 - blocksize 4096 - maxdir 256 - skew 1 - boottrk 2 - os 3 -end - -diskdef cf2dd - seclen 512 - tracks 160 - sectrk 9 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 1 - os 3 -end - -#amstrad: values are read from super block (special name hardcoded) - -# Royal alphatronic -# setfdprm /dev/fd1 dd ssize=256 cyl=40 sect=16 head=2 -diskdef alpha - seclen 256 - tracks 40 - sectrk 32 - blocksize 2048 - maxdir 128 - skew 1 - boottrk 2 - os 2.2 -end - -# Apple II CP/M skew o Apple II DOS 3.3 skew -diskdef apple-do - seclen 256 - tracks 35 - sectrk 16 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 3 - os 2.2 -end - -# Apple II CP/M skew o Apple II PRODOS skew -diskdef apple-po - seclen 256 - tracks 35 - sectrk 16 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 3 - os 2.2 -end - -# MYZ80 hard drive (only works with libdsk, because it has a 256-byte header) -diskdef myz80 - seclen 1024 - tracks 64 - sectrk 128 - blocksize 4096 - maxdir 1024 - skew 1 - boottrk 0 - os 3 -end - -# Despite being Amstrad formats, CPC System and CPC Data don't have an Amstrad -# superblock. You'll need to use libdsk to access them because the Linux -# and Windows kernel drivers won't touch them. -diskdef cpcsys - seclen 512 - tracks 40 - sectrk 9 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 2 - os 3 -end -diskdef cpcdata - seclen 512 - tracks 40 - sectrk 9 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 0 - os 3 -end - -# after being read in with no sector skew. -diskdef nigdos - seclen 512 - # NigDos double sided disk format, 42 tracks * 2 sides - tracks 84 - sectrk 10 - blocksize 2048 - maxdir 128 - skew 1 - boottrk 0 - # this format wastes half of the directory entry - logicalextents 1 - os 3 -end - -diskdef epsqx10 - seclen 512 - tracks 40 - sectrk 20 - blocksize 2048 - maxdir 128 - skew 0 - boottrk 2 - os 2.2 -end - -diskdef ibm-8ss - seclen 512 - tracks 40 - sectrk 8 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 1 - os 2.2 -end - -diskdef ibm-8ds - seclen 512 - tracks 40 - sectrk 8 - blocksize 1024 - maxdir 64 - skew 0 - boottrk 1 - os 2.2 -end - -diskdef electroglas - seclen 512 - tracks 80 - sectrk 10 - blocksize 2048 - maxdir 256 - skew 0 - boottrk 1 - os 3 -end - -# IBM CP/M-86 -# setfdprm /dev/fd1 sect=8 dtr=1 hd ssize=512 tpi=48 head=1 -diskdef ibmpc-514ss - seclen 512 - tracks 40 - sectrk 8 - blocksize 1024 - maxdir 64 - skew 1 - boottrk 1 - os 2.2 -end - -# IBM CP/M-86 -# setfdprm /dev/fd1 sect=8 dtr=1 hd ssize=512 tpi=48 -diskdef ibmpc-514ds - seclen 512 - tracks 80 - sectrk 8 - blocksize 2048 - maxdir 64 - skew 0 - boottrk 2 - os 2.2 -end - -diskdef p112 - seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 2 - os 3 -end - -diskdef p112-old - seclen 512 - tracks 160 - sectrk 18 - blocksize 2048 - maxdir 128 - skew 1 - boottrk 1 - os 3 -end - -diskdef kpii - seclen 512 - tracks 40 - sectrk 10 - blocksize 1024 - maxdir 32 - skew 0 - boottrk 1 - os 2.2 -end - -# setfdprm /dev/fd0 dd sect=10 -diskdef interak - seclen 512 - tracks 80 - sectrk 20 - blocksize 4096 - maxdir 256 - skew 1 - boottrk 2 - os 2.2 -end - -# For 512KB ROM, less 32K for system image -diskdef rom512KB - seclen 128 - tracks 14 - sectrk 256 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 0 - os 2.2 -end - -# For 1024KB ROM, less 32K for system image -diskdef rom1024KB - seclen 128 - tracks 30 - sectrk 256 - blocksize 2048 - maxdir 256 - skew 1 - boottrk 0 - os 2.2 -end - -# For N8VEM mass storage (4 raw partitions) -diskdef hd0 - seclen 512 - tracks 65 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 1 - os 2.2 -end - -diskdef hd1 - seclen 512 - tracks 130 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 66 - os 2.2 -end - -diskdef hd2 - seclen 512 - tracks 195 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 131 - os 2.2 -end - -diskdef hd3 - seclen 512 - tracks 260 - sectrk 256 - blocksize 4096 - maxdir 512 - skew 1 - boottrk 196 - os 2.2 -end diff --git a/branches/s100/Tools/cpmtools/docs/README.win32.cygwin.txt b/branches/s100/Tools/cpmtools/docs/README.win32.cygwin.txt deleted file mode 100644 index 868e1e8c..00000000 --- a/branches/s100/Tools/cpmtools/docs/README.win32.cygwin.txt +++ /dev/null @@ -1,518 +0,0 @@ -README.win32.cygwin.txt ------------------------ - -Building cpmtools-2.9 in Windows XP using: - -- cpmtools http://www.moria.de/~michael/cpmtools/ -- cygwin and the ncurses library - http://www.cygwin.com/ - -"The experts will always complain about shorter documents that do do not -provide enough details to confuse the rest of us, and longer documents that -do not omit enough details to confuse the rest of us. No documentation is -needed for people of that calibre." - -- Bill Buckels, November 2008 - -This document is provided in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. In particular, Bill Buckels has no warranty obligations -or liability resulting from its use in any way whatsoever. If you don't agree -then don't read it. - -Introduction ------------- - -This document is intended as a general guideline. An annotated summary is -provided directly below especially for expert users followed by annotated -details. - -Please review the other documentation and source code that comes with -cpmtools for more information about cpmtools. Please review the cygwin -documentation for more information about cygwin. - -At time of this writing, I have used the latest versions of the packages -listed above to build the latest version of cpmtools in its entirety. I have -documented the steps I followed below. - -Although there are probably other environments and compilers that can build -cpmtools for Windows I have not been successful in using the other several I -tried. Using a complete cygwin installation I had no problems and I had -cpmtools built in moments after I had cygwin installed and the cpmtools -source in place as documented below. - -Intended Audience ------------------ - -This document takes two tracks for installing cpmtools binary executables -after they have been built in cygwin: - -1. End users who will run cpmtools from within the cygwin shell. This -includes unix users who do not want to use the native Windows command line. - -2. End users who will run cpmtools from the native Windows command line. The -average Windows user does not have cygwin, and probably won't want to install -cygwin or learn a unix-like shell to use cpmtools. - -The consideration here is where cpmtools looks for its CP/M disk format -definitions file (diskdefs) when not in a unix-like environment like cygwin -and this consideration will affect the way you build cpmtools since this path -is hardcoded into the binary executables. - -My hope is that this document will help address the needs of both types of -Windows end users and those who wish to provide cpmtools to them. - -Summary -------- - -- Install cygwin with ncurses. -- Download cpmtools-2.9.tar.tar to your cygwin home directory. -- Start cygwin from the shortcut on the Windows desktop. - -- Enter the following commands: - -tar -xvf cpmtools.tar.tar -cd cpmtools-2.9 -./configure --with-diskdefs=/usr/local/share/diskdefs -make -mkdir /usr/local/share -mkdir /usr/local/share/man -mkdir /usr/local/share/man/man1 -mkdir /usr/local/share/man/man5 -make install - -Assumptions ------------ - -The above builds cpmtools under cygwin for end users who will use cpmtools in -the cygwin shell and who will use the default installation. - -I am assuming in this summary that all has gone well and that anyone who -deviates from what I have done or who has customized their cygwin -installation will be able to troubleshoot their own problems, - -I therefore make the following related assumptions in this summary: - -- That compiler related programs and libraries required to build cpmtools -under cygwin (including ncurses) are installed. - -- That you wish to download into and work under your home directory. You may -also consider whether a better place to download is in /usr/local/src and -whether you should install in the binaries in /opt/cpmtools/ and things of -that nature. - -Default Format --------------- - -You can change the default format to accomodate the special needs of your -users so they don't need to type their favorite format. The following line -can be entered to configure for an apple-do default format: - -./configure --with-defformat="apple-do" --with-diskdefs=/usr/local/share/diskdefs - -Native Windows Installation ---------------------------- - -If you wish to distribute your binaries to Windows end users who will not -have the cygwin shell and who will use the Windows command line, you have 2 -options: - -1. Require your users to always work in the same directory as diskdefs. - -- or - - -2. Hardcode the default diskdefs path into your binary executables and -require your users to always use the expected directory for diskdefs. - -The following line shows how to configure for an apple-do default format and -to set the default diskdefs path in a mannner that is acceptable to Windows -to a relative path from the root of the current drive: - -./configure --with-defformat="apple-do" --with-diskdefs=/cpmtools/diskdefs - -Cross-Cygwin Binary Installation --------------------------------- - -You can still use the binaries built as above and installed using "make -install" in cygwin if you add the following line to /etc/fstab (assuming your -cygdrive is the Windows C:drive): - -c:\cygwin\usr\local\share /cpmtools - -Making a Zip Installation for Native Windows Users --------------------------------------------------- - -If your target is the Windows user who does not have cygwin you can do the -following in cygwin in your build directory to create a zip file that will -contain the cpmtools binary executables: - -- mkdir cpmtools -- cp *.exe cpmtools/. -- cp diskdefs cpmtools/. -- cp /bin/cygwin1.dll cpmtools/. -- cp /bin/cygncurses-8.dll cpmtools/. -- zip -R cpmtools/*.* - -Making Documentation for Native Windows Users ---------------------------------------------- - -If you wish to provide the cpmtools manual pages in html format you can use -man2html to generate your html in ugly format and redirect to a file and edit -by hand. Here's an example: - -man2html -r cpm.5 > cpm.html - -If you wish to avoid html and provide the cpmtools manual pages in text -format you can use troff to generate your text in ugly format and redirect to -a file and edit by hand. Here's an example: - -troff -a cpm.5 > cpm.txt - -This concludes the summary. - -Details, Alternatives, and Other Fluff --------------------------------------- - -1.cygwin --------- - -Cygwin gave me a complete and free environment to both configure and build -cpmtools in its entirety. - -I installed cygwin from http://www.cygwin.com/ in its entirety which included -the ncurses library and when prompted to select a download site I chose -ftp://mirrors.kernel.org/sourceware/cygwin/ - -The site you pick will depend on your own preference and how much of cygwin -you decide to install will be up to you. I have a good Internet connection -and a large hard disk so installing ALL of cygwin was no problem for me. -Those who don't may wish to attempt an incremental installation which I -personally found to be annoying and tedious. - -It is not necessary to install ALL cygwin options. Another alternative is to -take the minimalistic approach and just install the compiler related -programs and libraries required to build cpmtools (including ncurses). If you -have missed something you will still be able to select additional components -via Cygwin Setup. - -By default cygwin installs into c:\cygwin and puts a shortcut on the Windows -desktop. By default the cygwin shell starts in your cygwin home directory -under c:\cygwin\home\. I used the cygwin default paths for my installation of -cygwin. - -2. cpmtoools ------------- - -I then downloaded Download cpmtools-2.9 from -http://www.moria.de/~michael/cpmtools/ -and used WinRAR to extract cpmtools-2.9 to -C:\cygwin\home\bbuckels\cpmtools-2.9\ - -I have noted in the summary that tar can be used. Use whatever you are -comfortable with to handle things from unix of a tarball nature. - -3. Building ------------ - -3.1. I started cygwin by clicking on the cygwin shortcut on my desktop which -placed me into my cygwin home directory in the cygwin shell. - -3.2 Now in the cygwin shell, I changed to the cpmtools directory by typing -the following and pressing the [Enter] key: - -cd cpmtools-2.9 - - -3.3 Running the configure script --------------------------------- - -Before making cpmtools, the configure script must be run to create the -cpmtools makefile and the config.h header file required by cpmtools. - -I ran the configure script with two options; to set the default format for -cpmtools to Apple II DOS 3.3 disk images and to tell cpmtools where to find -the diskdefs format definitions file (which is required to run cpmtools. See -far below.) - -3.3.2 Building for use in the cygwin shell ------------------------------------------- - -If I was building for use in the cygwin shell and I was using the default -paths used by "make install" noted far below, to be certain that my diskdefs -file would be found and to set my default format to "apple-do" I would type -the following and press the [Enter] key: - -./configure --with-defformat="apple-do" --with-diskdefs=/usr/local/share/diskdefs - -3.3.1 Building for the Native Windows command line ---------------------------------------------------- - -To set the default format to "apple-do" and to provide a relative path for -native Windows to my diskefs file which I would later copy to C:\cpmtools\ , -I typed the following and pressed the [Enter] key: - -./configure --with-defformat="apple-do" --with-diskdefs=/cpmtools/diskdefs - -Note: Windows paths are typed into the Windows native command line with -backslashes in the MS- DOS tradition. Historically the forward slash used by -unix as a path separator was used as a switch character in MS-DOS utilities -and this has carried forward with the commands that come with Windows. But in -a program, local Windows paths can be used with forward slashes instead and -they still work. Backslashes will cause problems for configure so use forward -slashes. - -3.4. The configure script created my cpmtools makefile and config.h with the -options I chose. I then ran make by typing the following and pressing the -[Enter] Key. - -make - -This concludes the first part of the details section of this document and I -have covered the basic steps that I followed to build cpmtools. What you do -will likely be a close variation. - -4. Installing -------------- - -4.1 Some of this is also noted in the summary. Also keep in mind that if -cpmtools is used outside of cygwin access to the documentation which is in -the form of unix-style man pages will not be available unless reformatted to -a media type that Windows users are familiar with. - -4.1.1 Installing for the cygwin shell ------------------------------------ - -You can review the summary and the cpmtools INSTALL document for more -information on unix-like installations. Installation of cpmtools for use in -the cygwin shell follows those conventions. - -If installing cpmtools to be used in cygwin using the cpmtools defaults and -assuming the directories below don't already exist, you will need to manually -create the following directories using the mkdir command as follows: - -mkdir /usr/local/share -mkdir /usr/local/share/man -mkdir /usr/local/share/man/man1 -mkdir /usr/local/share/man/man5 - -This is because the manual pages (man pages) will not be installed if you -don't. If you install the man pages, then when you need help on cpmtools in -cygwin, you can just enter "man cpmls" or "man cpmchmod", etc. - -After you make the directories above enter the following command: - -make install - -Assuming all has gone well, cpmtools is now part of your cygwin installation -and can be used wherever you work in cygwin. - -4.1.2 Installing for Use Outside Cygwin ---------------------------------------- - -Please also read the summary. - -The requirements of my installation were to create a directory structure for -a binary executable version of cpmtools targetted at Apple II disk image -users that would run at the native Windows cmd prompt. I offer the following -for general reference. The cygwin paths are based on my installation of -cygwin and are presented using conventional windows pathname notation. - -4.1.2.1 Dll's -------------- - -Two dll's from the c:\cygwin\bin\ directory were required: - -cygwin1.dll -cygncurses-8.dll - -Regardless of installation, for this cygwin and this ncurses version access -to these dll's will be required by this version of the cpmtools excecutables. - -4.2 Manually Placing Files for Use Outside Cygwin -------------------------------------------------- - -I did my installation by hand. - -My executables were created in c:\cygwin\home\bbuckels\cpmtools-2.9\ (my -cygwin home directory) which is also where the diskdefs file was. - -I used Windows Explorer to manually do the following: - -4.2.1 create c:\cpmtools\ directory. -4.2.2 copy all 8 exes into c:\cpmtools\ -4.2.3 copy both dll's listed above into c:\cpmtools\ -4.2.4 copy diskdefs into c:\cpmtools\ - -This gave me my directory structure and files for testing and distribution. - -I also placed an Apple II CP/M disk image called EXMPLCPM.dsk in c:\cpmtools\ -as a test target. - - -5. Additional Notes -------------------- - -5.1 diskdefs - CP/M disk format definitions --------------------------------------------- - -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available CP/M -formats and their names. For Apple II CP/M 80 users the disk image formats -apple-do and apple-po are available. - -The possible locations where cpmtools first looks for the diskdefs file: - -- Can vary depending on the preferences of the person who builds the cpmtools -binaries (executables) from the source code. - -- The location is also installation dependent and the diskdefs file may also -have been renamed (but we hope not). - -If it's not found the current (work) directory is then searched for a file -called diskdefs. - -On a unix-like system, a ${prefix}/share/ style path like /usr/local/share/ -is a possible place that cpmtools could be made to first look for diskdefs. - -In a Win32 system sometimes unix-like shells like cygwin are used to run -cpmtools instead of Windows cmd. For those installations unix-like -conventions probably should apply. - -For cpmtools installations targetted at the average Windows user who does not -have a unix-like shell and uses the Windows cmd prompt to run cpmtools there -is no standard shared place that cpmtools can be made to first look for -diskdefs. Pathed File names like \cpm\diskdefs or even c:\cpmtools\diskdefs -are possible. - -5.2 Difficulties in using the Windows File System ---------------------------------------------------- - -This is not a troubleshooting guide. Unless you wish to find-out for yourself -as I did just how many problems you can face with all of this, or you are -really an expert, please do yourself a favour and try to stay within what I -am suggesting as standard or alternative ways of building cpmtools. - -Missing libaries and compiler tools can be solved by trial and error and -reading the cygwin and cpmtools documentation. - -There are however some things about path names and file names that you need -to be aware of, some of which I have mentioned throughout this document and -some which I deliberately did not mention yet, like avoiding absolute paths -and drive letters. - -If you use a drive letter like C: when hardcoding a path to diskdefs you are -making several assumptions: - -First off, you are assuming that your build of cpmtools will only be run from -within Windows cmd shell on the local drive C:, (not from a bash-like shell -like cygwin which doesn't support drive letters the same way Windows cmd and -Windows itself does), and that diskdefs will not be on another drive, and -that drive C: exists in the first place, and that diskdefs is not on a -Windows network either unless drive C:,X:,Y:,Z:,etc is a mapped network -drive. It is questionable whether cpmtools build process for diskdefs pathing -supports UNC pathing anyway. I couldn't get \\ to work since the first slash -disappears in the configure script and the second slash becomes an escape -sequence for the next letter. - -Relative pathing will work and if you want to use conventions like -/cpmtools-2.9/diskedefs this will work. Environments like ${USERPROFILE} -aren't a good idea even if I could have got them to work since they are not -portable for several reasons and I will say no more on this except I -recommend that any path that you decide to use for diskdefs will only be -almost portable between shells if off the root directory and contains forward -slashes and no drive letters or colons. - -I hope what I have said proved less confusing to read than to write if you -have bothered to read it. If you are not confused yet read further. - -- Since cpmtools has special meanings for A: and B: as command line targets -it probably isn't a good idea to use these drives especially. - -- Some programmers and users have no difficulty in shifts between unix-like -and Windows pathing. Some will be familiar with how colons are used on -systems like Mac OSX. I think the only point to be made here is to consider -your target audience and all the things you can anticipate going wrong with -interoperability of all of this, (cpmtools being a set of command line -tools), and build cpmtools accordingly for the needs of you or your users, -then test what you have built with all this in mind. - -5.3 Testing your build of cpmtools ----------------------------------- - -To test what you have built I suggest you start with cpmls and cpmcp and an -apple disk image or equivalent. - -John Elliot said "If you have appropriate rights, the CPMTOOLS should be able -to access the floppy drive by using "A:" or "B:" as the name of the disc -image.". I say don't bother mucking with your physical disk drive unless you -have a physical CP/M disk of a format supported by cpmtools safely in the -drive. - -Get an apple CP/M disk image and use it for testing is what I suggest. The -following examples assume you have an Apple II DOS 3.3 order disk image -called EXMPLCPM.dsk for testing. - -To list the files: - -cpmls -f apple-do EXMPLCPM.dsk - -The following example shows how to copy a file from an Apple II DOS 3.3 order -cpm disk image to the current directory: - -cpmcp -f apple-do EXMPLCPM.dsk bhead.c 0:bhead.c - -The following example shows how to copy a file to an Apple II DOS 3.3 order -cpm disk image from the current directory: - -cpmcp -f apple-do EXMPLCPM.dsk 0:bhead.c bhead.c - -To test the other utilities in cpmtools like cpmrm, cpmchattr, cpmchmod, -fsck.cpm and fsed.cpm, review the appropriate manpages for usage. - -Those are simple tests as well using an apple-do format disk image. For -mkfs.cpm I will leave it to those more capable than I to decide what to do -there. Compared to them I am merely dangerous. - -Acknowledgements and Stuff --------------------------- - -Michael Haardt - for cpmtools in the first place and for his tireless and -ongoing efforts in supporting cpmtools in the second. - -John Elliot - for bringing cpmtools to Windows. - -My focus is on Windows XP (and other Windows) users and making this available -to them. At this point in time my focus is also on Apple II Z80 Softcard -users. Thankfully Michael Haardt has considered Apple II disk images in -cpmtools. My focus is also on the Aztec C Z80 MS-DOS cross-compiler which -creates Apple II CP/M programs in Windows XP. - -Between Michael and John, with cpmtools I can now easily get these onto an -Apple disk image and transfer the disk image over to my real Apple II which -has a Z80 softcard clone using my Microdrive with a CF card and make a real -CP/M disk from the image with DISKMAKER.8 or DSK2FILE then run my Aztec C -CP/M programs using the real thing. I can also use the emulator that came -with Apple II Oasis to run the disk image. - -Apparently nothing is missing from cpmtools for Windows XP that is available -on cpmtools for unix-like systems and I am thankful for that. Hopefully you -will be too. - -I would also like to acknowledge the following individuals from the -comp.os.cpm and apple2.sys usenet newsgroups who gave their experience, -thoughts and encouragement during my adventure with all of this and in no -particular order: - -David Schmidt - for cygwin feedback. -Udo Munk - for cygwin feedback. -Peter Dassow - for cygwin feedback. -Stevo Tarkin - for msys feedback. -Volker Pohlers - for msys and pdcurses feedback. -Rolf Harmann - for linux feedback. -Richard Brady - who may or may not know watfor:) - -If I missed anyone, I thank them too. I am somewhat new to some of this and -needed all the help I received. cygwin is now my friend. - -Bill Buckels -bbuckels@mts.net -November 2008 \ No newline at end of file diff --git a/branches/s100/Tools/cpmtools/docs/cpm.htm b/branches/s100/Tools/cpmtools/docs/cpm.htm deleted file mode 100644 index d4a165f6..00000000 --- a/branches/s100/Tools/cpmtools/docs/cpm.htm +++ /dev/null @@ -1,357 +0,0 @@ -CPM - CP/M disk and file system format - - - -

CPM

-Section: File formats (5)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- -  -NAME cpm - CP/M disk and file system format.

- -  -DESCRIPTION

- -  -Characteristic sizes - Each CP/M disk format is described by the following specific sizes: -
- -
- -Sector size in bytes -
- -Number of tracks -
- -Number of sectors -
- -Block size -
- -Number of directory entries -
- -Logical sector skew -
- -Number of reserved system tracks -

-
- -A block is the smallest allocatable storage unit. CP/M supports block -sizes of 1024, 2048, 4096, 8192 and 16384 bytes. Unfortunately, this -format specification is not stored on the disk and there are lots of -formats. Accessing a block is performed by accessing its sectors, which -are stored with the given software skew. -

- -  -Device areas - A CP/M disk contains three areas:
- -
- -System tracks (optional) -
- -Directory -
- -Data -

-
- -The system tracks store the boot loader and CP/M itself. In order to save -disk space, there are non-bootable formats which omit those system tracks. -The term disk capacity always excludes the space for system tracks. -Note that there is no bitmap or list for free blocks. When accessing a -drive for the first time, CP/M builds this bitmap in core from the directory. -

- -  -Directory entries - The directory is a sequence of directory entries (also called extents), -which contain 32 bytes of the following structure:
-
- -St F0 F1 F2 F3 F4 F5 F6 F7 E0 E1 E2 Xl Bc Xh Rc
-
- -Al   Al Al Al Al Al Al Al Al Al Al Al Al Al AlAl
-
-
- - -St is the status; possible values are:
-
- -0-15: used for file, status is the user number -
- -16-31: used for file, status is the user number (P2DOS) -or used for password extent (CP/M 3 or higher) -
- -32: disc label -
- -33: time stamp (P2DOS) -
- -0xE5: unused -

-
- -F0-E2 are the file name and its extension. They may consist of -any printable 7 bit ASCII character but: < > . , ; : = ? * [ ]. -The file name must not be empty, the extension may be empty. Both are -padded with blanks. The highest bit of each character of the file name -and extension is used as attribute. The attributes have the following -meaning:
- - -
-F0: requires set wheel byte (Backgrounder II) -
- -F1: public file (P2DOS, ZSDOS), forground-only command (Backgrounder II) -
- -F2: date stamp (ZSDOS), background-only commands (Backgrounder II) -
- -F7: wheel protect (ZSDOS) -
- -E0: read-only -
- -E1: system file -
- -E2: archived -

-
- -Public files (visible under each user number) are not supported by CP/M -2.2, but there is a patch and some free CP/M clones support them without -any patches. -

- -The wheel byte is (by default) the memory location at 0x4b. If it is -zero, only non-privileged commands may be executed. - -

- - -Xl and Xh store the extent number. A file may use more than -one directory entry, if it contains more blocks than an extent can hold. -In this case, more extents are allocated and each of them is numbered -sequentially with an extent number. If a physical extent stores more than -16k, it is considered to contain multiple logical extents, each pointing -to 16k data, and the extent number of the last used logical extent -is stored. Note: Some formats decided to always store only one logical -extent in a physical extent, thus wasting extent space. CP/M 2.2 allows -512 extents per file, CP/M 3 and higher allow up to 2048. Bit 5-7 of -Xl are 0, bit 0-4 store the lower bits of the extent number. Bit 6 -and 7 of Xh are 0, bit 0-5 store the higher bits of the extent number. - -

- - -Rc and Bc determine the length of the data used by this extent. The -physical extent is divided into logical extents, each of them being 16k -in size (a physical extent must hold at least one logical extent, e.g. a -blocksize of 1024 byte with two-byte block pointers is not allowed). -Rc stores the number of 128 byte records of the last used logical extent. -Bc stores the number of bytes in the last used record. The value 0 means -128 for backward compatibility with CP/M 2.2, which did not support Bc. - -

- - -Al stores block pointers. If the disk capacity is less than 256 blocks, -Al is interpreted as 16 byte-values, otherwise as 8 double-byte-values. -A block pointer of 0 marks a hole in the file. If a hole -covers the range of a full extent, the extent will not be allocated. In particular, -the first extent of a file does not neccessarily have extent number 0. -A file may not share blocks with other files, as its blocks would be freed -if the other files is erased without a following disk system reset. CP/M returns -EOF when it reaches a hole, whereas UNIX returns zero-value bytes, which makes -holes invisible. -

- -  -Time stamps - P2DOS and CP/M Plus support time stamps, which are stored in each fourth -directory entry. -

-This entry contains the time stamps for -the extents using the previous three directory entries. Note that you -really have time stamps for each extent, no matter if it is the first -extent of a file or not. The structure of time stamp entries is:
- -
- -1 byte status 0x21 -
- -8 bytes time stamp for third-last directory entry -
- -2 bytes unused -
- -8 bytes time stamp for second-last directory entry -
- -2 bytes unused -
- -8 bytes time stamp for last directory entry -

-
- -A time stamp consists of two dates: Creation and modification date (the -latter being recorded when the file is closed). CP/M Plus further -allows optionally to record the access instead of creation date as first -time stamp.
- -
-2 bytes (little-endian) days starting with 1 at 01-01-1978 -
- -1 byte hour in BCD format -
- -1 byte minute in BCD format -

-
- - -  -Disc labels - CP/M Plus supports disc labels, which are stored in an arbitrary directory -entry. -

-The structure of disc labels is:
- -
-1 byte status 0x20 -
- -F0-E2 are the disc label -
- -1 byte mode: bit 7 activates password protection, bit 6 causes time stamps on -access, but 5 causes time stamps on modifications, bit 4 causes time stamps on -creation and bit 0 is set when a label exists. Bit 4 and 6 are exclusively set. -
- -1 byte password decode byte: To decode the password, xor this byte with the password -bytes in reverse order. To encode a password, add its characters to get the -decode byte. -
- -2 reserved bytes -
- -8 password bytes -
- -4 bytes label creation time stamp -
- -4 bytes label modification time stamp -

-
- - -  -Passwords - CP/M Plus supports passwords, which are stored in an arbitrary directory entry. -

- -The structure of these entries is:
- -
- -1 byte status (user number plus 16) -
- -F0-E2 are the file name and its extension. -
- -1 byte password mode: bit 7 means password required for reading, bit 6 for writing -and bit 5 for deleting. -
- -1 byte password decode byte: To decode the password, xor this byte with the password -bytes in reverse order. To encode a password, add its characters to get the -decode byte. -
- -2 reserved bytes -
- -8 password bytes -

-
- - - -  -SEE ALSO

- -mkfs.cpm(1), - -fsck.cpm(1), - -fsed.cpm(1), - -cpmls(1) - - -

- -
- Index
-
-
NAME cpm - CP/M disk and file system format
-
DESCRIPTION
-
-
Characteristic sizes
-
Device areas
-
Directory entries
-
Time stamps
-
Disc labels
-
Passwords
-
-
SEE ALSO
-
-
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/docs/cpmchattr.htm b/branches/s100/Tools/cpmtools/docs/cpmchattr.htm deleted file mode 100644 index f1a98984..00000000 --- a/branches/s100/Tools/cpmtools/docs/cpmchattr.htm +++ /dev/null @@ -1,256 +0,0 @@ -CPMCHATTR - change file attributes on CP/M files - - -

CPMCHATTR

-Section: User commands (1)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- - -  -NAME cpmchattr - change file attributes on CP/M files.

- - -  -SYNOPSIS

- - -cpmchattr - -[-f - -format] - -image - -attrib - -file-pattern - -... - -

- -Note: Wildcards like *.com should be preceded with the user number -using a pattern like 0:*.com. -
-
- - -  -DESCRIPTION

- -Cpmchattr changes the file attributes for files on CP/M disks. -
-
- - -  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

-For Apple II CP/M 80 users the cpmchattr command may have no practical -effect. Try -cpmchmod instead for setting read only -attributes. -

- -
attrib Set the file attributes as given.
- -
-
- -  -FILE ATTRIBUTES - The file attribute string can contain the characters -1,2,3,4,s,a,N and M.

- -The meanings of these are: - -
-
1-4
- -
-The CP/M "user attributes" F1-F4. CP/M does not assign any -meaning to these attributes, though MP/M does. -
- -
s
- -
-The file is a system file. This attribute can also be set by -cpmchmod(1). - -
a
- -
-The file has been backed up. -
N
- -
-Reset all attributes to zero. So the string "N1r" resets all attributes and -then sets F1 and Read-Only. -
M
- -
-Attributes after an M are unset rather than set. The string "12M34" sets -atttributes F1 and F2, and unsets F3 and F4. -

-
- -  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system the -exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system the -exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available CP/M -formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-For Apple II CP/M 80 users the cpmchattr command may have no -practical effect. Try -cpmchmod instead for setting read only -attributes. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de> and -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- - -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- - -  -SEE ALSO

- -cmpls(1), - -cpmchmod(1), - -cpm(5) - -

- -
- - Index -
-
- -
-
NAME cpmchattr - change file attributes on CP/M files.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
FILE ATTRIBUTES
-
RETURN VALUE
-
ERRORS
-
FILES
-
-
AUTHORS
-
SEE ALSO
-
- -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- - diff --git a/branches/s100/Tools/cpmtools/docs/cpmchmod.htm b/branches/s100/Tools/cpmtools/docs/cpmchmod.htm deleted file mode 100644 index 72f1c48e..00000000 --- a/branches/s100/Tools/cpmtools/docs/cpmchmod.htm +++ /dev/null @@ -1,251 +0,0 @@ -CPMCHMOD - change file mode on CP/M files - - -

CPMCHMOD

-Section: User commands (1)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- -  -NAME cpmchmod - change file mode on CP/M files.

- -  -SYNOPSIS

- -cpmchmod - -[-f - -format] - -image - -mode - -file-pattern - -... - -

- -Note: Wildcards like *.com should be preceded with the user number -using a pattern like 0:*.com. -
-
- -  -DESCRIPTION

- -Cpmchmod changes the file mode for files on CP/M disks. -
-
- -  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

- - -
mode Octal file mode, as used in the unix command chmod.
- -
-Numeric (Octal) file mode: -
-
-From one to four octal digits. Any omitted digits are assumed to be leading zeros. -
-
-chmod Examples: -
-
-chmod 400 file - Read by owner
-chmod 040 file - Read by group
-chmod 004 file - Read by world -
-
-chmod 200 file - Write by owner
-chmod 020 file - Write by group
-chmod 002 file - Write by world -
-
-chmod 100 file - execute by owner
-chmod 010 file - execute by group
-chmod 001 file - execute by world -
-
-To combine these, just add the numbers together: -
-
-chmod 444 file - Allow read permission to owner and group and world
-chmod 777 file - Allow everyone to read, write, and execute file -
-
-
-cmpchmod Examples: -
-
-The following example shows how to change a file on an Apple II DOS 3.3 -order cpm disk image to read only: -
-
-cpmchmod -f apple-do exmplcpm.dsk 444 bhead.c -
-
-The following example shows how to change a file on an Apple II DOS 3.3 -order cpm disk image to read/write: -
-
-cpmchmod -f apple-do exmplcpm.dsk 666 bhead.c -
-
- -  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system the -exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system the -exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available CP/M -formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de> and -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- - -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- -  -SEE ALSO

- -cmpls(1), - -cpm(5) - -

- - -
- - Index -
-
- -
-
NAME cpmchmod - change file mode on CP/M files.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
RETURN VALUE
-
ERRORS
-
FILES
-
-
AUTHORS
-
SEE ALSO
-
- - -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- - diff --git a/branches/s100/Tools/cpmtools/docs/cpmcp.htm b/branches/s100/Tools/cpmtools/docs/cpmcp.htm deleted file mode 100644 index 9d9b676f..00000000 --- a/branches/s100/Tools/cpmtools/docs/cpmcp.htm +++ /dev/null @@ -1,290 +0,0 @@ -CPMCP - copy files from and to CP/M disks - - -

CPMCP

-Section: User commands (1)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- -  -NAME cpmcp - copy files from and to CP/M disks.

- - -  -SYNOPSIS

- -cpmcp - -[-f - -format] - -[-p] - -[-t] - -image - -user:file file -
-
- -cpmcp - -[-f - -format] - -[-p] - -[-t] - -image - -user:file ... directory -
-
- -cpmcp - -[-f - -format] - -[-p] - -[-t] - -image - -file user:file -
-
- -cpmcp - -[-f - -format] - -[-p] - -[-t] - -image - -file ... user: - -

- -  -DESCRIPTION

- -Cpmcp copies one or more files to or from a CP/M disk. -
-
- - -When copying multiple files, the last argument must be a drive or directory. -The drive letter does not matter because the device is specified by the -image, it is only used to specify which direction you want to copy. The user -number is specified after the drive letter, if omitted user 0 is used. -

- -You can use * and ? as "wildcards" in CP/M file names, -which have the same meaning in unix-like shells, and also on the MS-DOS -and Windows command lines for file name patterns. - -
-
- -  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

-For Apple II CP/M 80 -users the disk image formats apple-do and apple-po are available. These -are DOS3.3 order and ProDOS order disk image formats respectively, and must always be specified -using the form -f apple-do or -f apple-po. -

- -
-p
-Preserve time stamps when copying files from CP/M to UNIX (not -implemented for copying the other way so far). -
-
- - -
-t
-Convert text files between CP/M and UNIX conventions. -
- -
- -Examples: -
-
-The following example shows how to copy a file from an Apple II DOS 3.3 order cpm disk image -to the current directory: -
-
-cpmcp -f apple-do exmplcpm.dsk bhead.c 0:bhead.c -
-
-The following example shows how to copy a file to an Apple II DOS 3.3 order cpm disk image -from the current directory: -
-
-cpmcp -f apple-do exmplcpm.dsk 0:bhead.c bhead.c -
-
- -  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available -CP/M formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- - -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de>. -The Windows port is -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- - -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- -  -SEE ALSO

- -cmpls(1), - -cpm(5) - -

- -
- - Index -
-
- -
-
NAME cpmcp - copy files from and to CP/M disks.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
RETURN VALUE
-
ERRORS
-
FILES
-
-
AUTHORS
-
SEE ALSO
-
- -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/docs/cpmls.htm b/branches/s100/Tools/cpmtools/docs/cpmls.htm deleted file mode 100644 index 0617ea24..00000000 --- a/branches/s100/Tools/cpmtools/docs/cpmls.htm +++ /dev/null @@ -1,235 +0,0 @@ -CPMLS - list sorted contents of directory - - -

CPMLS

-Section: User commands (1)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- - -  -NAME cpmls - list sorted contents of directory

- -  -SYNOPSIS

- - -cpmls - -[-d|-D|-F|-A|-l[-c][-i]] - -[-f - -format] - -image - -[file-pattern...] -

- -  -DESCRIPTION

- -Cpmls lists the sorted contents of the directory. -
-
- -  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

-For Apple II CP/M 80 -users the disk image formats apple-do and apple-po are available. These -are DOS3.3 order and ProDOS order disk image formats respectively, and must always be specified -using the form -f apple-do or -f apple-po. -

- -
-d
-Old CP/M 2.2 dir output. -

- -
-D
-P2DOS 2.3 ddir-like output. -

- -
-F
-CP/M 3.x dir output. -

- -
-A
-E2fs lsattr-like output. -

- -
-l
-Long UNIX-style directory listing including size, time stamp and user number. -

- -
-c
-Output the creation time, not the modification time. -

- -
-i
-Print index number of each file. -
-
- -Example: -
-
-The following example shows how to list the files on an Apple II DOS 3.3 -order cpm disk image using a unix-like output: -
-
-cpmls -f apple-do -l exmplcpm.dsk -
-
- -  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system the -exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available -CP/M formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de>. -The Windows port is -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- - -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- -  -SEE ALSO

- -cpmcp(1), - -cpm(5) - -

- - -
- - Index -
-
- -
-
NAME cpmls - list sorted contents of directory.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
RETURN VALUE
-
ERRORS
-
FILES
-
-
AUTHORS
-
SEE ALSO
-
- -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/docs/cpmrm.htm b/branches/s100/Tools/cpmtools/docs/cpmrm.htm deleted file mode 100644 index 86bff425..00000000 --- a/branches/s100/Tools/cpmtools/docs/cpmrm.htm +++ /dev/null @@ -1,203 +0,0 @@ -CPMRM - remove files on CP/M disks - - -

CPMRM

-Section: User commands (1)
-Updated: June 16, 2008

- -
Index   -Return to Main Contents   -Disclaimer  


- - -  -NAME cpmrm - remove files on CP/M disks.

- -  -SYNOPSIS

- - -cpmrm - -[-f - -format] - -image - -file-pattern - -... -

- -  -DESCRIPTION

- -Cpmrm removes files from CP/M disks. -
-
- -  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

-For Apple II CP/M 80 -users the disk image formats apple-do and apple-po are available. These -are DOS3.3 order and ProDOS order disk image formats respectively, and must always be specified -using the form -f apple-do or -f apple-po. -
-
-
-Example: -
-
-The following example shows how to remove a file on an Apple II DOS 3.3 -order cpm disk image: -
-
-cpmrm -f apple-do exmplcpm.dsk 0:bhead.c -
-
-  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available -CP/M formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de>. -The Windows port is -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- - -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- -  -SEE ALSO

- -cpm(5) - -

- -
- - Index -
-
- -
-
NAME cpmrm - remove files on CP/M disks.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
RETURN VALUE
-
ERRORS
-
FILES
-
-
AUTHORS
-
SEE ALSO
-
- -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/docs/fsck.cpm.htm b/branches/s100/Tools/cpmtools/docs/fsck.cpm.htm deleted file mode 100644 index 32cf3075..00000000 --- a/branches/s100/Tools/cpmtools/docs/fsck.cpm.htm +++ /dev/null @@ -1,228 +0,0 @@ -FSCK.CPM - check a CP/M file system - - -

FSCK.CPM

-Section: User commands (1)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- - -  -NAME fsck.cpm - check a CP/M file system.

- -  -SYNOPSIS

- -fsck.cpm - -[-f - -format] - -[-n] - -image - -

- - -  -DESCRIPTION

- -Fsck.cpm is used to check and repair a CP/M file system. -
-
-After reading the directory, it makes two passes. The first pass checks -extent fields for range and format violations (bad status, extent number, -last record byte count, file name, extension, block number, record count, -size of .COM files, time stamp format, invalid password characters, invalid -time stamp mode). The second pass checks extent connectivity (multiple -allocated blocks and duplicate directory entries). -
-
-fsck.cpm can not yet repair all errors. -
-
- -  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

-For Apple II CP/M 80 -users the disk image formats apple-do and apple-po are available. These -are DOS3.3 order and ProDOS order disk image formats respectively, and must always be specified -using the form -f apple-do or -f apple-po. -

- - -
-n
-Open the file system read-only and do not repair any errors. -
-
-
- -  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available -CP/M formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- - -  -DIAGNOSTICS - image: used/total files (n.n% non-contiguos), used/total blocks -
-
-No inconsistencies could be found. The number of used files actually -is the number of used extents. Since a file may use more than -one extent, this may be greater than the actual number of files, but a -correct measure would not reflect how many files could still be created -at most. A file is considered fragmented, if sequential data blocks -pointed to by the same extent do not have sequential block numbers. -The number of used blocks includes the blocks used for system tracks -and the directory. -
-
- -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de>. -The Windows port is -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- - -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- -  -SEE ALSO

- -mkfs.cpm(1), - -cpm(5) - -

- -
- - Index -
-
- -
-
NAME fsck.cpm - check a CP/M file system.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
RETURN VALUE
-
ERRORS
-
FILES
-
DIAGNOSTICS
-
-
AUTHORS
-
SEE ALSO
-
- -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/docs/fsed.cpm.htm b/branches/s100/Tools/cpmtools/docs/fsed.cpm.htm deleted file mode 100644 index 2ea7a0ea..00000000 --- a/branches/s100/Tools/cpmtools/docs/fsed.cpm.htm +++ /dev/null @@ -1,202 +0,0 @@ -FSED.CPM - edit a CP/M file system - - -

FSED.CPM

-Section: User commands (1)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- - -  -NAME fsed.cpm - edit a CP/M file system.

- -  -SYNOPSIS

- -fsed.cpm - -[-f - -format] - -image - -
-
- - -  -DESCRIPTION

- -Fsed.cpm edits a CP/M file system on an image file or device. -
-
-It knows about the system, directory and data area, using sector skew on -the last two. Directory entries are decoded. The interactive usage is -self-explanatory, provided you are familiar with programming tools like -hexadecimal editors. If you are not then you should work with this program -and familiarize yourself with its usage. -
-
-  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

-For Apple II CP/M 80 -users the disk image formats apple-do and apple-po are available. These -are DOS3.3 order and ProDOS order disk image formats respectively, and must always be specified -using the form -f apple-do or -f apple-po. -

-
- -  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available -CP/M formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de>. -The Windows port is -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- -  -SEE ALSO

- -mkfs.cpm(1), - -mkfs.cpm(1), - -cpmls(1), - -cpm(5) - -

- -
- - Index -
-
- -
-
NAME fsed.cpm - edit a CP/M file system.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
RETURN VALUE
-
ERRORS
-
FILES
-
-
AUTHORS
-
SEE ALSO
-
- -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/docs/index.htm b/branches/s100/Tools/cpmtools/docs/index.htm deleted file mode 100644 index 5b257dda..00000000 --- a/branches/s100/Tools/cpmtools/docs/index.htm +++ /dev/null @@ -1,253 +0,0 @@ -Cpmtools 2.9 Executables for Windows Users - - - -

-

-Welcome to the Wonderfully Ancient World of CP/M
-Cpmtools 2.9 Executables for Windows Users
-
- - -
-Introduction -
-
- -Cpmtools is a suite of command line utilities which allow access to -CP/M file systems. It is available on many platforms. This document -is targetted at the use of the cpmtools Win32 executables at -the Windows command prompt by Windows users who know how to use -command line utilities and disk images -and who may not wish to create cpmtools executables from -source code... just to use them. - -
-
-Cpmtools is copyright 1997-2008 Michael Haardt <michael@moria.de> and -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -
-
-<< Back to Top -
-
-
-Licence -
-
-Cpmtools is free software; you can redistribute it and/or modify it -under the terms of -the GNU General Public License as -published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Cpmtools is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

-You should receive a copy of -the GNU General Public License along -with cpmtools. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-<< Back to Top -
-
-
-Downloads -
-
-The source for the latest version of cpmtools is available as -a GNU zipped tape archive from: -
-
- -http://www.moria.de/~michael/cpmtools/ - -
-
-The cpmtools source used in cygwin to build both the Windows binary (Executable) versions of -cpmtools 2.9 noted below is available from the -www.cpm8680.com Website in a zip file format: -
-
- -http://www.cpm8680.com/cpmtools/cpmtools-2.9.zip - -
-
-For Windows Users who do not wish to make working programs from source code, a compiled -Native Win32 Binary (Executable) version of cpmtools 2.9 is available from the -www.cpm8680.com Website in a zip file format: -
-
- -http://www.cpm8680.com/cpmtools/cpmtools-2.9-Win32.zip - -
-
-Just unzip with pathnames intact to the root of your local drive (usually C:) -and open-up a cmd prompt in the \cpmtools directory (Windows XP and Vista users -can click-on the cpmtools XP Shortcut) -and you should be good to go. The document you are reading and the program description documents -that it links to are included in the Windows zip file. To use them just click-on them from Windows explorer and -in the \cpmtools\docs directory and -they will load into your favorite web browser. -
-
- -The distribution noted above has the following customizations: -
-
-The default disk image format is apple-do. This means that if you are working -with Apple II DOS 3.3 order disk images you never need to include the -f apple-do -format option when typing in your command line. -
-
-The diskdefs file is called \cpmtools\diskdefs. This has been hardcoded -into the executables. This means that you can add the \cpmtools directory -to your PATH and the disk and disk image format definitions file will be found. -Users of earlier versions of Windows than XP that support Win32 will need to open a command -prompt and run \cpmtools\cpmtools.bat to set their PATH. -
-
-A Windows XP Shortcut has been added for Windows XP Users. This should -also work in Windows Vista. This means that Windows XP and Vista users can just -click on this shortcut in Windows Explorer or the Shortcut can be copied to -the desktop. -
-
-
-<< Back to Top -
-
-For cygwin Users who do not wish to make working programs from source code, a compiled -cygwin 5 Binary (Executable) version of cpmtools 2.9 is available from the -www.cpm8680.com Website in a zip file format: -
-
- -http://www.cpm8680.com/cpmtools/cpmtools-2.9-cygwin.zip - -
-
-Outside cygwin just unzip with pathnames intact to the root of the drive that the cygwin -version 5 directory is installed on (\cygwin is assumed). If you are doing this inside cygwin -using zip and cygwin is installed on C:, then cd \cygdrive\c before un-zipping. -
-
-The cygwin installation comes complete with the manpages but not the html manual. -It overlays your cygwin installation so review the zip before installing. -
-
- -The distribution noted above has the following customization: -
-
-The default disk image format is apple-do. This means that if you are working -with Apple II DOS 3.3 order disk images you never need to include the -f apple-do -format option when typing in your command line. -
-
-Other than that, it is what you would get if you built from scratch then installed -using "make install". If you wish to know more you should download -the source as well. -
-
-
-<< Back to Top -
-
-
-CP/M Resources -
-
-Aztec C CP/M compilers for -making programs in Windows, MS-DOS, and CP/M that will run in CP/M are available -from the Aztec C Museum Website for Fair Use and for -free by hobbyists and enthusiasts. These are no longer commercially available and are offered -with the permission of the Copyright holder. -
-
-The Aztec C Museum Website is only one of many free -CP/M resources on the Internet too numerous to mention that can be used in conjunction with -cpmtools. Some of these include: -
- -<< Back to Top -
-
-
-Caveat Emptor -
-
-This document was written and formatted by hand by Bill Buckels. Its -contents are either part of cpmtools or provide additional information about using cmptools. It is targetted primarily -at Windows users but most of it applies to all users of cpmtools. -
-
-It is provided in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. In particular, Bill Buckels has no warranty -obligations or liability resulting from its use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/docs/mkfs.cpm.htm b/branches/s100/Tools/cpmtools/docs/mkfs.cpm.htm deleted file mode 100644 index 35b2066c..00000000 --- a/branches/s100/Tools/cpmtools/docs/mkfs.cpm.htm +++ /dev/null @@ -1,215 +0,0 @@ -MKFS.CPM - make a CP/M file system - - -

MKFS.CPM

-Section: User commands (1)
-Updated: June 16, 2008

- -Index   -Return to Main Contents   -Disclaimer  


- -  -NAME mkfs.cpm - make a CP/M file system.

- -  -SYNOPSIS

- -mkfs.cpm - -[-f - -format] - -[-b - -boot] - -[-L - -label] - -image - -
-
- -  -DESCRIPTION

- -Mkfs.cpm makes a CP/M file system on an image file or device. -
-
- -  -OPTIONS

- -
- -
-f
- -Use the given CP/M disk format instead of the default format. -

-For Apple II CP/M 80 -users the disk image formats apple-do and apple-po are available. These -are DOS3.3 order and ProDOS order disk image formats respectively, and must always be specified -using the form -f apple-do or -f apple-po. -

- -
-b bootblock
- -
-Write the contents of the file bootblock to the system tracks -instead of filling them with 0xe5. This option can be used up to four -times. The file contents (typically boot block, CCP, BDOS and BIOS) -are written to sequential sectors, padding with 0xe5 if needed. -
-
- -
-L label
-
-Label the file system. This is only supported by CP/M Plus. -

-
- -  -RETURN VALUE - Upon successful completion, exit code 0 is returned.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -ERRORS - Any errors are indicated by exit code 1.

- -This will likely only be of interest to programmers. In a Win32 system -the exit code can be trapped in a batch file as an "ERRORLEVEL" or as a -return value when run from another Win32 console program written in a -language like C. -

- -  -FILES - diskdefs - CP/M disk format definitions

- -The diskdefs file is a plain ascii text file that serves as a database of -disk and disk image format definitions. It can be reviewed for available -CP/M formats and their names. For Apple II CP/M 80 users the disk -image formats apple-do and apple-po are available. -

-The possible locations where cpmtools first looks for the diskdefs file: -
-
-- Can vary depending on the preferences of the person who builds the -cpmtools binaries (executables) from the source code. -

-- The location is also installation dependent and the diskdefs file -may also have been renamed. -
-
-If it's not found the current (work) directory is then searched for a -file called diskdefs. -
-
-On a unix-like system, a ${prefix}/share/ style path -like /usr/local/share/ is a possible place that cpmtools will first -look for diskdefs. -
-
-In a Win32 system sometimes unix-like shells like cygwin -are used to run cpmtools instead of Windows cmd. For those installations -unix-like conventions probably apply. -
-
-For cpmtools installations targetted at the average -Windows user who does not have a unix-like shell and uses the Windows cmd -prompt to run cpmtools there is no standard shared place that cpmtools will first -look for diskdefs. Pathed File names like \cpm\diskdefs or -even c:\cpmtools\diskdefs are possible. -
-
- - -  -AUTHORS -
-
-This program is copyright 1997-2008 Michael Haardt <michael@moria.de>. -The Windows port is -copyright 2000, 2001 John Elliott <jce@seasip.demon.co.uk>. -

- - -This program is free software; you can redistribute it and/or modify -it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -

- -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -

- -You should have received a copy of the GNU General Public License along -with this program. If not, write to the Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -

- -  -SEE ALSO

- -cpmls(1), - -cpm(5) - -

- -
- - Index -
-
- -
-
NAME mkfs.cpm - make a CP/M file system.
-
SYNOPSIS
-
DESCRIPTION
-
-
OPTIONS
-
RETURN VALUE
-
ERRORS
-
FILES
-
-
AUTHORS
-
SEE ALSO
-
- -
-Gradus ad Parnassum -
-
-An ugly version of this document was initially created by man2html on November 14, 2008 -using the cpmtools version 2.8 manual pages -then edited and reformatted by hand by Bill Buckels. -
-
-Caveat Emptor -
-
-The contents of this document -are either part of cpmtools or provide additional information about using cmptools. -You can redistribute it under the terms of -the GNU General Public License as -published by the Free Software Foundation; either version 3 of the License, or (at your -option) any later version. -
-
-Bill Buckels has no warranty -obligations or liability resulting from this document's use in any way whatsoever. If you don't -agree then don't read it. -
- diff --git a/branches/s100/Tools/cpmtools/fsck.cpm.exe b/branches/s100/Tools/cpmtools/fsck.cpm.exe deleted file mode 100644 index 1fc22022..00000000 Binary files a/branches/s100/Tools/cpmtools/fsck.cpm.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/fsed.cpm.exe b/branches/s100/Tools/cpmtools/fsed.cpm.exe deleted file mode 100644 index 149a75e2..00000000 Binary files a/branches/s100/Tools/cpmtools/fsed.cpm.exe and /dev/null differ diff --git a/branches/s100/Tools/cpmtools/mkfs.cpm.exe b/branches/s100/Tools/cpmtools/mkfs.cpm.exe deleted file mode 100644 index eadcbd70..00000000 Binary files a/branches/s100/Tools/cpmtools/mkfs.cpm.exe and /dev/null differ diff --git a/branches/s100/Tools/gcc/libiconv-2.dll b/branches/s100/Tools/gcc/libiconv-2.dll deleted file mode 100644 index 049244df..00000000 Binary files a/branches/s100/Tools/gcc/libiconv-2.dll and /dev/null differ diff --git a/branches/s100/Tools/gcc/libintl-8.dll b/branches/s100/Tools/gcc/libintl-8.dll deleted file mode 100644 index c7e10441..00000000 Binary files a/branches/s100/Tools/gcc/libintl-8.dll and /dev/null differ diff --git a/branches/s100/Tools/gcc/mingw32-make.exe b/branches/s100/Tools/gcc/mingw32-make.exe deleted file mode 100644 index 0a5ce27b..00000000 Binary files a/branches/s100/Tools/gcc/mingw32-make.exe and /dev/null differ diff --git a/branches/s100/Tools/python/s100util.py b/branches/s100/Tools/python/s100util.py deleted file mode 100755 index 3cac8eb7..00000000 --- a/branches/s100/Tools/python/s100util.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python -import serial - -def memcmd(): - ser.flushInput() - str = "A" - ser.write(str) - print ser.read(1024) - -def menucmd(): - ser.flushInput() - str = "k" - ser.write(str) - print ser.read(1024) - -def portscmd(): - ser.flushInput() - str = "R" - ser.write(str) - print ser.read(1024) - -def dispcmd(beg,end): - ser.flushInput() - str = "D" + repr(beg) + " " + repr(end) + " " - ser.write(str) -# print ser.read(4096) - print ser.read( ((end+1-beg)/16*80)+100 ) - -def reset(): - ser.flushInput() - str = "GF000 " - ser.write(str) - print ser.read(256) - -def getpage(startaddr): - ser.flushInput() - str = "D" + repr(startaddr) + " " + repr(startaddr+255) + " " - print str - ser.write(str) - print ser.read(4096) - - -ser = serial.Serial('/dev/cu.PL2303-0000201D', 38400, timeout=2) -#reset() -#menucmd() -#portscmd() -#dispcmd(1000,1300) -#getpage(256) -#dispcmd(256,256+2) -#reset() -#getpage(0) -d1 = 100 -d2 = d1 + 255 -dispcmd(d1,d2) - - diff --git a/branches/s100/Tools/python/sendsave.py b/branches/s100/Tools/python/sendsave.py deleted file mode 100755 index 5ed2ab2d..00000000 --- a/branches/s100/Tools/python/sendsave.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/python - - -# Written by Douglas Goodall 17:25 Wed, Jan 30, 2013 - -import sys -import os -import serial - -filename = "rem.com" - -print "*******************************************************************" -print "sendsave.py 1/30/2013 dwg - deliver file to cp/m using save and ddt" -print "*******************************************************************" -# passing in a string either "12" or "0x12" -# return value is string of hex digits only (no 0x) -def safebyte(parm): - xyz = parm - myord = ord(xyz) - hexdata = hex(myord) - newstr = hexdata - if (hexdata[0] == '0'): - if(hexdata[1] == 'x'): - newstr = hexdata[2] - if(len(hexdata)>3): - newstr = newstr + hexdata[3] - return newstr - -# passing in a string either "1234" of "0x1234" -# return value is string of hex digits only (1234) (no 0x) -def safeword(parm): - xyz = parm - myint = int(xyz) - hexdata = hex(myint) - newstr = hexdata - if (hexdata[0] == '0'): - if(hexdata[1] == 'x'): - newstr = hexdata[2] - if(len(hexdata)>3): - newstr = newstr + hexdata[3] - if(len(hexdata)>4): - newstr = newstr + hexdata[4] - if(len(hexdata)>5): - newstr = newstr + hexdata[5] - return newstr - -statinfo = os.stat(filename) -filelen = statinfo.st_size - -beg = 0x100 -end = beg + filelen - 1 - -print "Target file is " + filename + " length is 0x" + hex(filelen) + "\n" - -infile = open(filename,'rb'); -data = infile.read() -infile.close() - -ser = serial.Serial('/dev/cu.PL2303-0000201D', 19200, timeout=1) - -# flush input queue -ser.read() - -ser.write("\n") -print ser.read(80) - -ser.write("save\n") -print ser.read(80) - -ser.write("ddt\n") -print ser.read(128) - -ser.write("s100\n") -print ser.read(20) - -for x in range(1,filelen): - ser.write(safebyte(data[x-1])) - ser.write("\n") - print ser.read(32) - -ser.write(".\n") -print ser.read(200) - -ser.write("g0\n") -print ser.read(160) - -ser.write(filename) -ser.write("\n") -print ser.read(128) - -ser.write("yes\n") -print ser.read(128) - -ser.write(safeword(beg)) -ser.write("\n") -print ser.read(128) - -ser.write(safeword(end)) -ser.write("\n") -print ser.read(128) - -ser.write("\n") -print ser.read(128) - diff --git a/branches/s100/Tools/rawwritewin/COPYING b/branches/s100/Tools/rawwritewin/COPYING deleted file mode 100644 index 5b6e7c66..00000000 --- a/branches/s100/Tools/rawwritewin/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/branches/s100/Tools/rawwritewin/changes.txt b/branches/s100/Tools/rawwritewin/changes.txt deleted file mode 100644 index c7c769eb..00000000 --- a/branches/s100/Tools/rawwritewin/changes.txt +++ /dev/null @@ -1,18 +0,0 @@ -Version 0.6 -Remove load time requirement for wininet.dll. -Add extra read to Win9X to settle floppy disk into the drive -Add absolute path to dll load to prevent conflict under ME -Packed the exe with UPX -Created auto install script - -Version 0.5 -Command line parameters -Better error messages -Autoupdate -Auto download missing dll - -Version 0.4 -Number of copies to write -NT does not always show floppy drives -Better error message when diskio.dll not found - diff --git a/branches/s100/Tools/rawwritewin/diskio.dll b/branches/s100/Tools/rawwritewin/diskio.dll deleted file mode 100644 index 1c6a7f0c..00000000 Binary files a/branches/s100/Tools/rawwritewin/diskio.dll and /dev/null differ diff --git a/branches/s100/Tools/rawwritewin/rawwritewin.exe b/branches/s100/Tools/rawwritewin/rawwritewin.exe deleted file mode 100644 index 822dfe19..00000000 Binary files a/branches/s100/Tools/rawwritewin/rawwritewin.exe and /dev/null differ diff --git a/branches/s100/Tools/rawwritewin/readme.txt b/branches/s100/Tools/rawwritewin/readme.txt deleted file mode 100644 index 42fad30c..00000000 --- a/branches/s100/Tools/rawwritewin/readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -RawWrite for Windows -==================== -95, 98, ME, NT, 2K, XP - -Under 95, 98 & ME you need diskio.dll. It must be in the same directory as rawwritewin.exe \ No newline at end of file diff --git a/branches/s100/Tools/tasm32/8051.H b/branches/s100/Tools/tasm32/8051.H deleted file mode 100644 index d5131ba9..00000000 --- a/branches/s100/Tools/tasm32/8051.H +++ /dev/null @@ -1,162 +0,0 @@ -;************************************************************* -;* TASM 8051/8052/80154 SFR BIT/BYTE MNEMONIC EQUATES LIST * -;************************************************************* - -P0 .equ 080H ;Port 0 -SP .equ 081H ;Stack pointer -DPL .equ 082H -DPH .equ 083H -PCON .equ 087H -TCON .equ 088H -TMOD .equ 089H -TL0 .equ 08AH -TL1 .equ 08BH -TH0 .equ 08CH -TH1 .equ 08DH -P1 .equ 090H ;Port 1 -SCON .equ 098H -SBUF .equ 099H -P2 .equ 0A0H ;Port 2 -IE .equ 0A8H -P3 .equ 0B0H ;Port 3 -IP .equ 0B8H -T2CON .equ 0C8H ;8052, 80154 only -RCAP2L .equ 0CAH ;8052, 80154 only -RCAP2H .equ 0CBH ;8052, 80154 only -TL2 .equ 0CCH ;8052, 80154 only -TH2 .equ 0CDH ;8052, 80154 only -PSW .equ 0D0H -ACC .equ 0E0H ;Accumulator -B .equ 0F0H ;Secondary Accumulator -IOCON .equ 0F8H ;80154 only - -;PORT 0 BITS -P0.0 .equ 080H ;Port 0 bit 0 -P0.1 .equ 081H ;Port 0 bit 1 -P0.2 .equ 082H ;Port 0 bit 2 -P0.3 .equ 083H ;Port 0 bit 3 -P0.4 .equ 084H ;Port 0 bit 4 -P0.5 .equ 085H ;Port 0 bit 5 -P0.6 .equ 086H ;Port 0 bit 6 -P0.7 .equ 087H ;Port 0 bit 7 - -;PORT 1 BITS -P1.0 .equ 090H ;Port 1 bit 0 -P1.1 .equ 091H ;Port 1 bit 1 -P1.2 .equ 092H ;Port 1 bit 2 -P1.3 .equ 093H ;Port 1 bit 3 -P1.4 .equ 094H ;Port 1 bit 4 -P1.5 .equ 095H ;Port 1 bit 5 -P1.6 .equ 096H ;Port 1 bit 6 -P1.7 .equ 097H ;Port 1 bit 7 - -;PORT 2 BITS -P2.0 .equ 0A0H ;Port 2 bit 0 -P2.1 .equ 0A1H ;Port 2 bit 1 -P2.2 .equ 0A2H ;Port 2 bit 2 -P2.3 .equ 0A3H ;Port 2 bit 3 -P2.4 .equ 0A4H ;Port 2 bit 4 -P2.5 .equ 0A5H ;Port 2 bit 5 -P2.6 .equ 0A6H ;Port 2 bit 6 -P2.7 .equ 0A7H ;Port 2 bit 7 - -;PORT 3 BITS -P3.0 .equ 0B0H ;Port 3 bit 0 -P3.1 .equ 0B1H ;Port 3 bit 1 -P3.2 .equ 0B2H ;Port 3 bit 2 -P3.3 .equ 0B3H ;Port 3 bit 3 -P3.4 .equ 0B4H ;Port 3 bit 4 -P3.5 .equ 0B5H ;Port 3 bit 5 -P3.6 .equ 0B6H ;Port 3 bit 6 -P3.7 .equ 0B7H ;Port 3 bit 7 - -;ACCUMULATOR BITS -ACC.0 .equ 0E0H ;Acc bit 0 -ACC.1 .equ 0E1H ;Acc bit 1 -ACC.2 .equ 0E2H ;Acc bit 2 -ACC.3 .equ 0E3H ;Acc bit 3 -ACC.4 .equ 0E4H ;Acc bit 4 -ACC.5 .equ 0E5H ;Acc bit 5 -ACC.6 .equ 0E6H ;Acc bit 6 -ACC.7 .equ 0E7H ;Acc bit 7 - -;B REGISTER BITS -B.0 .equ 0F0H ;Breg bit 0 -B.1 .equ 0F1H ;Breg bit 1 -B.2 .equ 0F2H ;Breg bit 2 -B.3 .equ 0F3H ;Breg bit 3 -B.4 .equ 0F4H ;Breg bit 4 -B.5 .equ 0F5H ;Breg bit 5 -B.6 .equ 0F6H ;Breg bit 6 -B.7 .equ 0F7H ;Breg bit 7 - -;PSW REGISTER BITS -P .equ 0D0H ;Parity flag -F1 .equ 0D1H ;User flag 1 -OV .equ 0D2H ;Overflow flag -RS0 .equ 0D3H ;Register bank select 1 -RS1 .equ 0D4H ;Register bank select 0 -F0 .equ 0D5H ;User flag 0 -AC .equ 0D6H ;Auxiliary carry flag -CY .equ 0D7H ;Carry flag - -;TCON REGISTER BITS -IT0 .equ 088H ;Intr 0 type control -IE0 .equ 089H ;Intr 0 edge flag -IT1 .equ 08AH ;Intr 1 type control -IE1 .equ 08BH ;Intr 1 edge flag -TR0 .equ 08CH ;Timer 0 run -TF0 .equ 08DH ;Timer 0 overflow -TR1 .equ 08EH ;Timer 1 run -TF1 .equ 08FH ;Timer 1 overflow - -;SCON REGISTER BITS -RI .equ 098H ;RX Intr flag -TI .equ 099H ;TX Intr flag -RB8 .equ 09AH ;RX 9th bit -TB8 .equ 09BH ;TX 9th bit -REN .equ 09CH ;Enable RX flag -SM2 .equ 09DH ;8/9 bit select flag -SM1 .equ 09EH ;Serial mode bit 1 -SM0 .equ 09FH ;Serial mode bit 0 - -;IE REGISTER BITS -EX0 .equ 0A8H ;External intr 0 -ET0 .equ 0A9H ;Timer 0 intr -EX1 .equ 0AAH ;External intr 1 -ET1 .equ 0ABH ;Timer 1 intr -ES .equ 0ACH ;Serial port intr -ET2 .equ 0ADH ;Timer 2 intr -;Reserved 0AEH Reserved -EA .equ 0AFH ;Global intr enable - -;IP REGISTER BITS -PX0 .equ 0B8H ;Priority level-External intr 0 -PT0 .equ 0B9H ;Priority level-Timer 0 intr -PX1 .equ 0BAH ;Priority level-External intr 1 -PT1 .equ 0BBH ;Priority level-Timer 1 intr -PS .equ 0BCH ;Priority level-Serial port intr -PT2 .equ 0BDH ;Priority level-Timer 2 intr -;Reserved 0BEH Reserved -PCT .equ 0BFH ;Global priority level - -;IOCON REGISTER BITS 80154 ONLY -ALF .equ 0F8H ;Power down port condition -P1HZ .equ 0F9H ;Port 1 control -P2HZ .equ 0FAH ;Port 2 control -P3HZ .equ 0FBH ;Port 3 control -IZC .equ 0FCH ;Pullup select -SERR .equ 0FDH ;Serial reception error -T32 .equ 0FEH ;32 bit timer config -WDT .equ 0FFH ;Watchdog config - -;T2CON REGISTER BITS 8052/80154 ONLY -CP/RL2 .equ 0C8H ;Timer 2 capture/reload flag -C/T2 .equ 0C9H ;Timer 2 timer/counter select -TR2 .equ 0CAH ;Timer 2 start/stop -EXEN2 .equ 0CBH ;Timer 2 external enable -TCLK .equ 0CCH ;TX clock flag -RCLK .equ 0CDH ;RX clock flag -EXF2 .equ 0CEH ;Timer 2 external flag -TF2 .equ 0CFH ;Timer 2 overflow - diff --git a/branches/s100/Tools/tasm32/COPYRIGH.TXT b/branches/s100/Tools/tasm32/COPYRIGH.TXT deleted file mode 100644 index cac66938..00000000 --- a/branches/s100/Tools/tasm32/COPYRIGH.TXT +++ /dev/null @@ -1,62 +0,0 @@ -The Telemark Assembler Copyright Notification - -The files on this disk are: -Copyright 1985-1993 by Speech Technology Incorporated, all rights reserved. -Copyright 1998,1999,2001 by Thomas N. Anderson , all rights reserved. - -The following files on this disk may be freely copied and shared with others: - -TASM.EXE - TASM Assembler, executable -TASM48.TAB - 8048 Instruction definition table -TASM51.TAB - 8051 Instruction definition table -TASM65.TAB - 6502 Instruction definition table -TASM85.TAB - 8085 Instruction definition table -TASM80.TAB - Z80 Instruction definition table -TASM05.TAB - 6805 Instruction definition table -TASM68.TAB - 6800/6801/68HC11 Instruction definition table -TASM3210.TAB - TMS32010 Instruction definition table -TASM3225.TAB - TMS32025 Instruction definition table -TASM70.TAB - TMS7000 Instruction definition table -TASMMAN.HTM - TASM Documentation (HTML) -TASMTABS.HTM - TASM Documentation on individual tables (HTML) -TEST*.ASM - TASM test cases (one for each table) -TESTTABS.BAT - Batch script to execute the test cases -8051.H - Useful register definitions for the 8051 -MOTO.H - Useful directive definitions for Motorola compatibility -README.TXT - Brief Explanation of Disk contents -COPYRIGH.TXT - Copyright notice -ORDERFRM.TXT - Registration Form -ORDERFRM.HTM - Registration Form (HTML) -RELNOTES.TXT - Release notes. - -Although you may freely copy the above files, TASM is not 'free' or -'public domain'. It is copyrighted material which can be copied and -evaluated by people without registration, but those that use it on a -regular basis must register (see the ORDERFRM.TXT or ORDERFRM.HTM files). - -The following files are to be copied only with the following -restrictions: The owner of this software may make as many copies of -the following as is deemed necessary as long as no possibility exists -for the software (or derivitive products) to be in use on more than -one machine at a time. Or, if a site license has been purchased, the -software can only be used on machines at that site. - - TASM.C - TASMMAIN.C - MACRO.C - PARSE.C - STR.C - LOOKUP.C - WRTOBJ.C - FNAME.C - WRTOBJ.C - ERRLOG.C - TASM.H - - - Thomas N. Anderson - Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - - email: andersontn@acm.org diff --git a/branches/s100/Tools/tasm32/MOTO.H b/branches/s100/Tools/tasm32/MOTO.H deleted file mode 100644 index 26e52282..00000000 --- a/branches/s100/Tools/tasm32/MOTO.H +++ /dev/null @@ -1,20 +0,0 @@ -; A few handy defines to make TASM more like typcial -; motorola syntax - -.MSFIRST ; Most Significant byte first - -#define EQU .EQU -#define ORG .ORG -#define RMB .BLOCK -#define FCB .BYTE -#define FCC .TEXT -#define FDB .WORD - -#define equ .EQU -#define org .ORG -#define rmb .BLOCK -#define fcb .BYTE -#define fcc .TEXT -#define fdb .WORD - - diff --git a/branches/s100/Tools/tasm32/ORDERFRM.HTM b/branches/s100/Tools/tasm32/ORDERFRM.HTM deleted file mode 100644 index 77af8f75..00000000 --- a/branches/s100/Tools/tasm32/ORDERFRM.HTM +++ /dev/null @@ -1,82 +0,0 @@ - - - -Telemark Cross Assembler (TASM) Order Form - -

TASM Order Form

-

To order TASM, print this page, fill in the details and mail to SVS at:

-

Squak Valley Software
837 Front Street South
Issaquah, WA 98027
USA

-

TASM registration provides the user:

-
    -
  • Most Recent TASM Distribution Disk (includes tables for all supported -processor families)
  • -
  • TASM Source code (in C)
  • -
  • Bound TASM Manual
  • -
  • Telephone Support
  • -
  • Knowledge that they are supporting the development of useful but -inexpensive software
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Item DescriptionUnit PriceAmount Extended
TASM 3.2 Registration $40______________________
TASM 3.2 Site Registration$90______________________
TASM 3.2 Update for registered users$10______________________
Subtotal______________________
Tax (Washington State residents add 8.6%)______________________
Billing Fee (for orders not accompanied by payment)$10______________________
Foreign postage and handling$10______________________
Total______________________
-
    -
  • All payments must be in US funds drawn on a US bank (No credit card -payments)
  • -
  • Orders outside North America please add the indicated foreign postage and -handling.
  • -
  • Purchase orders allowed from North America only (all others must be -prepaid).
-

Ship To:

- - - - - - - - - - - - - - - -
Name____________________________________
Company ___________________________________
Street Address____________________________________
City, State/Province, Postal Code____________________________________
Country ____________________________________
diff --git a/branches/s100/Tools/tasm32/ORDERFRM.TXT b/branches/s100/Tools/tasm32/ORDERFRM.TXT deleted file mode 100644 index d5282a5a..00000000 --- a/branches/s100/Tools/tasm32/ORDERFRM.TXT +++ /dev/null @@ -1,55 +0,0 @@ -ORDERING INFORMATION (TASM Version 3.2) - -TASM is distributed as shareware. The shareware portion of the -product may be freely copied and used for evaluation purposes. Use -of TASM beyond a reasonable evaluation period requires registration. -Registered users receive the following benefits: - - 1. The recent version of TASM. - 2. TASM source code (in C). - 3. Bound TASM manual. - 4. Telephone support. - 5. Knowledge that they are supporting the development of - useful but inexpensive software. - -DESCRIPTION UNIT PRICE PRICE --------------------------------------------------------------------- - -TASM Registration (TASM disk, manual, & source) $40.00 _______ - -TASM Site Registration (for sites with multiple 90.00 _______ - users. Includes same materials as above.) - -TASM User's Manual (included above) 10.00 _______ - -TASM update for registered users 10.00 _______ - (latest disk (with source), and manual) - -Subtotal _______ - -Tax (Washington state residents add 8.6%) _______ - -Billing fee (for orders not accompanied by check) 10.00 _______ - -Foreign postage (outside North America) add $10.00 _______ - (Foreign orders must be in US funds drawn on a US bank) - -TOTAL (post paid) _______ - - -Which processors are of primary interest to you? __________________ -(This is for our information only. You will -receive all current TASM tables). - -Shipping Address: - -______________________________________________ - -______________________________________________ - -______________________________________________ - -Send check or money order (no credit cards) to: Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - diff --git a/branches/s100/Tools/tasm32/README.1ST b/branches/s100/Tools/tasm32/README.1ST deleted file mode 100644 index 7bb8208e..00000000 --- a/branches/s100/Tools/tasm32/README.1ST +++ /dev/null @@ -1,18 +0,0 @@ -This is the registered distribution disk for TASM - the Telemark Assembler. -The files on the disk are: - -Readme.1st - This file -Tasm32.zip - TASM distribution archive, Version 3.2 - -To extract the archive use pkunzip or pkzip for windows and extract -into the desired directory for TASM. - -See the README.TXT file after extraction. -See the BUILD.TXT file for notes on building from the source archive. - - Thomas N. Anderson - Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - andersontn@acm.org - diff --git a/branches/s100/Tools/tasm32/README.TXT b/branches/s100/Tools/tasm32/README.TXT deleted file mode 100644 index 07555f5e..00000000 --- a/branches/s100/Tools/tasm32/README.TXT +++ /dev/null @@ -1,46 +0,0 @@ -This is the shareware distribution disk for TASM - a table driven -assembler. The files on the disk include: - -TASM.EXE - TASM Assembler, executable -TASM48.TAB - 8048 Instruction definition table -TASM51.TAB - 8051 Instruction definition table -TASM65.TAB - 6502 Instruction definition table -TASM85.TAB - 8085 Instruction definition table -TASM80.TAB - Z80 Instruction definition table -TASM05.TAB - 6805 Instruction definition table -TASM3210.TAB - TMS32010 Instruction definition table -TASM3225.TAB - TMS32025 Instruction definition table -TASM68.TAB - 6800/6801 Instruction definition table -TASM70.TAB - TMS7000 Instruction definition table -TASM96.TAB - 8096 Instruction definition table -TEST*.ASM - TASM test files (one for each table). -TESTTABS.BAT - Batch script to execute TASM for each test case. -8051.H - Useful register definitions for the 8051 -MOTO.H - Useful directive definitions for Motorola compatibility -TASMMAN.HTM - TASM User's Manual (HTML) -TASMTABS.HTM - TASM Table Description Manual (HTML) -README.TXT - Brief Explanation of Disk contents -COPYRIGH.TXT - Copyright notice -ORDERFRM.TXT - Order Form (plain text) -ORDERFRM.HTM - Order Form (HTML) - -For a brief discription of how to run TASM, execute TASM with no command -line parameters. - -If you find TASM useful, why not register? Unregistered use of TASM -beyond a 30 day evaluation period is a violation of the license. -For the $40.00 registration fee you get: - - 1. Latest version of TASM. - 2. Source code (in C). - 3. Bound Manual. - 4. email support. - -To register, use the form on the disk (ORDERFRM.TXT), or just send -$40.00 check or money order to: - - Thomas N. Anderson - Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - andersontn@acm.org diff --git a/branches/s100/Tools/tasm32/RELNOTES.TXT b/branches/s100/Tools/tasm32/RELNOTES.TXT deleted file mode 100644 index 24ae4f97..00000000 --- a/branches/s100/Tools/tasm32/RELNOTES.TXT +++ /dev/null @@ -1,213 +0,0 @@ -TASM RELEASE NOTES [September 2001] - -RELEASE DATE/VERSION DESCRIPTION ------------------------------------------------------------------------ -10/01/85 Version 2.0 First version with external table def files. - -01/01/86 Version 2.1 Added '*=' and '=' directives as - alternatives to .ORG and .EQU (for - more complete MOS Technology compatibility). - Enhanced parsing algorithm so it can - deal with more than one variable expression. - Added -d option - -02/14/86 Version 2.2 Modified so instruction set definition - tables don't need to be compiled in. - Added 8051 tables. - Increased the number of labels allowed. - -03/31/87 Version 2.3 Fixed bug that prevented location 0xffff - from being used and written to object file. - Most changes in wrtobj() and pr_hextab(). - -05/01/87 Version 2.4 Added multiple byte opcode support. - Added shift/or operation capability to - args from instruction set definition table. - Converted to MS C version 3.0 - Added hashing to instruction set table - lookups to speed up. - -11/01/87 Version 2.5 Added DB and DW directives. - Added escape capability in TEXT strings. - Fixed inst_lookup function to treat the - multiple wild card case a little better - Added 8080/8085 and Z80 tables. - Added sorting on label table. - Increased size of read buffer. - Speed enhancements. - Added DEFCONT (macro continuation) directive. - Converted to Microsoft C 5.0 compiler. - Added 6805 table (and related modops). - Added Z80 bit modop. - Minor speed up. - Fixed bug that enters infinite loop - when a macro invocation has no closing paren. - Added some three arg MODOPs. - -8/15/88 Version 2.6.1 Added CODES/NOCODES directives - Fixed bug preventing directives in multiple - statement lines. - 2.6.2 Added COMB_NIBBLE and COMB_NIBBLE_SWAP MODOPS - -2/1/89 Version 2.7 Removed ad hoc heap and now use malloc() - Added MSFIRST and LSFIRST directives. - Added EXPORT directive. - Added symbol table file (-s flag). - Added NSEG/CSEG/BSEG/DSEG/XSEG directives - and the SYM/AVSYM directives to support - the Avocet avsim51 simulator. - Added support for TMS320. - Added -r flag to set read buffer size. - Converted expression evaluation from - signed 16 bit to signed 32 bit (enabling - apparent ability to use signed or unsigned - 16 bit values). - -4/20/89 Version 2.7.1 Return 0x20000 for undefined labels so that - (label+x) type stuff won't confuse zero - page addressing. - Added duplicate label error message on pass 1. - -6/20/89 Version 2.7.2 Improved macro expansion capability. - No expansion in comments. - Context sensitive identifiers. - Revised exit codes. - -6/27/89 Version 2.7.3 Added -a flag for strict error checking: - (1) No outer parens around expressions. - (2) Error message if unused argbytes remain - (3) Duplicate labels - Fixed so ']' can terminate expressions. - Removed parse() from tasm.c - -8/19/89 Version 2.7.4 Added Motorola hex object format. - Fixed bug that complained when \ immediately - followed a opcode with no args. - Slightly improved error reporting (Errorbuf). - -10/31/89 Version 2.7.5 Added TMS7000 support. - Fixed argv[] bug (only dimensioned to 10 in pass1. - -12/23/89 Version 2.7.6 Improved handling of % (modulo vs binary - prefix ambiguity). - Fixed list so lines with more than - 6 bytes go on second line. - -03/04/90 Version 2.7.7 Fixed bug that left off 2 bytes if ORG - went backwards and all 64K was used. - Added a command line option to ignore - case on labels. - Added a couple MODOP rules for TMS9900. - Allow double quoted text strings for BYTE. - -04/15/90 Version 2.7.8 Fixed expression evaluator bug (paren popping) - and changed expression evaluator to a more - conventional left to right evaluation order. - Added TURBOC ifdef's (from Lance Jump). - -08/20/90 Version 2.8 Primarily a documentation update. - Added error check for AJMP/ACALL off of - current 2K block (8051). - -10/15/90 Version 2.8.1 Minor speed up in label searching. - Fixed word addressing for TMS320 - Version 2.8.2 Local labels. - More label table format options (long form - suppress local labels). - -11/30/90 Version 2.8.3 Turbo C conversion. - DS directive added. - -12/27/90 Version 2.8.4 Added COMMENTCHAR directive to change the - comment indicator in the first column. - This was done to support the assembly - files from the small C compiler (sc11) - for the 68CH11. - -02/14/91 Version 2.8.5 Added LOCALLABELCHAR directive to - override the default "_" as the - prefix for local labels. - -03/18/91 Version 2.8.6 Added some MODOPs in support of TMS320C25 - -04/20/91 Version 2.8.7 Fixed sign extend bug in CSWAP modop. - Increased MAXLABS to 10000 for big version. - -05/05/91 Version 2.8.8 Fixed pointer bug in debug output in sort_labels(). - -05/20/91 Version 2.9 TMS320C25 table along with some MODOP enhancements - for it. - TASMTABS.DOC updated (but not TASM.DOC) - -08/09/91 Version 2.9.1 Nested conditionals. - -04/01/92 Version 2.9.2 Fixed long label clobber problem in - find_label() and save_label. Syntax - errors could result in a comment line - after an instruction being lumped together - with a label resulting in a long label. - The label functions were not testing for - labels that exceed the specified size. - Added CHK directive. - Added REL3 MODOD to support uPD75xxx. - Delinting and more ANSIfication. - Modifications due to feedback from B Provo: - Added FILL directive. - Allow multiple labels for EXPORT directive. - Allow address with END directive. - TASM.DOC update - -11/25/92 Version 2.9.3 Improved error reporting for mismatched quotes. - Disallow the single quote character constants. - Convert to BCC++ 3.1 - Provide filename,linenum on all error messages. - Modify format of error messages for compatibility - with the Brief editor. - Added ECHO directive to send output to console. - Performance improvements in macro processing. - "Type Safe" conversion (compatible with C++). - Improved error reporting for imbalanced ifdefs. - - -01/29/93 Version 2.9.4 Added rules for 8096 (I1,I2,I3,I4,I5,I6). - Generate error message on forward reference - in EQUate statements. - Eliminated -a option for enabling the detection - of branches of 2K page for 8051. This - is now built into the table. - Allow white space in double quotes for BYTE - directive. This previously worked for TEXT, - but not BYTE. - Fixed defect with Z80 4 byte indexed instructions. - Fixed macro defect. If the macro definition has - args but the invocation does not some garbage - gets expanded into the source line. - Z80 OTDR opcode was incorrect. - Z80 IN0/OUT0/INA instructions did not require - the parens around the args. - Some experimental support for windows verson of TASM. - -10/24/93 Version 3.0 Documentation update. TASM.DOC, TASMTABS.DOC - and RELNOTES.DOC updated, but the functionality - remains unchanged from version 2.9.4. - -06/16/94 Version 3.0.1 Multiple macros on the same line. - Fixed problem with -c with >8000h bytes used goes bonkers - Corrected word addressing problem for BLOCK/DS directives. - Allow escaped quotes in TEXT strings. - -11/30/97 Version 3.1 LINUX support. - Protect mode version (tasmp) with better memory - management (more labels allowed, etc.) - Added an 8096 table. - Added Logical NOT unary operator. - Added an object file format with word address - -09/01/01 version 3.2 Increased LINESIZ to 512 to enable use of longer macros. - Eliminated -r command line option (to set - read buffer size - Now obsolete.) - Improved list() function to put a max of - six bytes per line to avoid problems with - directives that generate large blocks of - object code (i.e. .FILL). - Built as a 32 bit version using MS C++ 6.0 diff --git a/branches/s100/Tools/tasm32/TASM.EXE b/branches/s100/Tools/tasm32/TASM.EXE deleted file mode 100644 index f7c733cc..00000000 Binary files a/branches/s100/Tools/tasm32/TASM.EXE and /dev/null differ diff --git a/branches/s100/Tools/tasm32/TASM05.TAB b/branches/s100/Tools/tasm32/TASM05.TAB deleted file mode 100644 index 61e2972c..00000000 --- a/branches/s100/Tools/tasm32/TASM05.TAB +++ /dev/null @@ -1,215 +0,0 @@ -"TASM 6805 Assembler. " -/*************************************************************************** -/* $Id -/*************************************************************************** -/* This is the instruction set definition table for the 6805 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, April 1988. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC #* A9 2 NOP 1 -ADC ,X F9 1 NOP 1 -ADC *,X D9 3 MZERO 1 -ADC * C9 3 MZERO 1 - -ADD #* AB 2 NOP 1 -ADD ,X FB 1 NOP 1 -ADD *,X DB 3 MZERO 1 -ADD * CB 3 MZERO 1 - -AND #* A4 2 NOP 1 -AND ,X F4 1 NOP 1 -AND *,X D4 3 MZERO 1 -AND * C4 3 MZERO 1 - -ASLA "" 48 1 NOP 1 -ASLX "" 58 1 NOP 1 -ASL ,X 78 1 NOP 1 -ASL *,X 68 2 NOP 1 -ASL * 38 2 NOP 1 - -ASRA "" 47 1 NOP 1 -ASRX "" 57 1 NOP 1 -ASR ,X 77 1 NOP 1 -ASR *,X 67 2 NOP 1 -ASR * 37 2 NOP 1 - -BCC * 24 2 R1 1 -BCLR *,* 11 2 MBIT 1 -BCS * 25 2 R1 1 -BEQ * 27 2 R1 1 -BHCC * 28 2 R1 1 -BHCS * 29 2 R1 1 -BHI * 22 2 R1 1 -BHS * 24 2 R1 1 -BIH * 2F 2 R1 1 -BIL * 2E 2 R1 1 - -BIT #* A5 2 NOP 1 -BIT ,X F5 1 NOP 1 -BIT *,X D5 3 MZERO 1 -BIT * C5 3 MZERO 1 - -BLO * 25 2 R1 1 -BLS * 23 2 R1 1 -BMC * 2C 2 R1 1 -BMI * 2B 2 R1 1 -BMS * 2D 2 R1 1 -BNE * 26 2 R1 1 -BPL * 2A 2 R1 1 -BRA * 20 2 R1 1 - -BRCLR *,*,* 01 3 MBIT 1 -BRN * 21 2 R1 1 -BRSET *,*,* 00 3 MBIT 1 -BSET *,* 10 2 MBIT 1 -BSR * AD 2 R1 1 - -CLC "" 98 1 NOP 1 -CLI "" 9A 1 NOP 1 - -CLRA "" 4F 1 NOP 1 -CLRX "" 5F 1 NOP 1 -CLR ,X 7F 1 NOP 1 -CLR *,X 6F 2 NOP 1 -CLR * 3F 2 NOP 1 - -CMP #* A1 2 NOP 1 -CMP ,X F1 1 NOP 1 -CMP *,X D1 3 MZERO 1 -CMP * C1 3 MZERO 1 - -CMPX #* A3 2 NOP 1 /* equivalent to CPX */ -CMPX ,X F3 1 NOP 1 -CMPX *,X D3 3 MZERO 1 -CMPX * C3 3 MZERO 1 - -COMA "" 43 1 NOP 1 -COMX "" 53 1 NOP 1 -COM ,X 73 1 NOP 1 -COM *,X 63 2 NOP 1 -COM * 33 2 NOP 1 - -CPX #* A3 2 NOP 1 -CPX ,X F3 1 NOP 1 -CPX *,X D3 3 MZERO 1 -CPX * C3 3 MZERO 1 - -DECA "" 4A 1 NOP 1 -DECX "" 5A 1 NOP 1 -DEX "" 5A 1 NOP 1 -DEC ,X 7A 1 NOP 1 -DEC *,X 6A 2 NOP 1 -DEC * 3A 2 NOP 1 - -EOR #* A8 2 NOP 1 -EOR ,X F8 1 NOP 1 -EOR *,X D8 3 MZERO 1 -EOR * C8 3 MZERO 1 - -INCA "" 4C 1 NOP 1 -INCX "" 5C 1 NOP 1 -INX "" 5C 1 NOP 1 -INC ,X 7C 1 NOP 1 -INC *,X 6C 2 NOP 1 -INC * 3C 2 NOP 1 - -JMP ,X FC 1 NOP 1 -JMP *,X DC 3 MZERO 1 -JMP * CC 3 MZERO 1 - -JSR ,X FD 1 NOP 1 -JSR *,X DD 3 MZERO 1 -JSR * CD 3 MZERO 1 - -LDA #* A6 2 NOP 1 -LDA ,X F6 1 NOP 1 -LDA *,X D6 3 MZERO 1 -LDA * C6 3 MZERO 1 - -LDX #* AE 2 NOP 1 -LDX ,X FE 1 NOP 1 -LDX *,X DE 3 MZERO 1 -LDX * CE 3 MZERO 1 - -LSLA "" 48 1 NOP 1 -LSLX "" 58 1 NOP 1 -LSL ,X 78 1 NOP 1 -LSL *,X 68 2 NOP 1 -LSL * 38 2 NOP 1 - -LSRA "" 44 1 NOP 1 -LSRX "" 54 1 NOP 1 -LSR ,X 74 1 NOP 1 -LSR *,X 64 2 NOP 1 -LSR * 34 2 NOP 1 - -MUL "" 42 1 NOP 4 /* HC05C4 only */ - -NEGA "" 40 1 NOP 1 -NEGX "" 50 1 NOP 1 -NEG ,X 70 1 NOP 1 -NEG *,X 60 2 NOP 1 -NEG * 30 2 NOP 1 - -NOP "" 9D 1 NOP 1 - -ORA #* AA 2 NOP 1 -ORA ,X FA 1 NOP 1 -ORA *,X DA 3 MZERO 1 -ORA * CA 3 MZERO 1 - -ROLA "" 49 1 NOP 1 -ROLX "" 59 1 NOP 1 -ROL ,X 79 1 NOP 1 -ROL *,X 69 2 NOP 1 -ROL * 39 2 NOP 1 - -RORA "" 46 1 NOP 1 -RORX "" 56 1 NOP 1 -ROR ,X 76 1 NOP 1 -ROR *,X 66 2 NOP 1 -ROR * 36 2 NOP 1 - -RSP "" 9C 1 NOP 1 -RTI "" 80 1 NOP 1 -RTS "" 81 1 NOP 1 - -SBC #* A2 2 NOP 1 -SBC ,X F2 1 NOP 1 -SBC *,X D2 3 MZERO 1 -SBC * C2 3 MZERO 1 - -SEC "" 99 1 NOP 1 -SEI "" 9B 1 NOP 1 - -STA ,X F7 1 NOP 1 -STA *,X D7 3 MZERO 1 -STA * C7 3 MZERO 1 - -STOP "" 8E 1 NOP 2 /* M146805 CMOS only */ - -STX ,X FF 1 NOP 1 -STX *,X DF 3 MZERO 1 -STX * CF 3 MZERO 1 - -SUB #* A0 2 NOP 1 -SUB ,X F0 1 NOP 1 -SUB *,X D0 3 MZERO 1 -SUB * C0 3 MZERO 1 - -SWI "" 83 1 NOP 1 - -TAX "" 97 1 NOP 1 - -TSTA "" 4D 1 NOP 1 -TSTX "" 5D 1 NOP 1 -TST ,X 7D 1 NOP 1 -TST *,X 6D 2 NOP 1 -TST * 3D 2 NOP 1 - -TXA "" 9F 1 NOP 1 - -WAIT "" 8F 1 NOP 2 /* M146805 CMOS only */ - diff --git a/branches/s100/Tools/tasm32/TASM180.TAB b/branches/s100/Tools/tasm32/TASM180.TAB deleted file mode 100644 index 03affd9a..00000000 --- a/branches/s100/Tools/tasm32/TASM180.TAB +++ /dev/null @@ -1,594 +0,0 @@ -"TASM Z180 Assembler. " -/**************************************************************************** -/* $Id: tasm80.tab 1.2 1998/02/28 14:31:22 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the Z80 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Carl A. Wall, VE3APY. -/* -/* Class bits assigned as follows: -/* Bit-0 = Z80 (base instruction set) -/* Bit-1 = HD64180 (extended instructions) -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OP BYTES RULE CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC A,(HL) 8E 1 NOP 1 -ADC A,(IX*) 8EDD 3 ZIX 1 -ADC A,(IY*) 8EFD 3 ZIX 1 -ADC A,A 8F 1 NOP 1 -ADC A,B 88 1 NOP 1 -ADC A,C 89 1 NOP 1 -ADC A,D 8A 1 NOP 1 -ADC A,E 8B 1 NOP 1 -ADC A,H 8C 1 NOP 1 -ADC A,L 8D 1 NOP 1 -ADC A,* CE 2 NOP 1 -ADC HL,BC 4AED 2 NOP 1 -ADC HL,DE 5AED 2 NOP 1 -ADC HL,HL 6AED 2 NOP 1 -ADC HL,SP 7AED 2 NOP 1 - -ADD A,(HL) 86 1 NOP 1 -ADD A,(IX*) 86DD 3 ZIX 1 -ADD A,(IY*) 86FD 3 ZIX 1 -ADD A,A 87 1 NOP 1 -ADD A,B 80 1 NOP 1 -ADD A,C 81 1 NOP 1 -ADD A,D 82 1 NOP 1 -ADD A,E 83 1 NOP 1 -ADD A,H 84 1 NOP 1 -ADD A,L 85 1 NOP 1 -ADD A,* C6 2 NOP 1 -ADD HL,BC 09 1 NOP 1 -ADD HL,DE 19 1 NOP 1 -ADD HL,HL 29 1 NOP 1 -ADD HL,SP 39 1 NOP 1 -ADD IX,BC 09DD 2 NOP 1 -ADD IX,DE 19DD 2 NOP 1 -ADD IX,IX 29DD 2 NOP 1 -ADD IX,SP 39DD 2 NOP 1 -ADD IY,BC 09FD 2 NOP 1 -ADD IY,DE 19FD 2 NOP 1 -ADD IY,IY 29FD 2 NOP 1 -ADD IY,SP 39FD 2 NOP 1 - -AND (HL) A6 1 NOP 1 -AND (IX*) A6DD 3 ZIX 1 -AND (IY*) A6FD 3 ZIX 1 -AND A A7 1 NOP 1 -AND B A0 1 NOP 1 -AND C A1 1 NOP 1 -AND D A2 1 NOP 1 -AND E A3 1 NOP 1 -AND H A4 1 NOP 1 -AND L A5 1 NOP 1 -AND * E6 2 NOP 1 - -BIT *,(HL) 46CB 2 ZBIT 1 -BIT *,(IX*) CBDD 4 ZBIT 1 0 4600 -BIT *,(IY*) CBFD 4 ZBIT 1 0 4600 -BIT *,A 47CB 2 ZBIT 1 -BIT *,B 40CB 2 ZBIT 1 -BIT *,C 41CB 2 ZBIT 1 -BIT *,D 42CB 2 ZBIT 1 -BIT *,E 43CB 2 ZBIT 1 -BIT *,H 44CB 2 ZBIT 1 -BIT *,L 45CB 2 ZBIT 1 - -CALL C,* DC 3 NOP 1 -CALL M,* FC 3 NOP 1 -CALL NC,* D4 3 NOP 1 -CALL NZ,* C4 3 NOP 1 -CALL P,* F4 3 NOP 1 -CALL PE,* EC 3 NOP 1 -CALL PO,* E4 3 NOP 1 -CALL Z,* CC 3 NOP 1 -CALL * CD 3 NOP 1 - -CCF "" 3F 1 NOP 1 - -CP (HL) BE 1 NOP 1 -CP (IX*) BEDD 3 ZIX 1 -CP (IY*) BEFD 3 ZIX 1 -CP A BF 1 NOP 1 -CP B B8 1 NOP 1 -CP C B9 1 NOP 1 -CP D BA 1 NOP 1 -CP E BB 1 NOP 1 -CP H BC 1 NOP 1 -CP L BD 1 NOP 1 -CP * FE 2 NOP 1 -CPD "" A9ED 2 NOP 1 -CPDR "" B9ED 2 NOP 1 -CPIR "" B1ED 2 NOP 1 -CPI "" A1ED 2 NOP 1 -CPL "" 2F 1 NOP 1 - -DAA "" 27 1 NOP 1 - -DEC (HL) 35 1 NOP 1 -DEC (IX*) 35DD 3 ZIX 1 -DEC (IY*) 35FD 3 ZIX 1 -DEC A 3D 1 NOP 1 -DEC B 05 1 NOP 1 -DEC BC 0B 1 NOP 1 -DEC C 0D 1 NOP 1 -DEC D 15 1 NOP 1 -DEC DE 1B 1 NOP 1 -DEC E 1D 1 NOP 1 -DEC H 25 1 NOP 1 -DEC HL 2B 1 NOP 1 -DEC IX 2BDD 2 NOP 1 -DEC IY 2BFD 2 NOP 1 -DEC L 2D 1 NOP 1 -DEC SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -DJNZ * 10 2 R1 1 - -EI "" FB 1 NOP 1 -EX (SP),HL E3 1 NOP 1 -EX (SP),IX E3DD 2 NOP 1 -EX (SP),IY E3FD 2 NOP 1 -EX AF,AF' 08 1 NOP 1 -EX DE,HL EB 1 NOP 1 -EXX "" D9 1 NOP 1 -HALT "" 76 1 NOP 1 - -IM 0 46ED 2 NOP 1 -IM 1 56ED 2 NOP 1 -IM 2 5EED 2 NOP 1 - -/* Alternate form of above -IM0 46ED 2 NOP 1 -IM1 56ED 2 NOP 1 -IM2 5EED 2 NOP 1 - -IN A,(C) 78ED 2 NOP 1 -IN B,(C) 40ED 2 NOP 1 -IN C,(C) 48ED 2 NOP 1 -IN D,(C) 50ED 2 NOP 1 -IN E,(C) 58ED 2 NOP 1 -IN H,(C) 60ED 2 NOP 1 -IN L,(C) 68ED 2 NOP 1 - -IN A,(*) DB 2 NOP 1 - -IN0 A,(*) 38ED 3 NOP 1 -IN0 B,(*) 00ED 3 NOP 1 -IN0 C,(*) 08ED 3 NOP 1 -IN0 D,(*) 10ED 3 NOP 1 -IN0 E,(*) 18ED 3 NOP 1 -IN0 H,(*) 20ED 3 NOP 1 -IN0 L,(*) 28ED 3 NOP 1 - -INC (HL) 34 1 NOP 1 -INC (IX*) 34DD 3 ZIX 1 -INC (IY*) 34FD 3 ZIX 1 -INC A 3C 1 NOP 1 -INC B 04 1 NOP 1 -INC BC 03 1 NOP 1 -INC C 0C 1 NOP 1 -INC D 14 1 NOP 1 -INC DE 13 1 NOP 1 -INC E 1C 1 NOP 1 -INC H 24 1 NOP 1 -INC HL 23 1 NOP 1 -INC IX 23DD 2 NOP 1 -INC IY 23FD 2 NOP 1 -INC L 2C 1 NOP 1 -INC SP 33 1 NOP 1 - - -IND "" AAED 2 NOP 1 -INDR "" BAED 2 NOP 1 -INI "" A2ED 2 NOP 1 -INIR "" B2ED 2 NOP 1 - -JP (HL) E9 1 NOP 1 -JP (IX) E9DD 2 NOP 1 -JP (IY) E9FD 2 NOP 1 -JP C,* DA 3 NOP 1 -JP M,* FA 3 NOP 1 -JP NC,* D2 3 NOP 1 -JP NZ,* C2 3 NOP 1 -JP P,* F2 3 NOP 1 -JP PE,* EA 3 NOP 1 -JP PO,* E2 3 NOP 1 -JP Z,* CA 3 NOP 1 -JP * C3 3 NOP 1 - -JR C,* 38 2 R1 1 -JR NC,* 30 2 R1 1 -JR NZ,* 20 2 R1 1 -JR Z,* 28 2 R1 1 -JR * 18 2 R1 1 - -LD (BC),A 02 1 NOP 1 -LD (DE),A 12 1 NOP 1 -LD (HL),A 77 1 NOP 1 -LD (HL),B 70 1 NOP 1 -LD (HL),C 71 1 NOP 1 -LD (HL),D 72 1 NOP 1 -LD (HL),E 73 1 NOP 1 -LD (HL),H 74 1 NOP 1 -LD (HL),L 75 1 NOP 1 -LD (HL),* 36 2 NOP 1 -LD (IX*),A 77DD 3 ZIX 1 -LD (IX*),B 70DD 3 ZIX 1 -LD (IX*),C 71DD 3 ZIX 1 -LD (IX*),D 72DD 3 ZIX 1 -LD (IX*),E 73DD 3 ZIX 1 -LD (IX*),H 74DD 3 ZIX 1 -LD (IX*),L 75DD 3 ZIX 1 -LD (IX*),* 36DD 4 ZIX 1 -LD (IY*),A 77FD 3 ZIX 1 -LD (IY*),B 70FD 3 ZIX 1 -LD (IY*),C 71FD 3 ZIX 1 -LD (IY*),D 72FD 3 ZIX 1 -LD (IY*),E 73FD 3 ZIX 1 -LD (IY*),H 74FD 3 ZIX 1 -LD (IY*),L 75FD 3 ZIX 1 -LD (IY*),* 36FD 4 ZIX 1 -LD (*),A 32 3 NOP 1 -LD (*),BC 43ED 4 NOP 1 -LD (*),DE 53ED 4 NOP 1 -LD (*),HL 22 3 NOP 1 -LD (*),IX 22DD 4 NOP 1 -LD (*),IY 22FD 4 NOP 1 -LD (*),SP 73ED 4 NOP 1 -LD A,(BC) 0A 1 NOP 1 -LD A,(DE) 1A 1 NOP 1 -LD A,(HL) 7E 1 NOP 1 -LD A,(IX*) 7EDD 3 ZIX 1 -LD A,(IY*) 7EFD 3 ZIX 1 -LD A,A 7F 1 NOP 1 -LD A,B 78 1 NOP 1 -LD A,C 79 1 NOP 1 -LD A,D 7A 1 NOP 1 -LD A,E 7B 1 NOP 1 -LD A,H 7C 1 NOP 1 -LD A,I 57ED 2 NOP 1 -LD A,L 7D 1 NOP 1 -LD A,R 5FED 2 NOP 1 -LD A,(*) 3A 3 NOP 1 -LD A,* 3E 2 NOP 1 -LD B,(HL) 46 1 NOP 1 -LD B,(IX*) 46DD 3 ZIX 1 -LD B,(IY*) 46FD 3 ZIX 1 -LD B,A 47 1 NOP 1 -LD B,B 40 1 NOP 1 -LD B,C 41 1 NOP 1 -LD B,D 42 1 NOP 1 -LD B,E 43 1 NOP 1 -LD B,H 44 1 NOP 1 -LD B,L 45 1 NOP 1 -LD B,* 06 2 NOP 1 -LD BC,(*) 4BED 4 NOP 1 -LD BC,* 01 3 NOP 1 -LD C,(HL) 4E 1 NOP 1 -LD C,(IX*) 4EDD 3 ZIX 1 -LD C,(IY*) 4EFD 3 ZIX 1 -LD C,A 4F 1 NOP 1 -LD C,B 48 1 NOP 1 -LD C,C 49 1 NOP 1 -LD C,D 4A 1 NOP 1 -LD C,E 4B 1 NOP 1 -LD C,H 4C 1 NOP 1 -LD C,L 4D 1 NOP 1 -LD C,* 0E 2 NOP 1 -LD D,(HL) 56 1 NOP 1 -LD D,(IX*) 56DD 3 ZIX 1 -LD D,(IY*) 56FD 3 ZIX 1 -LD D,A 57 1 NOP 1 -LD D,B 50 1 NOP 1 -LD D,C 51 1 NOP 1 -LD D,D 52 1 NOP 1 -LD D,E 53 1 NOP 1 -LD D,H 54 1 NOP 1 -LD D,L 55 1 NOP 1 -LD D,* 16 2 NOP 1 -LD DE,(*) 5BED 4 NOP 1 -LD DE,* 11 3 NOP 1 -LD E,(HL) 5E 1 NOP 1 -LD E,(IX*) 5EDD 3 ZIX 1 -LD E,(IY*) 5EFD 3 ZIX 1 -LD E,A 5F 1 NOP 1 -LD E,B 58 1 NOP 1 -LD E,C 59 1 NOP 1 -LD E,D 5A 1 NOP 1 -LD E,E 5B 1 NOP 1 -LD E,H 5C 1 NOP 1 -LD E,L 5D 1 NOP 1 -LD E,* 1E 2 NOP 1 -LD H,(HL) 66 1 NOP 1 -LD H,(IX*) 66DD 3 ZIX 1 -LD H,(IY*) 66FD 3 ZIX 1 -LD H,A 67 1 NOP 1 -LD H,B 60 1 NOP 1 -LD H,C 61 1 NOP 1 -LD H,D 62 1 NOP 1 -LD H,E 63 1 NOP 1 -LD H,H 64 1 NOP 1 -LD H,L 65 1 NOP 1 -LD H,* 26 2 NOP 1 -LD HL,(*) 2A 3 NOP 1 -LD HL,* 21 3 NOP 1 -LD I,A 47ED 2 NOP 1 -LD IX,(*) 2ADD 4 NOP 1 -LD IX,* 21DD 4 NOP 1 -LD IY,(*) 2AFD 4 NOP 1 -LD IY,* 21FD 4 NOP 1 -LD L,(HL) 6E 1 NOP 1 -LD L,(IX*) 6EDD 3 ZIX 1 -LD L,(IY*) 6EFD 3 ZIX 1 -LD L,A 6F 1 NOP 1 -LD L,B 68 1 NOP 1 -LD L,C 69 1 NOP 1 -LD L,D 6A 1 NOP 1 -LD L,E 6B 1 NOP 1 -LD L,H 6C 1 NOP 1 -LD L,L 6D 1 NOP 1 -LD L,* 2E 2 NOP 1 -LD R,A 4FED 2 NOP 1 -LD SP,(*) 7BED 4 NOP 1 -LD SP,HL F9 1 NOP 1 -LD SP,IX F9DD 2 NOP 1 -LD SP,IY F9FD 2 NOP 1 -LD SP,* 31 3 NOP 1 -LDD "" A8ED 2 NOP 1 -LDDR "" B8ED 2 NOP 1 -LDI "" A0ED 2 NOP 1 -LDIR "" B0ED 2 NOP 1 -NEG "" 44ED 2 NOP 1 -NOP "" 00 1 NOP 1 - -MLT BC 4CED 2 NOP 1 -MLT DE 5CED 2 NOP 1 -MLT HL 6CED 2 NOP 1 -MLT SP 7CED 2 NOP 1 - -OR (HL) B6 1 NOP 1 -OR (IX*) B6DD 3 ZIX 1 -OR (IY*) B6FD 3 ZIX 1 -OR A B7 1 NOP 1 -OR B B0 1 NOP 1 -OR C B1 1 NOP 1 -OR D B2 1 NOP 1 -OR E B3 1 NOP 1 -OR H B4 1 NOP 1 -OR L B5 1 NOP 1 -OR * F6 2 NOP 1 - -OTDM "" 8BED 2 NOP 1 -OTDMR "" 9BED 2 NOP 1 -OTDR "" BBED 2 NOP 1 -OTIM "" 83ED 2 NOP 1 -OTIMR "" 93ED 2 NOP 1 -OTIR "" B3ED 2 NOP 1 - -OUT (C),A 79ED 2 NOP 1 -OUT (C),B 41ED 2 NOP 1 -OUT (C),C 49ED 2 NOP 1 -OUT (C),D 51ED 2 NOP 1 -OUT (C),E 59ED 2 NOP 1 -OUT (C),H 61ED 2 NOP 1 -OUT (C),L 69ED 2 NOP 1 -OUT (*),A D3 2 NOP 1 - -OUT0 (*),A 39ED 3 NOP 1 -OUT0 (*),B 01ED 3 NOP 1 -OUT0 (*),C 09ED 3 NOP 1 -OUT0 (*),D 11ED 3 NOP 1 -OUT0 (*),E 19ED 3 NOP 1 -OUT0 (*),H 21ED 3 NOP 1 -OUT0 (*),L 29ED 3 NOP 1 - -OUTD "" ABED 2 NOP 1 -OUTI "" A3ED 2 NOP 1 - -POP AF F1 1 NOP 1 -POP BC C1 1 NOP 1 -POP DE D1 1 NOP 1 -POP HL E1 1 NOP 1 -POP IX E1DD 2 NOP 1 -POP IY E1FD 2 NOP 1 - -PUSH AF F5 1 NOP 1 -PUSH BC C5 1 NOP 1 -PUSH DE D5 1 NOP 1 -PUSH HL E5 1 NOP 1 -PUSH IX E5DD 2 NOP 1 -PUSH IY E5FD 2 NOP 1 - -RES *,(HL) 86CB 2 ZBIT 1 -RES *,(IX*) CBDD 4 ZBIT 1 0 8600 -RES *,(IY*) CBFD 4 ZBIT 1 0 8600 -RES *,A 87CB 2 ZBIT 1 -RES *,B 80CB 2 ZBIT 1 -RES *,C 81CB 2 ZBIT 1 -RES *,D 82CB 2 ZBIT 1 -RES *,E 83CB 2 ZBIT 1 -RES *,H 84CB 2 ZBIT 1 -RES *,L 85CB 2 ZBIT 1 - -RET "" C9 1 NOP 1 -RET C D8 1 NOP 1 -RET M F8 1 NOP 1 -RET NC D0 1 NOP 1 -RET NZ C0 1 NOP 1 -RET P F0 1 NOP 1 -RET PE E8 1 NOP 1 -RET PO E0 1 NOP 1 -RET Z C8 1 NOP 1 -RETI "" 4DED 2 NOP 1 -RETN "" 45ED 2 NOP 1 - -RL (HL) 16CB 2 NOP 1 -RL (IX*) CBDD 4 ZIX 1 0 1600 -RL (IY*) CBFD 4 ZIX 1 0 1600 -RL A 17CB 2 NOP 1 -RL B 10CB 2 NOP 1 -RL C 11CB 2 NOP 1 -RL D 12CB 2 NOP 1 -RL E 13CB 2 NOP 1 -RL H 14CB 2 NOP 1 -RL L 15CB 2 NOP 1 -RLA "" 17 1 NOP 1 - -RLC (HL) 06CB 2 NOP 1 -RLC (IX*) CBDD 4 ZIX 1 0 0600 -RLC (IY*) CBFD 4 ZIX 1 0 0600 -RLC A 07CB 2 NOP 1 -RLC B 00CB 2 NOP 1 -RLC C 01CB 2 NOP 1 -RLC D 02CB 2 NOP 1 -RLC E 03CB 2 NOP 1 -RLC H 04CB 2 NOP 1 -RLC L 05CB 2 NOP 1 -RLCA "" 07 1 NOP 1 -RLD "" 6FED 2 NOP 1 - -RR (HL) 1ECB 2 NOP 1 -RR (IX*) CBDD 4 ZIX 1 0 1E00 -RR (IY*) CBFD 4 ZIX 1 0 1E00 -RR A 1FCB 2 NOP 1 -RR B 18CB 2 NOP 1 -RR C 19CB 2 NOP 1 -RR D 1ACB 2 NOP 1 -RR E 1BCB 2 NOP 1 -RR H 1CCB 2 NOP 1 -RR L 1DCB 2 NOP 1 -RRA "" 1F 1 NOP 1 -RRC (HL) 0ECB 2 NOP 1 -RRC (IX*) CBDD 4 ZIX 1 0 0E00 -RRC (IY*) CBFD 4 ZIX 1 0 0E00 -RRC A 0FCB 2 NOP 1 -RRC B 08CB 2 NOP 1 -RRC C 09CB 2 NOP 1 -RRC D 0ACB 2 NOP 1 -RRC E 0BCB 2 NOP 1 -RRC H 0CCB 2 NOP 1 -RRC L 0DCB 2 NOP 1 -RRCA "" 0F 1 NOP 1 -RRD "" 67ED 2 NOP 1 - -RST 00H C7 1 NOP 1 -RST 08H CF 1 NOP 1 -RST 10H D7 1 NOP 1 -RST 18H DF 1 NOP 1 -RST 20H E7 1 NOP 1 -RST 28H EF 1 NOP 1 -RST 30H F7 1 NOP 1 -RST 38H FF 1 NOP 1 - -/* Alternate form of above -RST 00 C7 1 NOP 1 -RST 08 CF 1 NOP 1 -RST 10 D7 1 NOP 1 -RST 18 DF 1 NOP 1 -RST 20 E7 1 NOP 1 -RST 28 EF 1 NOP 1 -RST 30 F7 1 NOP 1 -RST 38 FF 1 NOP 1 - -SBC A,(HL) 9E 1 NOP 1 -SBC A,(IX*) 9EDD 3 ZIX 1 -SBC A,(IY*) 9EFD 3 ZIX 1 -SBC A,A 9F 1 NOP 1 -SBC A,B 98 1 NOP 1 -SBC A,C 99 1 NOP 1 -SBC A,D 9A 1 NOP 1 -SBC A,E 9B 1 NOP 1 -SBC A,H 9C 1 NOP 1 -SBC A,L 9D 1 NOP 1 -SBC HL,BC 42ED 2 NOP 1 -SBC HL,DE 52ED 2 NOP 1 -SBC HL,HL 62ED 2 NOP 1 -SBC HL,SP 72ED 2 NOP 1 -SBC A,* DE 2 NOP 1 -SCF "" 37 1 NOP 1 - -SET *,(HL) C6CB 2 ZBIT 1 -SET *,(IX*) CBDD 4 ZBIT 1 0 C600 -SET *,(IY*) CBFD 4 ZBIT 1 0 C600 -SET *,A C7CB 2 ZBIT 1 -SET *,B C0CB 2 ZBIT 1 -SET *,C C1CB 2 ZBIT 1 -SET *,D C2CB 2 ZBIT 1 -SET *,E C3CB 2 ZBIT 1 -SET *,H C4CB 2 ZBIT 1 -SET *,L C5CB 2 ZBIT 1 - -SLA (HL) 26CB 2 NOP 1 -SLA (IX*) CBDD 4 ZIX 1 0 2600 -SLA (IY*) CBFD 4 ZIX 1 0 2600 -SLA A 27CB 2 NOP 1 -SLA B 20CB 2 NOP 1 -SLA C 21CB 2 NOP 1 -SLA D 22CB 2 NOP 1 -SLA E 23CB 2 NOP 1 -SLA H 24CB 2 NOP 1 -SLA L 25CB 2 NOP 1 - -SLP "" 76ED 2 NOP 1 - -SRA (HL) 2ECB 2 NOP 1 -SRA (IX*) CBDD 4 ZIX 1 0 2E00 -SRA (IY*) CBFD 4 ZIX 1 0 2E00 -SRA A 2FCB 2 NOP 1 -SRA B 28CB 2 NOP 1 -SRA C 29CB 2 NOP 1 -SRA D 2ACB 2 NOP 1 -SRA E 2BCB 2 NOP 1 -SRA H 2CCB 2 NOP 1 -SRA L 2DCB 2 NOP 1 - -SRL (HL) 3ECB 2 NOP 1 -SRL (IX*) CBDD 4 ZIX 1 0 3E00 -SRL (IY*) CBFD 4 ZIX 1 0 3E00 -SRL A 3FCB 2 NOP 1 -SRL B 38CB 2 NOP 1 -SRL C 39CB 2 NOP 1 -SRL D 3ACB 2 NOP 1 -SRL E 3BCB 2 NOP 1 -SRL H 3CCB 2 NOP 1 -SRL L 3DCB 2 NOP 1 - -SUB (HL) 96 1 NOP 1 -SUB (IX*) 96DD 3 ZIX 1 -SUB (IY*) 96FD 3 ZIX 1 -SUB A 97 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB * D6 2 NOP 1 - -TST A 3CED 2 NOP 1 -TST B 04ED 2 NOP 1 -TST C 0CED 2 NOP 1 -TST D 14ED 2 NOP 1 -TST E 1CED 2 NOP 1 -TST H 24ED 2 NOP 1 -TST L 2CED 2 NOP 1 -TST (HL) 34ED 2 NOP 1 -TST * 64ED 3 NOP 1 - -TSTIO * 74ED 3 NOP 1 - -XOR (HL) AE 1 NOP 1 -XOR (IX*) AEDD 3 ZIX 1 -XOR (IY*) AEFD 3 ZIX 1 -XOR A AF 1 NOP 1 -XOR B A8 1 NOP 1 -XOR C A9 1 NOP 1 -XOR D AA 1 NOP 1 -XOR E AB 1 NOP 1 -XOR H AC 1 NOP 1 -XOR L AD 1 NOP 1 -XOR * EE 2 NOP 1 diff --git a/branches/s100/Tools/tasm32/TASM3210.TAB b/branches/s100/Tools/tasm32/TASM3210.TAB deleted file mode 100644 index 88dbddd5..00000000 --- a/branches/s100/Tools/tasm32/TASM3210.TAB +++ /dev/null @@ -1,205 +0,0 @@ -"TASM TMS32010 Assembler." -/**************************************************************************** -/* $Id: tasm3210.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the TMS32010 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK */ -/*-------------------------------------------*/ - -/* Generate opcodes high byte first */ -.MSFIRST -/* Don't use '*' as the wild card since it is used for indirect addressing */ -/* In this table '@' is the wild card indicating where expression may appear*/ -.ALTWILD -/* Use word addressing (not byte addressing) -.WORDADDRS -/* All shift/and stuff applies to opcodes, not args -.NOARGSHIFT - -.REGSET *+ A0 1 -.REGSET *- 90 1 -.REGSET * 80 1 - -ABS "" 7F88 2 NOP 1 - -ADD !,@,@ 0000 2 T1 1 8 0F00 -ADD !,@ 0008 2 T1 1 8 0F00 -ADD ! 0008 2 NOP 1 -ADD @,@ 0000 2 TDMA 1 8 0F00 -ADD @ 0000 2 T1 1 0 007F - -ADDH !,@ 6000 2 T1 1 0 01 -ADDH ! 6008 2 NOP 1 -ADDH @ 6000 2 T1 1 0 007F - -ADDS !,@ 6100 2 T1 1 0 01 -ADDS ! 6108 2 NOP 1 -ADDS @ 6100 2 T1 1 0 007F - -AND !,@ 7900 2 T1 1 0 01 -AND ! 7908 2 NOP 1 -AND @ 7900 2 T1 1 0 7F - -APAC "" 7F8F 2 NOP 1 -B @ F900 4 SWAP 1 -BANZ @ F400 4 SWAP 1 -BGEZ @ FD00 4 SWAP 1 -BGZ @ FC00 4 SWAP 1 -BIOZ @ F600 4 SWAP 1 -BLEZ @ FB00 4 SWAP 1 -BLZ @ FA00 4 SWAP 1 -BNZ @ FE00 4 SWAP 1 -BV @ F500 4 SWAP 1 -BZ @ FF00 4 SWAP 1 -CALA "" 7F8C 2 NOP 1 -CALL @ F800 4 SWAP 1 -DINT "" 7F81 2 NOP 1 - -DMOV !,@ 6900 2 T1 1 0 01 -DMOV ! 6908 2 NOP 1 -DMOV @ 6900 2 T1 1 0 007F - -EINT "" 7F82 2 NOP 1 - -IN !,@,@ 4000 2 T1 1 8 0700 -IN !,@ 4008 2 T1 1 8 0700 -IN @,@ 4000 2 TDMA 1 8 0700 - -LAC !,@,@ 2000 2 T1 1 8 0F00 -LAC !,@ 2008 2 T1 1 8 0F00 -LAC ! 2008 2 NOP 1 -LAC @,@ 2000 2 TDMA 1 8 0F00 -LAC @ 2000 2 T1 1 0 007F - -LACK @ 7E00 2 T1 1 0 00FF - -LAR @,!,@ 3800 2 TAR 1 0 0001 -LAR @,! 3808 2 TAR 1 0 0001 -LAR @,@ 3800 2 TAR 1 0 007F - -LARK @,@ 7000 2 TAR 1 0 00FF -LARP @ 6880 2 T1 1 0 0001 - -LDP !,@ 6F00 2 T1 1 0 01 -LDP ! 6F08 2 NOP 1 -LDP @ 6F00 2 T1 1 0 007F - -LDPK @ 6E00 2 T1 1 0 01 - -LST !,@ 7B00 2 T1 1 0 01 -LST ! 7B08 2 NOP 1 -LST @ 7B00 2 T1 1 0 007F - -LT !,@ 6A00 2 T1 1 0 01 -LT ! 6A08 2 NOP 1 -LT @ 6A00 2 T1 1 0 007F - -LTA !,@ 6C00 2 T1 1 0 01 -LTA ! 6C08 2 NOP 1 -LTA @ 6C00 2 T1 1 0 007F - -LTD !,@ 6B00 2 T1 1 0 01 -LTD ! 6B08 2 NOP 1 -LTD @ 6B00 2 T1 1 0 007F - -MAR !,@ 6800 2 T1 1 0 01 -MAR ! 6808 2 NOP 1 -MAR @ 6800 2 T1 1 0 007F - -MPY !,@ 6D00 2 T1 1 0 01 -MPY ! 6D08 2 NOP 1 -MPY @ 6D00 2 T1 1 0 007F - -MPYK @ 8000 2 T1 1 0 1FFF - -NOP "" 7F80 2 NOP 1 - -OR !,@ 7A00 2 T1 1 0 01 -OR ! 7A08 2 NOP 1 -OR @ 7A00 2 T1 1 0 007F - -OUT !,@,@ 4800 2 T1 1 8 0700 -OUT !,@ 4808 2 T1 1 8 0700 -OUT @,@ 4800 2 TDMA 1 8 0700 - -PAC "" 7F8E 2 NOP 1 -POP "" 7F9D 2 NOP 1 -PUSH "" 7F9C 2 NOP 1 -RET "" 7F8D 2 NOP 1 -ROVM "" 7F8A 2 NOP 1 - -/* shift count for SACH can only be 0,1, or 4. The mask allows */ -/* 0,1,4, or 5. Let the user beware */ -SACH !,@,@ 5800 2 T1 1 8 0500 -SACH !,@ 5808 2 T1 1 8 0500 -SACH ! 5808 2 NOP 1 -SACH @,@ 5800 2 TDMA 1 8 0500 -SACH @ 5800 2 T1 1 0 007F - -/* The data book shows a shift field for SACL but states it must be 0. -/* The previous version of this table left the shift field out -/* for simplicity, but here I have put it back for compatibility. -/* The AND mask is set to zero in this case so a error message -/* will result from non-zero shifts. -SACL !,@,@ 5000 2 T1 1 8 0000 -SACL !,@ 5008 2 T1 1 8 0000 -SACL ! 5008 2 NOP 1 -SACL @,@ 5000 2 TDMA 1 8 0000 -SACL @ 5000 2 T1 1 0 007F - -SAR @,!,@ 3000 2 TAR 1 0 0001 -SAR @,! 3008 2 TAR 1 0 0001 -SAR @,@ 3000 2 TAR 1 0 007F - -SOVM "" 7F8B 2 NOP 1 -SPAC "" 7F90 2 NOP 1 - -SST !,@ 7C00 2 T1 1 0 0001 -SST ! 7C08 2 NOP 1 -SST @ 7C00 2 T1 1 0 007F - -SUB !,@,@ 1000 2 T1 1 8 0F00 -SUB !,@ 1008 2 T1 1 8 0F00 -SUB ! 1008 2 NOP 1 -SUB @,@ 1000 2 TDMA 1 8 0F00 -SUB @ 1000 2 T1 1 0 007F - -SUBC !,@ 6400 2 T1 1 0 01 -SUBC ! 6408 2 NOP 1 -SUBC @ 6400 2 T1 1 0 007F - -SUBH !,@ 6200 2 T1 1 0 01 -SUBH ! 6208 2 NOP 1 -SUBH @ 6200 2 T1 1 0 007F - -SUBS !,@ 6300 2 T1 1 0 01 -SUBS ! 6308 2 NOP 1 -SUBS @ 6300 2 T1 1 0 007F - -TBLR !,@ 6700 2 T1 1 0 01 -TBLR ! 6708 2 NOP 1 -TBLR @ 6700 2 T1 1 0 007F - -TBLW !,@ 7D00 2 T1 1 0 01 -TBLW ! 7D08 2 NOP 1 -TBLW @ 7D00 2 T1 1 0 007F - -XOR !,@ 7800 2 T1 1 0 01 -XOR ! 7808 2 NOP 1 -XOR @ 7800 2 T1 1 0 007F - -ZAC "" 7F89 2 NOP 1 - -ZALH !,@ 6500 2 T1 1 0 01 -ZALH ! 6508 2 NOP 1 -ZALH @ 6500 2 T1 1 0 007F - -ZALS !,@ 6600 2 T1 1 0 01 -ZALS ! 6608 2 NOP 1 -ZALS @ 6600 2 T1 1 0 007F - diff --git a/branches/s100/Tools/tasm32/TASM3225.TAB b/branches/s100/Tools/tasm32/TASM3225.TAB deleted file mode 100644 index 6535309a..00000000 --- a/branches/s100/Tools/tasm32/TASM3225.TAB +++ /dev/null @@ -1,456 +0,0 @@ -"TASM TMS32025 Assembler." -/**************************************************************************** -/* $Id: tasm3225.tab 1.2 1997/09/28 22:16:44 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the TMS32025 version of TASM. -/* Bob Stricklin -/* -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK */ -/*-------------------------------------------*/ - -/* Generate opcodes high byte first */ -.MSFIRST -/* Don't use '*' as the wild card since it is used for indirect addressing */ -/* In this table '@' is the wild card indicating where expression may appear*/ -.ALTWILD -.WORDADDRS -.NOARGSHIFT - -/* Addressing mode definitions. -/* Value gets OR'd in to the opcode if the -/* addressing mode is recognized -/* Note: no special classes are defined, so if this -/* table is used for TMS32020, invalid instructions -/* will not result in errors (no BR0+/- addressing mode (for example) -/* The ! character can match any of the patterns in the REGSET: -.REGSET *BR0+ F0 1 -.REGSET *BR0- C0 1 -.REGSET *0+ E0 1 -.REGSET *0- D0 1 -.REGSET *+ A0 1 -.REGSET *- 90 1 -.REGSET * 80 1 - - - - -ABS "" CE1B 2 NOP 1 - -ADD !,@,@ 0088 2 T1 1 8 0F00 -ADD !,@ 0080 2 T1 1 8 0F00 -ADD ! 0080 2 NOP 1 -ADD @,@ 0000 2 TDMA 1 8 0F00 -ADD @ 0000 2 T1 1 0 007F - -ADDC !,@ 4388 2 T1 1 0 0007 -ADDC ! 4380 2 NOP 1 -ADDC @ 4300 2 T1 1 0 007F - -ADDH !,@ 4888 2 T1 1 0 0007 -ADDH ! 4880 2 NOP 1 -ADDH @ 4800 2 T1 1 0 007F - -ADDK @ CC00 2 T1 1 0 00FF ;8 bit constant - -ADDS !,@ 4988 2 T1 1 0 0007 -ADDS ! 4980 2 NOP 1 -ADDS @ 4900 2 T1 1 0 007F - -ADDT !,@ 4A88 2 T1 1 0 0007 -ADDT ! 4A80 2 NOP 1 -ADDT @ 4A00 2 T1 1 0 007F - -ADLK @,@ D002 4 TLK 1 8 0F00 -ADLK @ D002 4 TLK 1 - -ADRK @ 7E00 2 T1 1 0 00FF ;8 bit constant - -AND !,@ 4E88 2 T1 1 0 0007 -AND ! 4E80 2 NOP 1 -AND @ 4E00 2 T1 1 0 007F - -ANDK @,@ D004 4 TLK 1 8 0F00 -ANDK @ D004 4 TLK 1 - -APAC "" CE15 2 NOP 1 - -B @,!,@ FF88 4 TLK 1 0 07 -B @,! FF80 4 SWAP 1 -B @ FF80 4 SWAP 1 - -BACC "" CE25 2 NOP 1 - -BANZ @,!,@ FB88 4 TLK 1 0 07 -BANZ @,! FB80 4 SWAP 1 -BANZ @ FB90 4 SWAP 1 ; Default to the equivalent of - ; BANZ loop,*- (as per spec) for - ; TMS32010 compatibility. - -BBNZ @,!,@ F988 4 TLK 1 0 07 -BBNZ @,! F980 4 SWAP 1 -BBNZ @ F980 4 SWAP 1 - -BBZ @,!,@ F888 4 TLK 1 0 07 -BBZ @,! F880 4 SWAP 1 -BBZ @ F880 4 SWAP 1 - -BC @,!,@ 5E88 4 TLK 1 0 07 -BC @,! 5E80 4 SWAP 1 -BC @ 5E80 4 SWAP 1 - -BGEZ @,!,@ F488 4 TLK 1 0 07 -BGEZ @,! F480 4 SWAP 1 -BGEZ @ F480 4 SWAP 1 - -BGZ @,!,@ F188 4 TLK 1 0 07 -BGZ @,! F180 4 SWAP 1 -BGZ @ F180 4 SWAP 1 - -BIOZ @,!,@ FA88 4 TLK 1 0 07 -BIOZ @,! FA80 4 SWAP 1 -BIOZ @ FA80 4 SWAP 1 - -BIT !,@,@ 9088 2 T1 1 8 0F00 ;8 bit shift -BIT !,@ 9080 2 T1 1 8 0F00 -BIT @,@ 9000 2 TDMA 1 8 0F00 - -BITT !,@ 5788 2 T1 1 0 07 -BITT ! 5780 2 T1 1 -BITT @ 5700 2 T1 1 0 7F - -BLEZ @,!,@ F288 4 TLK 1 0 07 -BLEZ @,! F280 4 SWAP 1 -BLEZ @ F280 4 SWAP 1 - -BLKD @,!,@ FD88 4 TLK 1 0 07 -BLKD @,! FD80 4 TLK 1 0 07 -BLKD @,@ FD00 4 TLK 1 0 FF - -BLKP @,!,@ FC88 4 TLK 1 0 07 -BLKP @,! FC80 4 TLK 1 0 07 -BLKP @,@ FC00 4 TLK 1 0 FF - -BLZ @,!,@ F388 4 TLK 1 0 07 -BLZ @,! F380 4 SWAP 1 -BLZ @ F380 4 SWAP 1 - -BNC @,!,@ 5F88 4 TLK 1 0 07 -BNC @,! 5F80 4 SWAP 1 -BNC @ 5F80 4 SWAP 1 - -BNV @,!,@ F788 4 TLK 1 0 07 -BNV @,! F780 4 SWAP 1 -BNV @ F780 4 SWAP 1 - -BNZ @,!,@ F588 4 TLK 1 0 07 -BNZ @,! F580 4 SWAP 1 -BNZ @ F580 4 SWAP 1 - -BV @,!,@ F088 4 TLK 1 0 07 -BV @,! F080 4 SWAP 1 -BV @ F080 4 SWAP 1 - -BZ @,!,@ F688 4 TLK 1 0 07 -BZ @,! F680 4 SWAP 1 -BZ @ F680 4 SWAP 1 - -CALA "" CE24 2 NOP 1 - -CALL @,!,@ FE88 4 TLK 1 0 07 -CALL @,! FE80 4 SWAP 1 -CALL @ FE80 4 SWAP 1 - -CMPL "" CE27 2 NOP 1 - -CMPR @ CE50 2 T1 1 0 03 ;2 BIT CONTANT - -CNFD "" CE04 2 NOP 1 - -CNFP "" CE05 2 NOP 1 - -CONF "" CE3C 2 T1 4 0 03 ; c26 ONLY - -DINT "" CE01 2 NOP 1 - -DMOV !,@ 5688 2 T1 1 0 07 -DMOV ! 5680 2 NOP 1 -DMOV @ 5600 2 T1 1 0 007F - -EINT "" CE00 2 NOP 1 - -FORT @ CE0E 2 T1 1 0 01 - -IDLE "" CE1F 2 NOP 1 - -IN !,@,@ 8088 2 T1 1 8 0F00 -IN !,@ 8080 2 T1 1 8 0F00 -IN @,@ 8000 2 TDMA 1 8 0F00 - -LAC !,@,@ 2088 2 T1 1 8 0F00 -LAC !,@ 2080 2 T1 1 8 0F00 -LAC ! 2080 2 NOP 1 -LAC @,@ 2000 2 TDMA 1 8 0F00 -LAC @ 2000 2 T1 1 0 007F - -LACK @ CA00 2 T1 1 0 00FF ;tested for -25 - -LACT !,@ 4288 2 T1 1 0 07 -LACT ! 4280 2 NOP 1 -LACT @ 4200 2 T1 1 0 007F - -LALK @,@ D001 4 TLK 1 8 0F00 -LALK @ D001 4 TLK 1 - -LAR @,!,@ 3088 2 TAR 1 0 07 -LAR @,! 3080 2 TAR 1 0 07 -LAR @,@ 3000 2 TAR 1 0 7F - -LARK @,@ C000 2 TAR 1 0 00FF -LARP @ 5588 2 T1 1 0 0007 - -LDP !,@ 5288 2 T1 1 0 07 -LDP ! 5280 2 NOP 1 -LDP @ 5200 2 T1 1 0 007F - -LDPK @ C800 2 T1 1 0 01FF ;9 bit constant - -LPH !,@ 5388 2 T1 1 0 07 -LPH ! 5380 2 NOP 1 -LPH @ 5300 2 T1 1 0 7F - -LRLK @,@ D000 4 T5 1 8 0700 ;, - -LST !,@ 5088 2 T1 1 0 07 -LST ! 5080 2 NOP 1 -LST @ 5000 2 T1 1 0 7F - -LST1 !,@ 5188 2 T1 1 0 07 -LST1 ! 5180 2 NOP 1 -LST1 @ 5100 2 T1 1 0 7F - -LT !,@ 3C88 2 T1 1 0 07 -LT ! 3C80 2 NOP 1 -LT @ 3C00 2 T1 1 0 7F - -LTA !,@ 3D88 2 T1 1 0 07 -LTA ! 3D80 2 NOP 1 -LTA @ 3D00 2 T1 1 0 7F - -LTD !,@ 3F88 2 T1 1 0 07 -LTD ! 3F80 2 NOP 1 -LTD @ 3F00 2 T1 1 0 7F - -LTP !,@ 3E88 2 T1 1 0 07 -LTP ! 3E80 2 NOP 1 -LTP @ 3E00 2 T1 1 0 7F - -LTS !,@ 5B88 2 T1 1 0 07 -LTS ! 5B80 2 NOP 1 -LTS @ 5B00 2 T1 1 0 7F - -MAC @,!,@ 5D88 4 TLK 1 0 07 -MAC @,! 5D80 4 TLK 1 0 07 -MAC @,@ 5D00 4 TLK 1 0 7F - -MACD @,!,@ 5C88 4 TLK 1 0 07 -MACD @,! 5C80 4 TLK 1 0 07 -MACD @,@ 5C00 4 TLK 1 0 7F - -MAR !,@ 5588 2 T1 1 0 07 -MAR ! 5580 2 NOP 1 -MAR @ 5500 2 T1 1 0 7F - -MPY !,@ 3888 2 T1 1 0 07 -MPY ! 3880 2 NOP 1 -MPY @ 3800 2 T1 1 0 7F - -MPYA !,@ 3A88 2 T1 1 0 07 -MPYA ! 3A80 2 NOP 1 -MPYA @ 3A00 2 T1 1 0 7F - -MPYK @ A000 2 T1 1 0 1FFF ;13 BIT CONTSTANT - -MPYS !,@ 3B88 2 T1 1 0 07 -MPYS ! 3B80 2 NOP 1 -MPYS @ 3B00 2 T1 1 0 7F - -MPYU !,@ CF88 2 T1 1 0 07 -MPYU ! CF80 2 NOP 1 -MPYU @ CF00 2 T1 1 0 7F - -NEG "" CE23 2 NOP 1 - -NOP "" 5500 2 NOP 1 - -NORM ! CE82 2 NOP 1 ; C25 -NORM "" CEA2 2 NOP 1 ; C20 - -OR !,@ 4D88 2 T1 1 0 07 -OR ! 4D80 2 NOP 1 -OR @ 4D00 2 T1 1 0 7F - -ORK @,@ D005 4 TLK 1 8 0F00 -ORK @ D005 4 TLK 1 - -OUT !,@,@ E088 2 T1 1 8 0F00 -OUT !,@ E080 2 T1 1 8 0F00 -OUT @,@ E000 2 TDMA 1 8 0F00 - -PAC "" CE14 2 NOP 1 - -POP "" CE1D 2 NOP 1 - -POPD !,@ 7A88 2 T1 1 0 07 -POPD ! 7A80 2 NOP 1 -POPD @ 7A00 2 T1 1 0 7F - -PSHD !,@ 5488 2 T1 1 0 07 -PSHD ! 5480 2 NOP 1 -PSHD @ 5400 2 T1 1 0 7F - -PUSH "" CE1C 2 NOP 1 -RC "" CE30 2 NOP 1 -RET "" CE26 2 NOP 1 -RFSM "" CE36 2 NOP 1 -RHM "" CE38 2 NOP 1 -ROL "" CE34 2 NOP 1 -ROR "" CE35 2 NOP 1 -ROVM "" CE02 2 NOP 1 - -RPT !,@ 4B88 2 T1 1 0 07 -RPT ! 4B80 2 NOP 1 -RPT @ 4B00 2 T1 1 0 7F - -RPTK @ CB00 2 T1 1 0 00FF ;8 bit constant - -RSXM "" CE06 2 NOP 1 -RTC "" CE32 2 NOP 1 -RTXM "" CE20 2 NOP 1 -RXF "" CE0C 2 NOP 1 - -/* shift count for SACH can only be 0,1, or 4 FOR 32020 -/* 0-7 FOR 320c25. For now, build the table specifically for the 320C25 -SACH !,@,@ 6888 2 T1 1 8 0700 -SACH !,@ 6880 2 T1 1 8 0700 -SACH ! 6880 2 NOP 1 -SACH @,@ 6800 2 TDMA 1 8 0700 -SACH @ 6800 2 T1 1 0 007F - -SACL !,@,@ 6088 2 T1 1 8 0700 -SACL !,@ 6080 2 T1 1 8 0700 -SACL ! 6080 2 NOP 1 -SACL @,@ 6000 2 TDMA 1 8 0700 -SACL @ 6000 2 T1 1 0 007F - -SAR @,!,@ 7088 2 TAR 1 0 0007 -SAR @,! 7080 2 TAR 1 0 0007 -SAR @,@ 7000 2 TAR 1 0 007F - -SBLK @,@ D003 4 TLK 1 8 0F00 -SBLK @ D003 4 TLK 1 - -SBRK @ 7F00 2 T1 1 0 00FF - -SC "" CE31 2 NOP 1 -SFL "" CE18 2 NOP 1 -SFR "" CE19 2 NOP 1 -SFSM "" CE37 2 NOP 1 -SHM "" CE39 2 NOP 1 -SOVM "" CE03 2 NOP 1 -SPAC "" CE16 2 NOP 1 - -SPH !,@ 7D88 2 T1 1 0 07 -SPH ! 7D80 2 NOP 1 -SPH @ 7D00 2 T1 1 0 7F - -SPL !,@ 7C88 2 T1 1 0 07 -SPL ! 7C80 2 NOP 1 -SPL @ 7C00 2 T1 1 0 7F - -SPM @ CE08 2 T1 1 0 03 ;2 bit constant - -SQRA !,@ 3988 2 T1 1 0 07 -SQRA ! 3980 2 NOP 1 -SQRA @ 3900 2 T1 1 0 7F - -SQRS !,@ 5A88 2 T1 1 0 07 -SQRS ! 5A80 2 NOP 1 -SQRS @ 5A00 2 T1 1 0 7F - -SST !,@ 7888 2 T1 1 0 07 -SST ! 7880 2 NOP 1 -SST @ 7800 2 T1 1 0 7F - -SST1 !,@ 7988 2 T1 1 0 07 -SST1 ! 7980 2 NOP 1 -SST1 @ 7900 2 T1 1 0 7F - -SSXM "" CE07 2 NOP 1 -STC "" CE33 2 NOP 1 -STXM "" CE21 2 NOP 1 - - -SUB !,@,@ 1088 2 T1 1 8 0F00 -SUB !,@ 1080 2 T1 1 8 0F00 -SUB ! 1080 2 NOP 1 -SUB @,@ 1000 2 TDMA 1 8 0F00 -SUB @ 1000 2 T1 1 0 007F - -SUBB !,@ 4F88 2 T1 1 0 07 -SUBB ! 4F80 2 NOP 1 -SUBB @ 4F00 2 T1 1 0 7F - -SUBC !,@ 4788 2 T1 1 0 07 -SUBC ! 4780 2 NOP 1 -SUBC @ 4700 2 T1 1 0 7F - -SUBH !,@ 4488 2 T1 1 0 07 -SUBH ! 4480 2 NOP 1 -SUBH @ 4400 2 T1 1 0 7F - -SUBK @ CD00 2 T1 1 0 00FF - -SUBS !,@ 4588 2 T1 1 0 07 -SUBS ! 4580 2 NOP 1 -SUBS @ 4500 2 T1 1 0 7F - -SUBT !,@ 4688 2 T1 1 0 07 -SUBT ! 4680 2 NOP 1 -SUBT @ 4600 2 T1 1 0 7F - -SXF "" CE0D 2 NOP 1 - -TBLR !,@ 5888 2 T1 1 0 07 -TBLR ! 5880 2 NOP 1 -TBLR @ 5800 2 T1 1 0 7F - -TBLW !,@ 5988 2 T1 1 0 07 -TBLW ! 5980 2 NOP 1 -TBLW @ 5900 2 T1 1 0 7F - -TRAP "" CE1E 2 NOP 1 - -XOR !,@ 4C88 2 T1 1 0 07 -XOR ! 4C80 2 NOP 1 -XOR @ 4C00 2 T1 1 0 7F - -XORK @,@ D006 4 TLK 1 8 0F00 -XORK @ D006 4 TLK 1 - -ZAC "" CA00 2 NOP 1 - -ZALH !,@ 4088 2 T1 1 0 07 -ZALH ! 4080 2 NOP 1 -ZALH @ 4000 2 T1 1 0 7F - -ZALR !,@ 7B88 2 T1 1 0 07 -ZALR ! 7B80 2 NOP 1 -ZALR @ 7B00 2 T1 1 0 7F - -ZALS !,@ 4188 2 T1 1 0 07 -ZALS ! 4180 2 NOP 1 -ZALS @ 4100 2 T1 1 0 7F - diff --git a/branches/s100/Tools/tasm32/TASM48.TAB b/branches/s100/Tools/tasm32/TASM48.TAB deleted file mode 100644 index c241a0ff..00000000 --- a/branches/s100/Tools/tasm32/TASM48.TAB +++ /dev/null @@ -1,281 +0,0 @@ -"TASM 8048 Assembler. " -/**************************************************************************** -/* $Id: tasm48.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8048 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* CLASS bits are assigned as follows: -/* bit 0 = 8X48, 8035, 8039, 8049 instructions -/* bit 1 = 8X41A -/* bit 2 = 8022 -/* bit 3 = 8021 -/* Note that some of the base instructions should be disabled for the -/* 8041, 8022, and 8021, but are not. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ADD A,R0 68 1 NOP 1 -ADD A,R1 69 1 NOP 1 -ADD A,R2 6A 1 NOP 1 -ADD A,R3 6B 1 NOP 1 -ADD A,R4 6C 1 NOP 1 -ADD A,R5 6D 1 NOP 1 -ADD A,R6 6E 1 NOP 1 -ADD A,R7 6F 1 NOP 1 -ADD A,@R0 60 1 NOP 1 -ADD A,@R1 61 1 NOP 1 -ADD A,#* 03 2 NOP 1 - -ADDC A,R0 78 1 NOP 1 -ADDC A,R1 79 1 NOP 1 -ADDC A,R2 7A 1 NOP 1 -ADDC A,R3 7B 1 NOP 1 -ADDC A,R4 7C 1 NOP 1 -ADDC A,R5 7D 1 NOP 1 -ADDC A,R6 7E 1 NOP 1 -ADDC A,R7 7F 1 NOP 1 -ADDC A,@R0 70 1 NOP 1 -ADDC A,@R1 71 1 NOP 1 -ADDC A,#* 13 2 NOP 1 - -ANL A,R0 58 1 NOP 1 -ANL A,R1 59 1 NOP 1 -ANL A,R2 5A 1 NOP 1 -ANL A,R3 5B 1 NOP 1 -ANL A,R4 5C 1 NOP 1 -ANL A,R5 5D 1 NOP 1 -ANL A,R6 5E 1 NOP 1 -ANL A,R7 5F 1 NOP 1 -ANL A,@R0 50 1 NOP 1 -ANL A,@R1 51 1 NOP 1 -ANL A,#* 53 2 NOP 1 -ANL BUS,#* 98 2 NOP 1 -ANL P1,#* 99 2 NOP 1 -ANL P2,#* 9A 2 NOP 1 - -ANLD P4,A 9C 1 NOP 1 -ANLD P5,A 9D 1 NOP 1 -ANLD P6,A 9E 1 NOP 1 -ANLD P7,A 9F 1 NOP 1 - -CALL * 14 2 JMP 1 - -CLR A 27 1 NOP 1 -CLR C 97 1 NOP 1 -CLR F0 85 1 NOP 1 -CLR F1 A5 1 NOP 1 - -CPL A 37 1 NOP 1 -CPL C A7 1 NOP 1 -CPL F0 95 1 NOP 1 -CPL F1 B5 1 NOP 1 - -DA A 57 1 NOP 1 - -DEC A 07 1 NOP 1 -DEC R0 C8 1 NOP 1 -DEC R1 C9 1 NOP 1 -DEC R2 CA 1 NOP 1 -DEC R3 CB 1 NOP 1 -DEC R4 CC 1 NOP 1 -DEC R5 CD 1 NOP 1 -DEC R6 CE 1 NOP 1 -DEC R7 CF 1 NOP 1 - -DIS I 15 1 NOP 1 -DIS TCNTI 35 1 NOP 1 - -DJNZ R0,* E8 2 JTHISPAGE 1 -DJNZ R1,* E9 2 JTHISPAGE 1 -DJNZ R2,* EA 2 JTHISPAGE 1 -DJNZ R3,* EB 2 JTHISPAGE 1 -DJNZ R4,* EC 2 JTHISPAGE 1 -DJNZ R5,* ED 2 JTHISPAGE 1 -DJNZ R6,* EE 2 JTHISPAGE 1 -DJNZ R7,* EF 2 JTHISPAGE 1 - -EN DMA E5 1 NOP 2 ;8041 -EN FLAGS F5 1 NOP 2 ;8041 -EN I 05 1 NOP 1 -EN TCNTI 25 1 NOP 1 -ENT0 CLK 75 1 NOP 1 - -IN A,DBB 22 1 NOP 2 ;8041 -IN A,P0 08 1 NOP 8 ;8021 -IN A,P1 09 1 NOP 1 -IN A,P2 0A 1 NOP 1 - -INC A 17 1 NOP 1 -INC R0 18 1 NOP 1 -INC R1 19 1 NOP 1 -INC R2 1A 1 NOP 1 -INC R3 1B 1 NOP 1 -INC R4 1C 1 NOP 1 -INC R5 1D 1 NOP 1 -INC R6 1E 1 NOP 1 -INC R7 1F 1 NOP 1 -INC @R0 10 1 NOP 1 -INC @R1 11 1 NOP 1 - -INS A,BUS 08 1 NOP 1 - -JB0 * 12 2 JTHISPAGE 1 -JB1 * 32 2 JTHISPAGE 1 -JB2 * 52 2 JTHISPAGE 1 -JB3 * 72 2 JTHISPAGE 1 -JB4 * 92 2 JTHISPAGE 1 -JB5 * B2 2 JTHISPAGE 1 -JB6 * D2 2 JTHISPAGE 1 -JB7 * F2 2 JTHISPAGE 1 - -JMP * 04 2 JMP 1 - -JC * F6 2 JTHISPAGE 1 -JF0 * B6 2 JTHISPAGE 1 -JF1 * 76 2 JTHISPAGE 1 -JNC * E6 2 JTHISPAGE 1 -JNI * 86 2 JTHISPAGE 1 -JNIBF * D6 2 JTHISPAGE 2 ;8041 -JNT0 * 26 2 JTHISPAGE 1 -JNT1 * 46 2 JTHISPAGE 1 -JNZ * 96 2 JTHISPAGE 1 -JOBF * 86 2 JTHISPAGE 2 ;8041 -JTF * 16 2 JTHISPAGE 1 -JT0 * 36 2 JTHISPAGE 1 -JT1 * 56 2 JTHISPAGE 1 -JZ * C6 2 JTHISPAGE 1 - -JMPP @A B3 1 NOP 1 - -MOV A,PSW C7 1 NOP 1 -MOV A,R0 F8 1 NOP 1 -MOV A,R1 F9 1 NOP 1 -MOV A,R2 FA 1 NOP 1 -MOV A,R3 FB 1 NOP 1 -MOV A,R4 FC 1 NOP 1 -MOV A,R5 FD 1 NOP 1 -MOV A,R6 FE 1 NOP 1 -MOV A,R7 FF 1 NOP 1 -MOV A,T 42 1 NOP 1 -MOV A,@R0 F0 1 NOP 1 -MOV A,@R1 F1 1 NOP 1 -MOV A,#* 23 2 NOP 1 -MOV PSW,A D7 1 NOP 1 -MOV R0,A A8 1 NOP 1 -MOV R1,A A9 1 NOP 1 -MOV R2,A AA 1 NOP 1 -MOV R3,A AB 1 NOP 1 -MOV R4,A AC 1 NOP 1 -MOV R5,A AD 1 NOP 1 -MOV R6,A AE 1 NOP 1 -MOV R7,A AF 1 NOP 1 -MOV R0,#* B8 2 NOP 1 -MOV R1,#* B9 2 NOP 1 -MOV R2,#* BA 2 NOP 1 -MOV R3,#* BB 2 NOP 1 -MOV R4,#* BC 2 NOP 1 -MOV R5,#* BD 2 NOP 1 -MOV R6,#* BE 2 NOP 1 -MOV R7,#* BF 2 NOP 1 -MOV STS,A 90 1 NOP 2 ;8041 -MOV T,A 62 1 NOP 1 -MOV @R0,A A0 1 NOP 1 -MOV @R1,A A1 1 NOP 1 -MOV @R0,#* B0 2 NOP 1 -MOV @R1,#* B1 2 NOP 1 - -MOVD A,P4 0C 1 NOP 1 -MOVD A,P5 0D 1 NOP 1 -MOVD A,P6 0E 1 NOP 1 -MOVD A,P7 0F 1 NOP 1 -MOVD P4,A 3C 1 NOP 1 -MOVD P5,A 3D 1 NOP 1 -MOVD P6,A 3E 1 NOP 1 -MOVD P7,A 3F 1 NOP 1 - -MOVP A,@A A3 1 NOP 1 -MOVP3 A,@A E3 1 NOP 1 - -MOVX A,@R0 80 1 NOP 1 -MOVX A,@R1 81 1 NOP 1 -MOVX @R0,A 90 1 NOP 1 -MOVX @R1,A 91 1 NOP 1 - -NOP "" 00 1 NOP 1 - -ORL A,R0 48 1 NOP 1 -ORL A,R1 49 1 NOP 1 -ORL A,R2 4A 1 NOP 1 -ORL A,R3 4B 1 NOP 1 -ORL A,R4 4C 1 NOP 1 -ORL A,R5 4D 1 NOP 1 -ORL A,R6 4E 1 NOP 1 -ORL A,R7 4F 1 NOP 1 -ORL A,@R0 40 1 NOP 1 -ORL A,@R1 41 1 NOP 1 -ORL A,#* 43 2 NOP 1 -ORL BUS,#* 88 2 NOP 1 -ORL P1,#* 89 2 NOP 1 -ORL P2,#* 8A 2 NOP 1 - -ORLD P4,A 8C 1 NOP 1 -ORLD P5,A 8D 1 NOP 1 -ORLD P6,A 8E 1 NOP 1 -ORLD P7,A 8F 1 NOP 1 - -OUTL BUS,A 02 1 NOP 1 -OUT DBB,A 02 1 NOP 2 ;8041 -OUTL P0,A 90 1 NOP 8 ;8021 -OUTL P1,A 39 1 NOP 1 -OUTL P2,A 3A 1 NOP 1 - -RAD "" 80 1 NOP 4 ;8022 - -RET "" 83 1 NOP 1 -RETI "" 93 1 NOP 4 ;8022 -RETR "" 93 1 NOP 1 - -RL A E7 1 NOP 1 -RLC A F7 1 NOP 1 -RR A 77 1 NOP 1 -RRC A 67 1 NOP 1 - -SEL AN0 85 1 NOP 4 ;8022 -SEL AN1 95 1 NOP 4 ;8022 -SEL MB0 E5 1 NOP 1 -SEL MB1 F5 1 NOP 1 -SEL RB0 C5 1 NOP 1 -SEL RB1 D5 1 NOP 1 - -STOP TCNT 65 1 NOP 1 -STRT CNT 45 1 NOP 1 -STRT T 55 1 NOP 1 - -SWAP A 47 1 NOP 1 - -XCH A,R0 28 1 NOP 1 -XCH A,R1 29 1 NOP 1 -XCH A,R2 2A 1 NOP 1 -XCH A,R3 2B 1 NOP 1 -XCH A,R4 2C 1 NOP 1 -XCH A,R5 2D 1 NOP 1 -XCH A,R6 2E 1 NOP 1 -XCH A,R7 2F 1 NOP 1 -XCH A,@R0 20 1 NOP 1 -XCH A,@R1 21 1 NOP 1 - -XCHD A,@R0 30 1 NOP 1 -XCHD A,@R1 31 1 NOP 1 - -XRL A,R0 D8 1 NOP 1 -XRL A,R1 D9 1 NOP 1 -XRL A,R2 DA 1 NOP 1 -XRL A,R3 DB 1 NOP 1 -XRL A,R4 DC 1 NOP 1 -XRL A,R5 DD 1 NOP 1 -XRL A,R6 DE 1 NOP 1 -XRL A,R7 DF 1 NOP 1 -XRL A,@R0 D0 1 NOP 1 -XRL A,@R1 D1 1 NOP 1 -XRL A,#* D3 2 NOP 1 - diff --git a/branches/s100/Tools/tasm32/TASM51.TAB b/branches/s100/Tools/tasm32/TASM51.TAB deleted file mode 100644 index 40fc3a56..00000000 --- a/branches/s100/Tools/tasm32/TASM51.TAB +++ /dev/null @@ -1,285 +0,0 @@ -"TASM 8051 Assembler. " -/**************************************************************************** -/* $Id: tasm51.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8051 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* - -.NOARGSHIFT - -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ACALL * 11 2 JMP 1 0 F800 - -ADD A,R0 28 1 NOP 1 -ADD A,R1 29 1 NOP 1 -ADD A,R2 2A 1 NOP 1 -ADD A,R3 2B 1 NOP 1 -ADD A,R4 2C 1 NOP 1 -ADD A,R5 2D 1 NOP 1 -ADD A,R6 2E 1 NOP 1 -ADD A,R7 2F 1 NOP 1 -ADD A,@R0 26 1 NOP 1 -ADD A,@R1 27 1 NOP 1 -ADD A,#* 24 2 NOP 1 -ADD A,* 25 2 NOP 1 - -ADDC A,R0 38 1 NOP 1 -ADDC A,R1 39 1 NOP 1 -ADDC A,R2 3A 1 NOP 1 -ADDC A,R3 3B 1 NOP 1 -ADDC A,R4 3C 1 NOP 1 -ADDC A,R5 3D 1 NOP 1 -ADDC A,R6 3E 1 NOP 1 -ADDC A,R7 3F 1 NOP 1 -ADDC A,@R0 36 1 NOP 1 -ADDC A,@R1 37 1 NOP 1 -ADDC A,#* 34 2 NOP 1 -ADDC A,* 35 2 NOP 1 - -AJMP * 01 2 JMP 1 0 F800 - -ANL A,R0 58 1 NOP 1 -ANL A,R1 59 1 NOP 1 -ANL A,R2 5A 1 NOP 1 -ANL A,R3 5B 1 NOP 1 -ANL A,R4 5C 1 NOP 1 -ANL A,R5 5D 1 NOP 1 -ANL A,R6 5E 1 NOP 1 -ANL A,R7 5F 1 NOP 1 -ANL A,@R0 56 1 NOP 1 -ANL A,@R1 57 1 NOP 1 -ANL A,#* 54 2 NOP 1 -ANL A,* 55 2 NOP 1 -ANL C,/* b0 2 NOP 1 -ANL C,* 82 2 NOP 1 -ANL *,A 52 2 NOP 1 -ANL *,#* 53 3 COMBINE 1 - -CJNE A,#*,* b4 3 CR 1 -CJNE A,*,* b5 3 CR 1 -CJNE R0,#*,* b8 3 CR 1 -CJNE R1,#*,* b9 3 CR 1 -CJNE R2,#*,* ba 3 CR 1 -CJNE R3,#*,* bb 3 CR 1 -CJNE R4,#*,* bc 3 CR 1 -CJNE R5,#*,* bd 3 CR 1 -CJNE R6,#*,* be 3 CR 1 -CJNE R7,#*,* bf 3 CR 1 -CJNE @R0,#*,* b6 3 CR 1 -CJNE @R1,#*,* b7 3 CR 1 - -CLR A e4 1 NOP 1 -CLR C c3 1 NOP 1 -CLR * c2 2 NOP 1 - -CPL A f4 1 NOP 1 -CPL C b3 1 NOP 1 -CPL * b2 2 NOP 1 - -DA A d4 1 NOP 1 - -DEC A 14 1 NOP 1 -DEC R0 18 1 NOP 1 -DEC R1 19 1 NOP 1 -DEC R2 1A 1 NOP 1 -DEC R3 1B 1 NOP 1 -DEC R4 1C 1 NOP 1 -DEC R5 1D 1 NOP 1 -DEC R6 1E 1 NOP 1 -DEC R7 1F 1 NOP 1 -DEC @R0 16 1 NOP 1 -DEC @R1 17 1 NOP 1 -DEC * 15 2 NOP 1 - -DIV AB 84 1 NOP 1 - -DJNZ R0,* d8 2 R1 1 -DJNZ R1,* d9 2 R1 1 -DJNZ R2,* dA 2 R1 1 -DJNZ R3,* dB 2 R1 1 -DJNZ R4,* dC 2 R1 1 -DJNZ R5,* dD 2 R1 1 -DJNZ R6,* dE 2 R1 1 -DJNZ R7,* dF 2 R1 1 -DJNZ *,* d5 3 CR 1 - -INC A 04 1 NOP 1 -INC R0 08 1 NOP 1 -INC R1 09 1 NOP 1 -INC R2 0A 1 NOP 1 -INC R3 0B 1 NOP 1 -INC R4 0C 1 NOP 1 -INC R5 0D 1 NOP 1 -INC R6 0E 1 NOP 1 -INC R7 0F 1 NOP 1 -INC @R0 06 1 NOP 1 -INC @R1 07 1 NOP 1 -INC DPTR a3 1 NOP 1 -INC * 05 2 NOP 1 - -JB *,* 20 3 CR 1 -JBC *,* 10 3 CR 1 -JC * 40 2 R1 1 -JMP @A+DPTR 73 1 NOP 1 -JNB *,* 30 3 CR 1 -JNC * 50 2 R1 1 -JNZ * 70 2 R1 1 -JZ * 60 2 R1 1 - -LCALL * 12 3 SWAP 1 - -LJMP * 02 3 SWAP 1 - -MOV A,R0 e8 1 NOP 1 -MOV A,R1 e9 1 NOP 1 -MOV A,R2 eA 1 NOP 1 -MOV A,R3 eB 1 NOP 1 -MOV A,R4 eC 1 NOP 1 -MOV A,R5 eD 1 NOP 1 -MOV A,R6 eE 1 NOP 1 -MOV A,R7 eF 1 NOP 1 -MOV A,@R0 e6 1 NOP 1 -MOV A,@R1 e7 1 NOP 1 -MOV A,#* 74 2 NOP 1 -MOV A,* e5 2 NOP 1 -MOV C,* a2 2 NOP 1 -MOV DPTR,#* 90 3 SWAP 1 -MOV R0,A f8 1 NOP 1 -MOV R1,A f9 1 NOP 1 -MOV R2,A fA 1 NOP 1 -MOV R3,A fB 1 NOP 1 -MOV R4,A fC 1 NOP 1 -MOV R5,A fD 1 NOP 1 -MOV R6,A fE 1 NOP 1 -MOV R7,A fF 1 NOP 1 -MOV R0,#* 78 2 NOP 1 -MOV R1,#* 79 2 NOP 1 -MOV R2,#* 7A 2 NOP 1 -MOV R3,#* 7B 2 NOP 1 -MOV R4,#* 7C 2 NOP 1 -MOV R5,#* 7D 2 NOP 1 -MOV R6,#* 7E 2 NOP 1 -MOV R7,#* 7F 2 NOP 1 -MOV R0,* a8 2 NOP 1 -MOV R1,* a9 2 NOP 1 -MOV R2,* aA 2 NOP 1 -MOV R3,* aB 2 NOP 1 -MOV R4,* aC 2 NOP 1 -MOV R5,* aD 2 NOP 1 -MOV R6,* aE 2 NOP 1 -MOV R7,* aF 2 NOP 1 -MOV @R0,A f6 1 NOP 1 -MOV @R1,A f7 1 NOP 1 -MOV @R0,#* 76 2 NOP 1 -MOV @R1,#* 77 2 NOP 1 -MOV @R0,* a6 2 NOP 1 -MOV @R1,* a7 2 NOP 1 -MOV *,A f5 2 NOP 1 -MOV *,C 92 2 NOP 1 -MOV *,R0 88 2 NOP 1 -MOV *,R1 89 2 NOP 1 -MOV *,R2 8A 2 NOP 1 -MOV *,R3 8B 2 NOP 1 -MOV *,R4 8C 2 NOP 1 -MOV *,R5 8D 2 NOP 1 -MOV *,R6 8E 2 NOP 1 -MOV *,R7 8F 2 NOP 1 -MOV *,@R0 86 2 NOP 1 -MOV *,@R1 87 2 NOP 1 -MOV *,#* 75 3 COMBINE 1 -MOV *,* 85 3 CSWAP 1 - -MOVC A,@A+DPTR 93 1 NOP 1 -MOVC A,@A+PC 83 1 NOP 1 - -MOVX A,@R0 e2 1 NOP 1 -MOVX A,@R1 e3 1 NOP 1 -MOVX A,@DPTR e0 1 NOP 1 -MOVX @R0,A f2 1 NOP 1 -MOVX @R1,A f3 1 NOP 1 -MOVX @DPTR,A f0 1 NOP 1 - -MUL AB a4 1 NOP 1 - -NOP "" 00 1 NOP 1 - -ORL A,R0 48 1 NOP 1 -ORL A,R1 49 1 NOP 1 -ORL A,R2 4A 1 NOP 1 -ORL A,R3 4B 1 NOP 1 -ORL A,R4 4C 1 NOP 1 -ORL A,R5 4D 1 NOP 1 -ORL A,R6 4E 1 NOP 1 -ORL A,R7 4F 1 NOP 1 -ORL A,@R0 46 1 NOP 1 -ORL A,@R1 47 1 NOP 1 -ORL A,#* 44 2 NOP 1 -ORL A,* 45 2 NOP 1 -ORL C,/* a0 2 NOP 1 -ORL C,* 72 2 NOP 1 -ORL *,A 42 2 NOP 1 -ORL *,#* 43 3 COMBINE 1 - -POP * d0 2 NOP 1 -PUSH * c0 2 NOP 1 - -RET "" 22 1 NOP 1 -RETI "" 32 1 NOP 1 - -RL A 23 1 NOP 1 -RLC A 33 1 NOP 1 -RR A 03 1 NOP 1 -RRC A 13 1 NOP 1 - -SETB C d3 1 NOP 1 -SETB * d2 2 NOP 1 - -SJMP * 80 2 R1 1 - -SUBB A,R0 98 1 NOP 1 -SUBB A,R1 99 1 NOP 1 -SUBB A,R2 9A 1 NOP 1 -SUBB A,R3 9B 1 NOP 1 -SUBB A,R4 9C 1 NOP 1 -SUBB A,R5 9D 1 NOP 1 -SUBB A,R6 9E 1 NOP 1 -SUBB A,R7 9F 1 NOP 1 -SUBB A,@R0 96 1 NOP 1 -SUBB A,@R1 97 1 NOP 1 -SUBB A,#* 94 2 NOP 1 -SUBB A,* 95 2 NOP 1 - -SWAP A c4 1 NOP 1 - -XCH A,R0 c8 1 NOP 1 -XCH A,R1 c9 1 NOP 1 -XCH A,R2 cA 1 NOP 1 -XCH A,R3 cB 1 NOP 1 -XCH A,R4 cC 1 NOP 1 -XCH A,R5 cD 1 NOP 1 -XCH A,R6 cE 1 NOP 1 -XCH A,R7 cF 1 NOP 1 -XCH A,@R0 c6 1 NOP 1 -XCH A,@R1 c7 1 NOP 1 -XCH A,* c5 2 NOP 1 - -XCHD A,@R0 d6 1 NOP 1 -XCHD A,@R1 d7 1 NOP 1 - -XRL A,R0 68 1 NOP 1 -XRL A,R1 69 1 NOP 1 -XRL A,R2 6A 1 NOP 1 -XRL A,R3 6B 1 NOP 1 -XRL A,R4 6C 1 NOP 1 -XRL A,R5 6D 1 NOP 1 -XRL A,R6 6E 1 NOP 1 -XRL A,R7 6F 1 NOP 1 -XRL A,@R0 66 1 NOP 1 -XRL A,@R1 67 1 NOP 1 -XRL A,#* 64 2 NOP 1 -XRL A,* 65 2 NOP 1 -XRL *,A 62 2 NOP 1 -XRL *,#* 63 3 COMBINE 1 - diff --git a/branches/s100/Tools/tasm32/TASM65.TAB b/branches/s100/Tools/tasm32/TASM65.TAB deleted file mode 100644 index b30b4d20..00000000 --- a/branches/s100/Tools/tasm32/TASM65.TAB +++ /dev/null @@ -1,222 +0,0 @@ -"TASM 6502 Assembler. " -/**************************************************************************** -/* $Id: tasm65.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 6502 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* Note that there are two classes of extended instructions beyond -/* the standard set. The classes are assigned bits as follows: -/* bit 0 = standard set -/* bit 1 = extended instructions for R65C02 -/* bit 2 = extended instructions for R65C00/21 -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ADC #* 69 2 NOP 1 -ADC (*,X) 61 2 NOP 1 -ADC (*),Y 71 2 NOP 1 -ADC (*) 72 2 NOP 2 -ADC *,X 7D 3 ZP 1 -ADC *,Y 79 3 NOP 1 -ADC * 6D 3 ZP 1 - -AND #* 29 2 NOP 1 -AND (*,X) 21 2 NOP 1 -AND (*),Y 31 2 NOP 1 -AND (*) 32 2 NOP 2 -AND *,X 3D 3 ZP 1 -AND *,Y 39 3 NOP 1 -AND * 2D 3 ZP 1 - -ASL A 0A 1 NOP 1 -ASL *,X 1E 3 ZP 1 -ASL * 0E 3 ZP 1 - -BBR0 *,* 0f 3 CR 6 -BBR1 *,* 1f 3 CR 6 -BBR2 *,* 2f 3 CR 6 -BBR3 *,* 3f 3 CR 6 -BBR4 *,* 4f 3 CR 6 -BBR5 *,* 5f 3 CR 6 -BBR6 *,* 6f 3 CR 6 -BBR7 *,* 7f 3 CR 6 - -BBS0 *,* 8f 3 CR 6 -BBS1 *,* 9f 3 CR 6 -BBS2 *,* af 3 CR 6 -BBS3 *,* bf 3 CR 6 -BBS4 *,* cf 3 CR 6 -BBS5 *,* df 3 CR 6 -BBS6 *,* ef 3 CR 6 -BBS7 *,* ff 3 CR 6 - -BCC * 90 2 R1 1 -BCS * B0 2 R1 1 -BEQ * F0 2 R1 1 -BMI * 30 2 R1 1 -BNE * D0 2 R1 1 -BPL * 10 2 R1 1 -BRA * 80 2 R1 6 -BVC * 50 2 R1 1 -BVS * 70 2 R1 1 - -BIT #* 89 2 NOP 2 -BIT *,X 3C 3 ZP 2 -BIT * 2C 3 ZP 1 - -BRK "" 00 1 NOP 1 - -CLC "" 18 1 NOP 1 -CLD "" D8 1 NOP 1 -CLI "" 58 1 NOP 1 -CLV "" B8 1 NOP 1 - -CMP #* C9 2 NOP 1 -CMP (*,X) C1 2 NOP 1 -CMP (*),Y D1 2 NOP 1 -CMP (*) D2 2 NOP 2 -CMP *,X DD 3 ZP 1 -CMP *,Y D9 3 NOP 1 -CMP * CD 3 ZP 1 - -CPX #* E0 2 NOP 1 -CPX * EC 3 ZP 1 - -CPY #* C0 2 NOP 1 -CPY * CC 3 ZP 1 - -DEC A 3A 1 NOP 2 -DEC *,X DE 3 ZP 1 -DEC * CE 3 ZP 1 - -DEX "" CA 1 NOP 1 -DEY "" 88 1 NOP 1 - -EOR #* 49 2 NOP 1 -EOR (*,X) 41 2 NOP 1 -EOR (*),Y 51 2 NOP 1 -EOR (*) 52 2 NOP 2 -EOR *,X 5D 3 ZP 1 -EOR *,Y 59 3 NOP 1 -EOR * 4D 3 ZP 1 - -INC A 1A 1 NOP 2 -INC *,X FE 3 ZP 1 -INC * EE 3 ZP 1 - -INX "" E8 1 NOP 1 -INY "" C8 1 NOP 1 - -JMP (*,X) 7C 3 NOP 2 -JMP (*) 6C 3 NOP 1 -JMP * 4C 3 NOP 1 - -JSR * 20 3 NOP 1 - -LDA #* A9 2 NOP 1 -LDA (*,X) A1 2 NOP 1 -LDA (*),Y B1 2 NOP 1 -LDA (*) B2 2 NOP 2 -LDA *,X BD 3 ZP 1 -LDA *,Y B9 3 NOP 1 -LDA * AD 3 ZP 1 - -LDX #* A2 2 NOP 1 -LDX *,Y BE 3 ZP 1 -LDX * AE 3 ZP 1 - -LDY #* A0 2 NOP 1 -LDY *,X BC 3 ZP 1 -LDY * AC 3 ZP 1 - -LSR A 4A 1 NOP 1 -LSR *,X 5E 3 ZP 1 -LSR * 4E 3 ZP 1 - -MUL "" 02 1 NOP 4 /* R65C00/21 only*/ - -NOP "" EA 1 NOP 1 - -ORA #* 09 2 NOP 1 -ORA (*,X) 01 2 NOP 1 -ORA (*),Y 11 2 NOP 1 -ORA (*) 12 2 NOP 2 -ORA *,X 1D 3 ZP 1 -ORA *,Y 19 3 NOP 1 -ORA * 0D 3 ZP 1 - -PHA "" 48 1 NOP 1 -PHP "" 08 1 NOP 1 -PHX "" DA 1 NOP 6 -PHY "" 5A 1 NOP 6 -PLA "" 68 1 NOP 1 -PLP "" 28 1 NOP 1 -PLX "" FA 1 NOP 6 -PLY "" 7A 1 NOP 6 - -RMB0 * 07 2 NOP 6 -RMB1 * 17 2 NOP 6 -RMB2 * 27 2 NOP 6 -RMB3 * 37 2 NOP 6 -RMB4 * 47 2 NOP 6 -RMB5 * 57 2 NOP 6 -RMB6 * 67 2 NOP 6 -RMB7 * 77 2 NOP 6 - -ROL A 2A 1 NOP 1 -ROL *,X 3E 3 ZP 1 -ROL * 2E 3 ZP 1 - -ROR A 6A 1 NOP 1 -ROR *,X 7E 3 ZP 1 -ROR * 6E 3 ZP 1 - -RTI "" 40 1 NOP 1 -RTS "" 60 1 NOP 1 - -SBC #* E9 2 NOP 1 -SBC (*,X) E1 2 NOP 1 -SBC (*),Y F1 2 NOP 1 -SBC (*) F2 2 NOP 2 -SBC *,X FD 3 ZP 1 -SBC *,Y F9 3 NOP 1 -SBC * ED 3 ZP 1 - -SEC "" 38 1 NOP 1 -SED "" F8 1 NOP 1 -SEI "" 78 1 NOP 1 - -SMB0 * 87 2 NOP 6 -SMB1 * 97 2 NOP 6 -SMB2 * a7 2 NOP 6 -SMB3 * b7 2 NOP 6 -SMB4 * c7 2 NOP 6 -SMB5 * d7 2 NOP 6 -SMB6 * e7 2 NOP 6 -SMB7 * f7 2 NOP 6 - -STA (*,X) 81 2 NOP 1 -STA (*),Y 91 2 NOP 1 -STA (*) 92 2 NOP 2 -STA *,X 9D 3 ZP 1 -STA *,Y 99 3 NOP 1 -STA * 8D 3 ZP 1 - -STX *,Y 96 2 ZP 1 -STX * 8E 3 ZP 1 - -STY *,X 94 2 NOP 1 -STY * 8C 3 ZP 1 - -STZ *,X 9e 3 ZP 2 -STZ * 9c 3 ZP 2 - -TAX "" AA 1 NOP 1 -TAY "" A8 1 NOP 1 -TRB * 1c 3 ZP 2 -TSB * 0c 3 ZP 2 -TSX "" BA 1 NOP 1 -TXA "" 8A 1 NOP 1 -TXS "" 9A 1 NOP 1 -TYA "" 98 1 NOP 1 - diff --git a/branches/s100/Tools/tasm32/TASM68.TAB b/branches/s100/Tools/tasm32/TASM68.TAB deleted file mode 100644 index c3543c5a..00000000 --- a/branches/s100/Tools/tasm32/TASM68.TAB +++ /dev/null @@ -1,348 +0,0 @@ -"TASM 6800-6811 Assembler" -/**************************************************************************** -/* $Id: tasm68.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* Originally submitted by Richard P. White, June 4,1989 */ -/* Corrected and enhanced by T.N. Anderson, STI */ -/* Enhanced for the 68HC11 by George Blat, Nov 3, 1990 -/* Class bits defined as follows: -/* -/* bit 0 for 6800 -/* bit 1 for 6801/6803 -/* bit 2 for 68HC11 -/* -/* Note that TASM deviates from motorola syntax for BCLR, BSET, -/* BRCLR, and BRSET instructions. TASM requires commas between -/* each arg. Motorola requires white space before the make and -/* label args. - -.MSFIRST - -ABA "" 1B 1 NOP 1 -ABX "" 3A 1 NOP 2 -ABY "" 183A 2 NOP 4 - -ADCA #* 89 2 NOP 1 -ADCA *,Y 18A9 3 NOP 4 -ADCA *,X A9 2 NOP 1 -ADCA * B9 3 MZERO 1 - -ADCB #* C9 2 NOP 1 -ADCB *,Y 18E9 3 NOP 4 -ADCB *,X E9 2 NOP 1 -ADCB * F9 3 MZERO 1 - -ADDA #* 8B 2 NOP 1 -ADDA *,Y 18AB 3 NOP 4 -ADDA *,X AB 2 NOP 1 -ADDA * BB 3 MZERO 1 - -ADDB #* CB 2 NOP 1 -ADDB *,Y 18EB 3 NOP 4 -ADDB *,X EB 2 NOP 1 -ADDB * FB 3 MZERO 1 - -ADDD #* C3 3 SWAP 2 -ADDD *,Y 18E3 3 NOP 4 -ADDD *,X E3 2 NOP 2 -ADDD * F3 3 MZERO 2 - -ANDA #* 84 2 NOP 1 -ANDA *,Y 18A4 3 NOP 4 -ANDA *,X A4 2 NOP 1 -ANDA * B4 3 MZERO 1 - -ANDB #* C4 2 NOP 1 -ANDB *,Y 18E4 3 NOP 4 -ANDB *,X E4 2 NOP 1 -ANDB * F4 3 MZERO 1 - -ASL *,Y 1868 3 NOP 4 -ASL *,X 68 2 NOP 1 -ASL * 78 3 SWAP 1 -ASLA "" 48 1 NOP 1 -ASLB "" 58 1 NOP 1 -ASLD "" 05 1 NOP 2 - -ASR *,Y 1867 3 NOP 4 -ASR *,X 67 2 NOP 1 -ASR * 77 3 SWAP 1 -ASRA "" 47 1 NOP 1 -ASRB "" 57 1 NOP 1 - -BCC * 24 2 R1 1 -BCLR *,X,* 1D 3 COMB 4 -BCLR *,Y,* 181D 4 COMB 4 -BCLR *,#* 15 3 COMB 4 /* allow # since mask is immediate data -BCLR *,* 15 3 COMB 4 -BCS * 25 2 R1 1 -BEQ * 27 2 R1 1 -BGE * 2C 2 R1 1 -BGT * 2E 2 R1 1 -BHI * 22 2 R1 1 -BHS * 24 2 R1 1 -BITA #* 85 2 NOP 1 -BITA *,Y 18A5 3 NOP 4 -BITA *,X A5 2 NOP 1 -BITA * B5 3 MZERO 1 -BITB #* C5 2 NOP 1 -BITB *,Y 18E5 3 NOP 4 -BITB *,X E5 2 NOP 1 -BITB * F5 3 MZERO 1 -BLE * 2F 2 R1 1 -BLO * 25 2 R1 1 -BLS * 23 2 R1 1 -BLT * 2D 2 R1 1 -BMI * 2B 2 R1 1 -BNE * 26 2 R1 1 -BPL * 2A 2 R1 1 -BRA * 20 2 R1 1 -BRCLR *,X,*,* 1F 4 3REL 4 -BRCLR *,Y,*,* 181F 5 3REL 4 -BRCLR *,*,* 13 4 3REL 4 -BRN * 21 2 R1 2 /* NOT SURE ABOUT 6803 */ -BRSET *,X,*,* 1E 4 3REL 4 -BRSET *,Y,*,* 181E 5 3REL 4 -BRSET *,*,* 12 4 3REL 4 -BSET *,X,* 1C 3 COMB 4 -BSET *,Y,* 181C 4 COMB 4 -BSET *,#* 14 3 COMB 4 /* allow # -BSET *,* 14 3 COMB 4 -BSR * 8D 2 R1 1 -BVC * 28 2 R1 1 -BVS * 29 2 R1 1 -CBA "" 11 1 NOP 1 -CLC "" 0C 1 NOP 1 -CLI "" 0E 1 NOP 1 -CLR *,Y 186F 3 NOP 4 -CLR *,X 6F 2 NOP 1 -CLR * 7F 3 SWAP 1 -CLRA "" 4F 1 NOP 1 -CLRB "" 5F 1 NOP 1 -CLV "" 0A 1 NOP 1 -CMPA #* 81 2 NOP 1 -CMPA *,X A1 2 NOP 1 -CMPA *,Y 18A1 3 NOP 4 -CMPA * B1 3 MZERO 1 -CMPB #* C1 2 NOP 1 -CMPB *,Y 18E1 3 NOP 4 -CMPB *,X E1 2 NOP 1 -CMPB * F1 3 MZERO 1 -CMPD #* 1A83 4 SWAP 4 /* alias for CPD */ -CMPD *,X 1AA3 3 NOP 4 -CMPD *,Y CDA3 3 NOP 4 -CMPD * 1AB3 4 MZERO 4 -COM *,X 63 2 NOP 1 -COM *,Y 1863 3 NOP 4 -COM * 73 3 SWAP 1 -COMA "" 43 1 NOP 1 -COMB "" 53 1 NOP 1 -CPD #* 1A83 4 SWAP 4 -CPD *,X 1AA3 3 NOP 4 -CPD *,Y CDA3 3 NOP 4 -CPD * 1AB3 4 MZERO 4 -CPX #* 8C 3 SWAP 1 -CPX *,X AC 2 NOP 1 -CPX *,Y CDAC 3 NOP 4 -CPX * BC 3 MZERO 1 -CPY #* 188C 4 SWAP 4 -CPY *,Y 18AC 3 NOP 4 -CPY *,X 1AAC 3 NOP 4 -CPY * 18BC 4 MZERO 4 -DAA "" 19 1 NOP 1 -DEC *,Y 186A 3 NOP 4 -DEC *,X 6A 2 NOP 1 -DEC * 7A 3 SWAP 1 -DECA "" 4A 1 NOP 1 -DECB "" 5A 1 NOP 1 -DES "" 34 1 NOP 1 -DEX "" 09 1 NOP 1 -DEY "" 1809 2 NOP 4 -EORA #* 88 2 NOP 1 -EORA *,Y 18A8 3 NOP 4 -EORA *,X A8 2 NOP 1 -EORA * B8 3 MZERO 1 -EORB #* C8 2 NOP 1 -EORB *,Y 18E8 3 NOP 4 -EORB *,X E8 2 NOP 1 -EORB * F8 3 MZERO 1 -FDIV "" 03 1 NOP 4 -IDIV "" 02 1 NOP 4 -INC *,Y 186C 3 NOP 4 -INC *,X 6C 2 NOP 1 -INC * 7C 3 SWAP 1 -INCA "" 4C 1 NOP 1 -INCB "" 5C 1 NOP 1 -INS "" 31 1 NOP 1 -INX "" 08 1 NOP 1 -INY "" 1808 2 NOP 4 -JMP *,Y 186E 3 NOP 4 -JMP *,X 6E 2 NOP 1 -JMP * 7E 3 SWAP 1 -JSR *,Y 18AD 3 NOP 4 -JSR *,X AD 2 NOP 1 -JSR * BD 3 MZERO 1 - -LDAA #* 86 2 NOP 1 -LDAA *,Y 18A6 3 NOP 4 -LDAA *,X A6 2 NOP 1 -LDAA >* B6 3 SWAP 1 /* Force EXT mode */ -LDAA * B6 3 MZERO 1 - -LDAB #* C6 2 NOP 1 -LDAB *,Y 18E6 3 NOP 4 -LDAB *,X E6 2 NOP 1 -LDAB >* F6 3 SWAP 1 /* Force EXT mode */ -LDAB * F6 3 MZERO 1 - -LDD #* CC 3 SWAP 2 -LDD *,Y 18EC 3 NOP 4 -LDD *,X EC 2 NOP 2 -LDD >* FC 3 SWAP 2 /* Force EXT mode */ -LDD * FC 3 MZERO 2 - -LDS #* 8E 3 SWAP 1 -LDS *,Y 18AE 3 NOP 4 -LDS *,X AE 2 NOP 1 -LDS >* BE 3 SWAP 1 /* Force EXT mode */ -LDS * BE 3 MZERO 1 - -LDX #* CE 3 SWAP 1 -LDX *,X EE 2 NOP 1 -LDX *,Y CDEE 3 NOP 4 -LDX >* FE 3 SWAP 1 /* Force EXT mode */ -LDX * FE 3 MZERO 1 - -LDY #* 18CE 4 SWAP 4 -LDY *,Y 18EE 3 NOP 4 -LDY *,X 1AEE 3 NOP 4 -LDY >* 18FE 4 SWAP 4 /* Force EXT mode */ -LDY * 18FE 4 MZERO 4 - -LSL *,Y 1868 3 NOP 4 -LSL *,X 68 2 NOP 1 /*SAME AS ASL */ -LSL * 78 3 SWAP 1 -LSLA "" 48 1 NOP 1 -LSLB "" 58 1 NOP 1 -LSLD "" 05 1 NOP 2 -LSR *,Y 1864 3 NOP 4 -LSR *,X 64 2 NOP 1 -LSR * 74 3 SWAP 1 -LSRA "" 44 1 NOP 1 -LSRB "" 54 1 NOP 1 -LSRD "" 04 1 NOP 2 -MUL "" 3D 1 NOP 2 -NEG *,Y 1860 3 NOP 4 -NEG *,X 60 2 NOP 1 -NEG * 70 3 SWAP 1 -NEGA "" 40 1 NOP 1 -NEGB "" 50 1 NOP 1 -NOP "" 01 1 NOP 1 -ORAA #* 8A 2 NOP 1 -ORAA *,Y 18AA 3 NOP 4 -ORAA *,X AA 2 NOP 1 -ORAA * BA 3 MZERO 1 -ORAB #* CA 2 NOP 1 -ORAB *,Y 18EA 3 NOP 4 -ORAB *,X EA 2 NOP 1 -ORAB * FA 3 MZERO 1 -PSHA "" 36 1 NOP 1 -PSHB "" 37 1 NOP 1 -PSHX "" 3C 1 NOP 2 -PSHY "" 183C 2 NOP 4 -PULA "" 32 1 NOP 1 -PULB "" 33 1 NOP 1 -PULX "" 38 1 NOP 2 -PULY "" 1838 2 NOP 4 -ROL *,Y 1869 3 NOP 4 -ROL *,X 69 2 NOP 1 -ROL * 79 3 SWAP 1 -ROLA "" 49 1 NOP 1 -ROLB "" 59 1 NOP 1 -ROR *,Y 1866 3 NOP 4 -ROR *,X 66 2 NOP 1 -ROR * 76 3 SWAP 1 -RORA "" 46 1 NOP 1 -RORB "" 56 1 NOP 1 -RTI "" 3B 1 NOP 1 -RTS "" 39 1 NOP 1 -SBA "" 10 1 NOP 1 -SBCA #* 82 2 NOP 1 -SBCA *,Y 18A2 3 NOP 4 -SBCA *,X A2 2 NOP 1 -SBCA * B2 3 MZERO 1 -SBCB #* C2 2 NOP 1 -SBCB *,Y 18E2 3 NOP 4 -SBCB *,X E2 2 NOP 1 -SBCB * F2 3 MZERO 1 -SEC "" 0D 1 NOP 1 -SEI "" 0F 1 NOP 1 -SEV "" 0B 1 NOP 1 - -STAA *,Y 18A7 3 NOP 4 -STAA *,X A7 2 NOP 1 -STAA >* B7 3 SWAP 1 /* Force EXT mode */ -STAA * B7 3 MZERO 1 - -STAB *,Y 18E7 3 NOP 4 -STAB *,X E7 2 NOP 1 -STAB >* F7 3 SWAP 1 /* Force EXT mode */ -STAB * F7 3 MZERO 1 - -STD *,Y 18ED 3 NOP 4 -STD *,X ED 2 NOP 2 -STD >* FD 3 SWAP 2 /* Force EXT mode */ -STD * FD 3 MZERO 2 - -STOP "" CF 1 NOP 1 - -STS *,X AF 2 NOP 1 -STS *,Y 18AF 3 NOP 4 -STS >* BF 3 SWAP 1 /* Force EXT mode */ -STS * BF 3 MZERO 1 - -STX *,X EF 2 NOP 1 -STX *,Y CDEF 3 NOP 4 -STX >* FF 3 SWAP 1 /* Force EXT mode */ -STX * FF 3 MZERO 1 - -STY *,Y 18EF 3 NOP 4 -STY *,X 1AEF 3 NOP 4 -STY >* 18FF 4 SWAP 4 /* Force EXT mode */ -STY * 18FF 4 MZERO 4 - -SUBA #* 80 2 NOP 1 -SUBA *,Y 18A0 3 NOP 4 -SUBA *,X A0 2 NOP 1 -SUBA * B0 3 MZERO 1 - -SUBB #* C0 2 NOP 1 -SUBB *,Y 18E0 3 NOP 4 -SUBB *,X E0 2 NOP 1 -SUBB * F0 3 MZERO 1 - -SUBD #* 83 3 SWAP 2 -SUBD *,Y 18A3 3 NOP 4 -SUBD *,X A3 2 NOP 2 -SUBD * B3 3 MZERO 2 - -SWI "" 3F 1 NOP 1 -TAB "" 16 1 NOP 1 -TAP "" 06 1 NOP 1 -TBA "" 17 1 NOP 1 -TEST "" 00 1 NOP 1 -TPA "" 07 1 NOP 1 -TST *,Y 186D 3 NOP 4 -TST *,X 6D 2 NOP 1 -TST * 7D 3 SWAP 1 -TSTA "" 4D 1 NOP 1 -TSTB "" 5D 1 NOP 1 -TSX "" 30 1 NOP 1 -TSY "" 1830 2 NOP 4 -TXS "" 35 1 NOP 1 -TYS "" 1835 2 NOP 4 -WAI "" 3E 1 NOP 1 -XGDX "" 8F 1 NOP 4 -XGDY "" 188F 2 NOP 4 -/* That's all folks */ - diff --git a/branches/s100/Tools/tasm32/TASM70.TAB b/branches/s100/Tools/tasm32/TASM70.TAB deleted file mode 100644 index 7f8cf218..00000000 --- a/branches/s100/Tools/tasm32/TASM70.TAB +++ /dev/null @@ -1,290 +0,0 @@ -"TASM 7000 Assembler. " -/**************************************************************************** -/* $Id: tasm70.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* Table for TMS7000 micros -/* Note that the table does not require the 'Rnn' nomenclature -/* for reference of locations in the register file. Any expression -/* will do, the value of which indicates the register. This is more -/* flexible then making an entry like "ADC R*,A". -/* -/* TASM has trouble with the MOVD +(B),+ instruction so -/* we convert it to MOVD +[B],+ -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -.ALTWILD+ - -ADC B,A 69 1 NOP 1 -ADC %+,A 29 2 NOP 1 -ADC %+,B 59 2 NOP 1 -ADC %+,+ 79 3 COMB 1 -ADC +,A 19 2 NOP 1 -ADC +,B 39 2 NOP 1 -ADC +,+ 49 3 COMB 1 - -ADD B,A 68 1 NOP 1 -ADD %+,A 28 2 NOP 1 -ADD %+,B 58 2 NOP 1 -ADD %+,+ 78 3 COMB 1 -ADD +,A 18 2 NOP 1 -ADD +,B 38 2 NOP 1 -ADD +,+ 48 3 COMB 1 - -AND B,A 63 1 NOP 1 -AND %+,A 23 2 NOP 1 -AND %+,B 53 2 NOP 1 -AND %+,+ 73 3 COMB 1 -AND +,A 13 2 NOP 1 -AND +,B 33 2 NOP 1 -AND +,+ 43 3 COMB 1 - -ANDP A,+ 83 2 NOP 1 -ANDP B,+ 93 2 NOP 1 -ANDP %+,+ A3 3 COMB 1 - -BTJO B,A,+ 66 2 R1 1 -BTJO %+,A,+ 26 3 CREL 1 -BTJO %+,B,+ 56 3 CREL 1 -BTJO %+,+,+ 76 4 3REL 1 -BTJO +,A,+ 16 3 CREL 1 -BTJO +,B,+ 36 3 CREL 1 -BTJO +,+,+ 46 4 3REL 1 - - -BTJOP A,+,+ 86 3 CREL 1 -BTJOP B,+,+ 96 3 CREL 1 -BTJOP %+,+,+ A6 4 3REL 1 - -BTJZ B,A,+ 67 2 R1 1 -BTJZ %+,A,+ 27 3 CREL 1 -BTJZ %+,B,+ 57 3 CREL 1 -BTJZ %+,+,+ 77 4 3REL 1 -BTJZ +,A,+ 17 3 CREL 1 -BTJZ +,B,+ 37 3 CREL 1 -BTJZ +,+,+ 47 4 3REL 1 - -BTJZP A,+,+ 87 3 CREL 1 -BTJZP B,+,+ 97 3 CREL 1 -BTJZP %+,+,+ A7 4 3REL 1 - -BR @+(B) AC 3 SWAP 1 -BR @+[B] AC 3 SWAP 1 -BR @+ 8C 3 SWAP 1 -BR *+ 9C 2 NOP 1 - -CALL @+(B) AE 3 SWAP 1 -CALL @+[B] AE 3 SWAP 1 -CALL @+ 8E 3 SWAP 1 -CALL *+ 9E 2 NOP 1 - -CLR A B5 1 NOP 1 -CLR B C5 1 NOP 1 -CLR + D5 2 NOP 1 - -CLRC "" B0 1 NOP 1 - -CMP B,A 6D 1 NOP 1 -CMP %+,A 2D 2 NOP 1 -CMP %+,B 5D 2 NOP 1 -CMP %+,+ 7D 3 COMB 1 -CMP +,A 1D 2 NOP 1 -CMP +,B 3D 2 NOP 1 -CMP +,+ 4D 3 COMB 1 - -CMPA @+(B) AD 3 SWAP 1 -CMPA @+[B] AD 3 SWAP 1 -CMPA @+ 8D 3 SWAP 1 -CMPA *+ 9D 2 NOP 1 - -DAC B,A 6E 1 NOP 1 -DAC %+,A 2E 2 NOP 1 -DAC %+,B 5E 2 NOP 1 -DAC %+,+ 7E 3 COMB 1 -DAC +,A 1E 2 NOP 1 -DAC +,B 3E 2 NOP 1 -DAC +,+ 4E 3 COMB 1 - -DEC A B2 1 NOP 1 -DEC B C2 1 NOP 1 -DEC + D2 2 NOP 1 - -DECD A BB 1 NOP 1 -DECD B CB 1 NOP 1 -DECD + DB 2 NOP 1 - -DINT "" 06 1 NOP 1 - -DJNZ A,+ BA 2 R1 1 -DJNZ B,+ CA 2 R1 1 -DJNZ +,+ DA 3 CREL 1 - -DSB B,A 6F 1 NOP 1 -DSB %+,A 2F 2 NOP 1 -DSB %+,B 5F 2 NOP 1 -DSB %+,+ 7F 3 COMB 1 -DSB +,A 1F 2 NOP 1 -DSB +,B 3F 2 NOP 1 -DSB +,+ 4F 3 COMB 1 - -EINT "" 05 1 NOP 1 - -IDLE "" 01 1 NOP 1 - -INC A B3 1 NOP 1 -INC B C3 1 NOP 1 -INC + D3 2 NOP 1 - -INV A B4 1 NOP 1 -INV B C4 1 NOP 1 -INV + D4 2 NOP 1 - -JMP + E0 2 R1 1 - -JC + E3 2 R1 1 -JEQ + E2 2 R1 1 -JGE + E5 2 R1 1 -JGT + E4 2 R1 1 -JHS + E3 2 R1 1 -JL + E7 2 R1 1 -JN + E1 2 R1 1 /+ ?? -JNC + E7 2 R1 1 -JNE + E6 2 R1 1 -JNZ + E6 2 R1 1 -JP + E4 2 R1 1 -JPZ + E5 2 R1 1 -JZ + E2 2 R1 1 - -LDA @+(B) AA 3 SWAP 1 -LDA @+[B] AA 3 SWAP 1 -LDA @+ 8A 3 SWAP 1 -LDA *+ 9A 2 NOP 1 - -LDSP "" 0D 1 NOP 1 - -MOV A,B C0 1 NOP 1 -MOV B,A 62 1 NOP 1 -MOV A,+ D0 2 NOP 1 -MOV B,+ D1 2 NOP 1 -MOV %+,A 22 2 NOP 1 -MOV %+,B 52 2 NOP 1 -MOV %+,+ 72 3 COMB 1 -MOV +,A 12 2 NOP 1 -MOV +,B 32 2 NOP 1 -MOV +,+ 42 3 COMB 1 - -MOVD %+[B],+ A8 4 CSWAP 1 -MOVD %+,+ 88 4 CSWAP 1 -MOVD +,+ 98 3 COMB 1 - -MOVP A,+ 82 2 NOP 1 -MOVP B,+ 92 2 NOP 1 -MOVP %+,+ A2 3 COMB 1 -MOVP +,A 80 2 NOP 1 -MOVP +,B 91 2 NOP 1 - -MPY B,A 6C 1 NOP 1 -MPY %+,A 2C 2 NOP 1 -MPY %+,B 5C 2 NOP 1 -MPY %+,+ 7C 3 COMB 1 -MPY +,A 1C 2 NOP 1 -MPY +,B 3C 2 NOP 1 -MPY +,+ 4C 3 COMB 1 - -NOP "" 00 1 NOP 1 - -OR B,A 64 1 NOP 1 -OR %+,A 24 2 NOP 1 -OR %+,B 54 2 NOP 1 -OR %+,+ 74 3 COMB 1 -OR +,A 14 2 NOP 1 -OR +,B 34 2 NOP 1 -OR +,+ 44 3 COMB 1 - -ORP A,+ 84 2 NOP 1 -ORP B,+ 94 2 NOP 1 -ORP %+,+ A4 3 COMB 1 - -POP A B9 1 NOP 1 -POP B C9 1 NOP 1 -POP ST 08 1 NOP 1 -POP + D9 2 NOP 1 -POPST "" 08 1 NOP 1 - -PUSH A B8 1 NOP 1 -PUSH B C8 1 NOP 1 -PUSH ST 0E 1 NOP 1 -PUSH + D8 2 NOP 1 -PUSHST "" 0E 1 NOP 1 - -RETI "" 0B 1 NOP 1 - -RETS "" 0A 1 NOP 1 - -RL A BE 1 NOP 1 -RL B CE 1 NOP 1 -RL + DE 2 NOP 1 - -RLC A BF 1 NOP 1 -RLC B CF 1 NOP 1 -RLC + DF 2 NOP 1 - -RR A BC 1 NOP 1 -RR B CC 1 NOP 1 -RR + DC 2 NOP 1 - -RRC A BD 1 NOP 1 -RRC B CD 1 NOP 1 -RRC + DD 2 NOP 1 - -SBB B,A 6B 1 NOP 1 -SBB %+,A 2B 2 NOP 1 -SBB %+,B 5B 2 NOP 1 -SBB %+,+ 7B 3 COMB 1 -SBB +,A 1B 2 NOP 1 -SBB +,B 3B 2 NOP 1 -SBB +,+ 4B 3 COMB 1 - -SETC "" 07 1 NOP 1 - -STA @+(B) AB 3 SWAP 1 -STA @+[B] AB 3 SWAP 1 -STA @+ 8B 3 SWAP 1 -STA *+ 9B 2 NOP 1 - -STSP "" 09 1 NOP 1 - -SUB B,A 6A 1 NOP 1 -SUB %+,A 2A 2 NOP 1 -SUB %+,B 5A 2 NOP 1 -SUB %+,+ 7A 3 COMB 1 -SUB +,A 1A 2 NOP 1 -SUB +,B 3A 2 NOP 1 -SUB +,+ 4A 3 COMB 1 - -SWAP A B7 1 NOP 1 -SWAP B C7 1 NOP 1 -SWAP + D7 2 NOP 1 - -TRAP + FF 1 SUB 1 - -TST A B0 1 NOP 1 -TSTA "" B0 1 NOP 1 -TST B C1 1 NOP 1 -TSTB "" C1 1 NOP 1 - -XCHB A B6 1 NOP 1 -XCHB + D6 2 NOP 1 - -XOR B,A 65 1 NOP 1 -XOR %+,A 25 2 NOP 1 -XOR %+,B 55 2 NOP 1 -XOR %+,+ 75 3 COMB 1 -XOR +,A 15 2 NOP 1 -XOR +,B 35 2 NOP 1 -XOR +,+ 45 3 COMB 1 - -XORP A,+ 85 2 NOP 1 -XORP B,+ 95 2 NOP 1 -XORP %+,+ A5 3 COMB 1 - diff --git a/branches/s100/Tools/tasm32/TASM80.TAB b/branches/s100/Tools/tasm32/TASM80.TAB deleted file mode 100644 index 058fa145..00000000 --- a/branches/s100/Tools/tasm32/TASM80.TAB +++ /dev/null @@ -1,594 +0,0 @@ -"TASM Z80 Assembler. " -/**************************************************************************** -/* $Id: tasm80.tab 1.2 1998/02/28 14:31:22 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the Z80 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Carl A. Wall, VE3APY. -/* -/* Class bits assigned as follows: -/* Bit-0 = Z80 (base instruction set) -/* Bit-1 = HD64180 (extended instructions) -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OP BYTES RULE CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC A,(HL) 8E 1 NOP 1 -ADC A,(IX*) 8EDD 3 ZIX 1 -ADC A,(IY*) 8EFD 3 ZIX 1 -ADC A,A 8F 1 NOP 1 -ADC A,B 88 1 NOP 1 -ADC A,C 89 1 NOP 1 -ADC A,D 8A 1 NOP 1 -ADC A,E 8B 1 NOP 1 -ADC A,H 8C 1 NOP 1 -ADC A,L 8D 1 NOP 1 -ADC A,* CE 2 NOP 1 -ADC HL,BC 4AED 2 NOP 1 -ADC HL,DE 5AED 2 NOP 1 -ADC HL,HL 6AED 2 NOP 1 -ADC HL,SP 7AED 2 NOP 1 - -ADD A,(HL) 86 1 NOP 1 -ADD A,(IX*) 86DD 3 ZIX 1 -ADD A,(IY*) 86FD 3 ZIX 1 -ADD A,A 87 1 NOP 1 -ADD A,B 80 1 NOP 1 -ADD A,C 81 1 NOP 1 -ADD A,D 82 1 NOP 1 -ADD A,E 83 1 NOP 1 -ADD A,H 84 1 NOP 1 -ADD A,L 85 1 NOP 1 -ADD A,* C6 2 NOP 1 -ADD HL,BC 09 1 NOP 1 -ADD HL,DE 19 1 NOP 1 -ADD HL,HL 29 1 NOP 1 -ADD HL,SP 39 1 NOP 1 -ADD IX,BC 09DD 2 NOP 1 -ADD IX,DE 19DD 2 NOP 1 -ADD IX,IX 29DD 2 NOP 1 -ADD IX,SP 39DD 2 NOP 1 -ADD IY,BC 09FD 2 NOP 1 -ADD IY,DE 19FD 2 NOP 1 -ADD IY,IY 29FD 2 NOP 1 -ADD IY,SP 39FD 2 NOP 1 - -AND (HL) A6 1 NOP 1 -AND (IX*) A6DD 3 ZIX 1 -AND (IY*) A6FD 3 ZIX 1 -AND A A7 1 NOP 1 -AND B A0 1 NOP 1 -AND C A1 1 NOP 1 -AND D A2 1 NOP 1 -AND E A3 1 NOP 1 -AND H A4 1 NOP 1 -AND L A5 1 NOP 1 -AND * E6 2 NOP 1 - -BIT *,(HL) 46CB 2 ZBIT 1 -BIT *,(IX*) CBDD 4 ZBIT 1 0 4600 -BIT *,(IY*) CBFD 4 ZBIT 1 0 4600 -BIT *,A 47CB 2 ZBIT 1 -BIT *,B 40CB 2 ZBIT 1 -BIT *,C 41CB 2 ZBIT 1 -BIT *,D 42CB 2 ZBIT 1 -BIT *,E 43CB 2 ZBIT 1 -BIT *,H 44CB 2 ZBIT 1 -BIT *,L 45CB 2 ZBIT 1 - -CALL C,* DC 3 NOP 1 -CALL M,* FC 3 NOP 1 -CALL NC,* D4 3 NOP 1 -CALL NZ,* C4 3 NOP 1 -CALL P,* F4 3 NOP 1 -CALL PE,* EC 3 NOP 1 -CALL PO,* E4 3 NOP 1 -CALL Z,* CC 3 NOP 1 -CALL * CD 3 NOP 1 - -CCF "" 3F 1 NOP 1 - -CP (HL) BE 1 NOP 1 -CP (IX*) BEDD 3 ZIX 1 -CP (IY*) BEFD 3 ZIX 1 -CP A BF 1 NOP 1 -CP B B8 1 NOP 1 -CP C B9 1 NOP 1 -CP D BA 1 NOP 1 -CP E BB 1 NOP 1 -CP H BC 1 NOP 1 -CP L BD 1 NOP 1 -CP * FE 2 NOP 1 -CPD "" A9ED 2 NOP 1 -CPDR "" B9ED 2 NOP 1 -CPIR "" B1ED 2 NOP 1 -CPI "" A1ED 2 NOP 1 -CPL "" 2F 1 NOP 1 - -DAA "" 27 1 NOP 1 - -DEC (HL) 35 1 NOP 1 -DEC (IX*) 35DD 3 ZIX 1 -DEC (IY*) 35FD 3 ZIX 1 -DEC A 3D 1 NOP 1 -DEC B 05 1 NOP 1 -DEC BC 0B 1 NOP 1 -DEC C 0D 1 NOP 1 -DEC D 15 1 NOP 1 -DEC DE 1B 1 NOP 1 -DEC E 1D 1 NOP 1 -DEC H 25 1 NOP 1 -DEC HL 2B 1 NOP 1 -DEC IX 2BDD 2 NOP 1 -DEC IY 2BFD 2 NOP 1 -DEC L 2D 1 NOP 1 -DEC SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -DJNZ * 10 2 R1 1 - -EI "" FB 1 NOP 1 -EX (SP),HL E3 1 NOP 1 -EX (SP),IX E3DD 2 NOP 1 -EX (SP),IY E3FD 2 NOP 1 -EX AF,AF' 08 1 NOP 1 -EX DE,HL EB 1 NOP 1 -EXX "" D9 1 NOP 1 -HALT "" 76 1 NOP 1 - -IM 0 46ED 2 NOP 1 -IM 1 56ED 2 NOP 1 -IM 2 5EED 2 NOP 1 - -/* Alternate form of above -IM0 46ED 2 NOP 1 -IM1 56ED 2 NOP 1 -IM2 5EED 2 NOP 1 - -IN A,(C) 78ED 2 NOP 1 -IN B,(C) 40ED 2 NOP 1 -IN C,(C) 48ED 2 NOP 1 -IN D,(C) 50ED 2 NOP 1 -IN E,(C) 58ED 2 NOP 1 -IN H,(C) 60ED 2 NOP 1 -IN L,(C) 68ED 2 NOP 1 - -IN A,(*) DB 2 NOP 1 - -IN0 A,(*) 38ED 3 NOP 2 -IN0 B,(*) 00ED 3 NOP 2 -IN0 C,(*) 08ED 3 NOP 2 -IN0 D,(*) 10ED 3 NOP 2 -IN0 E,(*) 18ED 3 NOP 2 -IN0 H,(*) 20ED 3 NOP 2 -IN0 L,(*) 28ED 3 NOP 2 - -INC (HL) 34 1 NOP 1 -INC (IX*) 34DD 3 ZIX 1 -INC (IY*) 34FD 3 ZIX 1 -INC A 3C 1 NOP 1 -INC B 04 1 NOP 1 -INC BC 03 1 NOP 1 -INC C 0C 1 NOP 1 -INC D 14 1 NOP 1 -INC DE 13 1 NOP 1 -INC E 1C 1 NOP 1 -INC H 24 1 NOP 1 -INC HL 23 1 NOP 1 -INC IX 23DD 2 NOP 1 -INC IY 23FD 2 NOP 1 -INC L 2C 1 NOP 1 -INC SP 33 1 NOP 1 - - -IND "" AAED 2 NOP 1 -INDR "" BAED 2 NOP 1 -INI "" A2ED 2 NOP 1 -INIR "" B2ED 2 NOP 1 - -JP (HL) E9 1 NOP 1 -JP (IX) E9DD 2 NOP 1 -JP (IY) E9FD 2 NOP 1 -JP C,* DA 3 NOP 1 -JP M,* FA 3 NOP 1 -JP NC,* D2 3 NOP 1 -JP NZ,* C2 3 NOP 1 -JP P,* F2 3 NOP 1 -JP PE,* EA 3 NOP 1 -JP PO,* E2 3 NOP 1 -JP Z,* CA 3 NOP 1 -JP * C3 3 NOP 1 - -JR C,* 38 2 R1 1 -JR NC,* 30 2 R1 1 -JR NZ,* 20 2 R1 1 -JR Z,* 28 2 R1 1 -JR * 18 2 R1 1 - -LD (BC),A 02 1 NOP 1 -LD (DE),A 12 1 NOP 1 -LD (HL),A 77 1 NOP 1 -LD (HL),B 70 1 NOP 1 -LD (HL),C 71 1 NOP 1 -LD (HL),D 72 1 NOP 1 -LD (HL),E 73 1 NOP 1 -LD (HL),H 74 1 NOP 1 -LD (HL),L 75 1 NOP 1 -LD (HL),* 36 2 NOP 1 -LD (IX*),A 77DD 3 ZIX 1 -LD (IX*),B 70DD 3 ZIX 1 -LD (IX*),C 71DD 3 ZIX 1 -LD (IX*),D 72DD 3 ZIX 1 -LD (IX*),E 73DD 3 ZIX 1 -LD (IX*),H 74DD 3 ZIX 1 -LD (IX*),L 75DD 3 ZIX 1 -LD (IX*),* 36DD 4 ZIX 1 -LD (IY*),A 77FD 3 ZIX 1 -LD (IY*),B 70FD 3 ZIX 1 -LD (IY*),C 71FD 3 ZIX 1 -LD (IY*),D 72FD 3 ZIX 1 -LD (IY*),E 73FD 3 ZIX 1 -LD (IY*),H 74FD 3 ZIX 1 -LD (IY*),L 75FD 3 ZIX 1 -LD (IY*),* 36FD 4 ZIX 1 -LD (*),A 32 3 NOP 1 -LD (*),BC 43ED 4 NOP 1 -LD (*),DE 53ED 4 NOP 1 -LD (*),HL 22 3 NOP 1 -LD (*),IX 22DD 4 NOP 1 -LD (*),IY 22FD 4 NOP 1 -LD (*),SP 73ED 4 NOP 1 -LD A,(BC) 0A 1 NOP 1 -LD A,(DE) 1A 1 NOP 1 -LD A,(HL) 7E 1 NOP 1 -LD A,(IX*) 7EDD 3 ZIX 1 -LD A,(IY*) 7EFD 3 ZIX 1 -LD A,A 7F 1 NOP 1 -LD A,B 78 1 NOP 1 -LD A,C 79 1 NOP 1 -LD A,D 7A 1 NOP 1 -LD A,E 7B 1 NOP 1 -LD A,H 7C 1 NOP 1 -LD A,I 57ED 2 NOP 1 -LD A,L 7D 1 NOP 1 -LD A,R 5FED 2 NOP 1 -LD A,(*) 3A 3 NOP 1 -LD A,* 3E 2 NOP 1 -LD B,(HL) 46 1 NOP 1 -LD B,(IX*) 46DD 3 ZIX 1 -LD B,(IY*) 46FD 3 ZIX 1 -LD B,A 47 1 NOP 1 -LD B,B 40 1 NOP 1 -LD B,C 41 1 NOP 1 -LD B,D 42 1 NOP 1 -LD B,E 43 1 NOP 1 -LD B,H 44 1 NOP 1 -LD B,L 45 1 NOP 1 -LD B,* 06 2 NOP 1 -LD BC,(*) 4BED 4 NOP 1 -LD BC,* 01 3 NOP 1 -LD C,(HL) 4E 1 NOP 1 -LD C,(IX*) 4EDD 3 ZIX 1 -LD C,(IY*) 4EFD 3 ZIX 1 -LD C,A 4F 1 NOP 1 -LD C,B 48 1 NOP 1 -LD C,C 49 1 NOP 1 -LD C,D 4A 1 NOP 1 -LD C,E 4B 1 NOP 1 -LD C,H 4C 1 NOP 1 -LD C,L 4D 1 NOP 1 -LD C,* 0E 2 NOP 1 -LD D,(HL) 56 1 NOP 1 -LD D,(IX*) 56DD 3 ZIX 1 -LD D,(IY*) 56FD 3 ZIX 1 -LD D,A 57 1 NOP 1 -LD D,B 50 1 NOP 1 -LD D,C 51 1 NOP 1 -LD D,D 52 1 NOP 1 -LD D,E 53 1 NOP 1 -LD D,H 54 1 NOP 1 -LD D,L 55 1 NOP 1 -LD D,* 16 2 NOP 1 -LD DE,(*) 5BED 4 NOP 1 -LD DE,* 11 3 NOP 1 -LD E,(HL) 5E 1 NOP 1 -LD E,(IX*) 5EDD 3 ZIX 1 -LD E,(IY*) 5EFD 3 ZIX 1 -LD E,A 5F 1 NOP 1 -LD E,B 58 1 NOP 1 -LD E,C 59 1 NOP 1 -LD E,D 5A 1 NOP 1 -LD E,E 5B 1 NOP 1 -LD E,H 5C 1 NOP 1 -LD E,L 5D 1 NOP 1 -LD E,* 1E 2 NOP 1 -LD H,(HL) 66 1 NOP 1 -LD H,(IX*) 66DD 3 ZIX 1 -LD H,(IY*) 66FD 3 ZIX 1 -LD H,A 67 1 NOP 1 -LD H,B 60 1 NOP 1 -LD H,C 61 1 NOP 1 -LD H,D 62 1 NOP 1 -LD H,E 63 1 NOP 1 -LD H,H 64 1 NOP 1 -LD H,L 65 1 NOP 1 -LD H,* 26 2 NOP 1 -LD HL,(*) 2A 3 NOP 1 -LD HL,* 21 3 NOP 1 -LD I,A 47ED 2 NOP 1 -LD IX,(*) 2ADD 4 NOP 1 -LD IX,* 21DD 4 NOP 1 -LD IY,(*) 2AFD 4 NOP 1 -LD IY,* 21FD 4 NOP 1 -LD L,(HL) 6E 1 NOP 1 -LD L,(IX*) 6EDD 3 ZIX 1 -LD L,(IY*) 6EFD 3 ZIX 1 -LD L,A 6F 1 NOP 1 -LD L,B 68 1 NOP 1 -LD L,C 69 1 NOP 1 -LD L,D 6A 1 NOP 1 -LD L,E 6B 1 NOP 1 -LD L,H 6C 1 NOP 1 -LD L,L 6D 1 NOP 1 -LD L,* 2E 2 NOP 1 -LD R,A 4FED 2 NOP 1 -LD SP,(*) 7BED 4 NOP 1 -LD SP,HL F9 1 NOP 1 -LD SP,IX F9DD 2 NOP 1 -LD SP,IY F9FD 2 NOP 1 -LD SP,* 31 3 NOP 1 -LDD "" A8ED 2 NOP 1 -LDDR "" B8ED 2 NOP 1 -LDI "" A0ED 2 NOP 1 -LDIR "" B0ED 2 NOP 1 -NEG "" 44ED 2 NOP 1 -NOP "" 00 1 NOP 1 - -MLT BC 4CED 2 NOP 2 -MLT DE 5CED 2 NOP 2 -MLT HL 6CED 2 NOP 2 -MLT SP 7CED 2 NOP 2 - -OR (HL) B6 1 NOP 1 -OR (IX*) B6DD 3 ZIX 1 -OR (IY*) B6FD 3 ZIX 1 -OR A B7 1 NOP 1 -OR B B0 1 NOP 1 -OR C B1 1 NOP 1 -OR D B2 1 NOP 1 -OR E B3 1 NOP 1 -OR H B4 1 NOP 1 -OR L B5 1 NOP 1 -OR * F6 2 NOP 1 - -OTDM "" 8BED 2 NOP 2 -OTDMR "" 9BED 2 NOP 2 -OTDR "" BBED 2 NOP 1 -OTIM "" 83ED 2 NOP 2 -OTIMR "" 93ED 2 NOP 2 -OTIR "" B3ED 2 NOP 1 - -OUT (C),A 79ED 2 NOP 1 -OUT (C),B 41ED 2 NOP 1 -OUT (C),C 49ED 2 NOP 1 -OUT (C),D 51ED 2 NOP 1 -OUT (C),E 59ED 2 NOP 1 -OUT (C),H 61ED 2 NOP 1 -OUT (C),L 69ED 2 NOP 1 -OUT (*),A D3 2 NOP 1 - -OUT0 (*),A 39ED 3 NOP 2 -OUT0 (*),B 01ED 3 NOP 2 -OUT0 (*),C 09ED 3 NOP 2 -OUT0 (*),D 11ED 3 NOP 2 -OUT0 (*),E 19ED 3 NOP 2 -OUT0 (*),H 21ED 3 NOP 2 -OUT0 (*),L 29ED 3 NOP 2 - -OUTD "" ABED 2 NOP 1 -OUTI "" A3ED 2 NOP 1 - -POP AF F1 1 NOP 1 -POP BC C1 1 NOP 1 -POP DE D1 1 NOP 1 -POP HL E1 1 NOP 1 -POP IX E1DD 2 NOP 1 -POP IY E1FD 2 NOP 1 - -PUSH AF F5 1 NOP 1 -PUSH BC C5 1 NOP 1 -PUSH DE D5 1 NOP 1 -PUSH HL E5 1 NOP 1 -PUSH IX E5DD 2 NOP 1 -PUSH IY E5FD 2 NOP 1 - -RES *,(HL) 86CB 2 ZBIT 1 -RES *,(IX*) CBDD 4 ZBIT 1 0 8600 -RES *,(IY*) CBFD 4 ZBIT 1 0 8600 -RES *,A 87CB 2 ZBIT 1 -RES *,B 80CB 2 ZBIT 1 -RES *,C 81CB 2 ZBIT 1 -RES *,D 82CB 2 ZBIT 1 -RES *,E 83CB 2 ZBIT 1 -RES *,H 84CB 2 ZBIT 1 -RES *,L 85CB 2 ZBIT 1 - -RET "" C9 1 NOP 1 -RET C D8 1 NOP 1 -RET M F8 1 NOP 1 -RET NC D0 1 NOP 1 -RET NZ C0 1 NOP 1 -RET P F0 1 NOP 1 -RET PE E8 1 NOP 1 -RET PO E0 1 NOP 1 -RET Z C8 1 NOP 1 -RETI "" 4DED 2 NOP 1 -RETN "" 45ED 2 NOP 1 - -RL (HL) 16CB 2 NOP 1 -RL (IX*) CBDD 4 ZIX 1 0 1600 -RL (IY*) CBFD 4 ZIX 1 0 1600 -RL A 17CB 2 NOP 1 -RL B 10CB 2 NOP 1 -RL C 11CB 2 NOP 1 -RL D 12CB 2 NOP 1 -RL E 13CB 2 NOP 1 -RL H 14CB 2 NOP 1 -RL L 15CB 2 NOP 1 -RLA "" 17 1 NOP 1 - -RLC (HL) 06CB 2 NOP 1 -RLC (IX*) CBDD 4 ZIX 1 0 0600 -RLC (IY*) CBFD 4 ZIX 1 0 0600 -RLC A 07CB 2 NOP 1 -RLC B 00CB 2 NOP 1 -RLC C 01CB 2 NOP 1 -RLC D 02CB 2 NOP 1 -RLC E 03CB 2 NOP 1 -RLC H 04CB 2 NOP 1 -RLC L 05CB 2 NOP 1 -RLCA "" 07 1 NOP 1 -RLD "" 6FED 2 NOP 1 - -RR (HL) 1ECB 2 NOP 1 -RR (IX*) CBDD 4 ZIX 1 0 1E00 -RR (IY*) CBFD 4 ZIX 1 0 1E00 -RR A 1FCB 2 NOP 1 -RR B 18CB 2 NOP 1 -RR C 19CB 2 NOP 1 -RR D 1ACB 2 NOP 1 -RR E 1BCB 2 NOP 1 -RR H 1CCB 2 NOP 1 -RR L 1DCB 2 NOP 1 -RRA "" 1F 1 NOP 1 -RRC (HL) 0ECB 2 NOP 1 -RRC (IX*) CBDD 4 ZIX 1 0 0E00 -RRC (IY*) CBFD 4 ZIX 1 0 0E00 -RRC A 0FCB 2 NOP 1 -RRC B 08CB 2 NOP 1 -RRC C 09CB 2 NOP 1 -RRC D 0ACB 2 NOP 1 -RRC E 0BCB 2 NOP 1 -RRC H 0CCB 2 NOP 1 -RRC L 0DCB 2 NOP 1 -RRCA "" 0F 1 NOP 1 -RRD "" 67ED 2 NOP 1 - -RST 00H C7 1 NOP 1 -RST 08H CF 1 NOP 1 -RST 10H D7 1 NOP 1 -RST 18H DF 1 NOP 1 -RST 20H E7 1 NOP 1 -RST 28H EF 1 NOP 1 -RST 30H F7 1 NOP 1 -RST 38H FF 1 NOP 1 - -/* Alternate form of above -RST 00 C7 1 NOP 1 -RST 08 CF 1 NOP 1 -RST 10 D7 1 NOP 1 -RST 18 DF 1 NOP 1 -RST 20 E7 1 NOP 1 -RST 28 EF 1 NOP 1 -RST 30 F7 1 NOP 1 -RST 38 FF 1 NOP 1 - -SBC A,(HL) 9E 1 NOP 1 -SBC A,(IX*) 9EDD 3 ZIX 1 -SBC A,(IY*) 9EFD 3 ZIX 1 -SBC A,A 9F 1 NOP 1 -SBC A,B 98 1 NOP 1 -SBC A,C 99 1 NOP 1 -SBC A,D 9A 1 NOP 1 -SBC A,E 9B 1 NOP 1 -SBC A,H 9C 1 NOP 1 -SBC A,L 9D 1 NOP 1 -SBC HL,BC 42ED 2 NOP 1 -SBC HL,DE 52ED 2 NOP 1 -SBC HL,HL 62ED 2 NOP 1 -SBC HL,SP 72ED 2 NOP 1 -SBC A,* DE 2 NOP 1 -SCF "" 37 1 NOP 1 - -SET *,(HL) C6CB 2 ZBIT 1 -SET *,(IX*) CBDD 4 ZBIT 1 0 C600 -SET *,(IY*) CBFD 4 ZBIT 1 0 C600 -SET *,A C7CB 2 ZBIT 1 -SET *,B C0CB 2 ZBIT 1 -SET *,C C1CB 2 ZBIT 1 -SET *,D C2CB 2 ZBIT 1 -SET *,E C3CB 2 ZBIT 1 -SET *,H C4CB 2 ZBIT 1 -SET *,L C5CB 2 ZBIT 1 - -SLA (HL) 26CB 2 NOP 1 -SLA (IX*) CBDD 4 ZIX 1 0 2600 -SLA (IY*) CBFD 4 ZIX 1 0 2600 -SLA A 27CB 2 NOP 1 -SLA B 20CB 2 NOP 1 -SLA C 21CB 2 NOP 1 -SLA D 22CB 2 NOP 1 -SLA E 23CB 2 NOP 1 -SLA H 24CB 2 NOP 1 -SLA L 25CB 2 NOP 1 - -SLP "" 76ED 2 NOP 2 - -SRA (HL) 2ECB 2 NOP 1 -SRA (IX*) CBDD 4 ZIX 1 0 2E00 -SRA (IY*) CBFD 4 ZIX 1 0 2E00 -SRA A 2FCB 2 NOP 1 -SRA B 28CB 2 NOP 1 -SRA C 29CB 2 NOP 1 -SRA D 2ACB 2 NOP 1 -SRA E 2BCB 2 NOP 1 -SRA H 2CCB 2 NOP 1 -SRA L 2DCB 2 NOP 1 - -SRL (HL) 3ECB 2 NOP 1 -SRL (IX*) CBDD 4 ZIX 1 0 3E00 -SRL (IY*) CBFD 4 ZIX 1 0 3E00 -SRL A 3FCB 2 NOP 1 -SRL B 38CB 2 NOP 1 -SRL C 39CB 2 NOP 1 -SRL D 3ACB 2 NOP 1 -SRL E 3BCB 2 NOP 1 -SRL H 3CCB 2 NOP 1 -SRL L 3DCB 2 NOP 1 - -SUB (HL) 96 1 NOP 1 -SUB (IX*) 96DD 3 ZIX 1 -SUB (IY*) 96FD 3 ZIX 1 -SUB A 97 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB * D6 2 NOP 1 - -TST A 3CED 2 NOP 2 -TST B 04ED 2 NOP 2 -TST C 0CED 2 NOP 2 -TST D 14ED 2 NOP 2 -TST E 1CED 2 NOP 2 -TST H 24ED 2 NOP 2 -TST L 2CED 2 NOP 2 -TST (HL) 34ED 2 NOP 2 -TST * 64ED 3 NOP 2 - -TSTIO * 74ED 3 NOP 2 - -XOR (HL) AE 1 NOP 1 -XOR (IX*) AEDD 3 ZIX 1 -XOR (IY*) AEFD 3 ZIX 1 -XOR A AF 1 NOP 1 -XOR B A8 1 NOP 1 -XOR C A9 1 NOP 1 -XOR D AA 1 NOP 1 -XOR E AB 1 NOP 1 -XOR H AC 1 NOP 1 -XOR L AD 1 NOP 1 -XOR * EE 2 NOP 1 diff --git a/branches/s100/Tools/tasm32/TASM85.TAB b/branches/s100/Tools/tasm32/TASM85.TAB deleted file mode 100644 index 33a1bf5b..00000000 --- a/branches/s100/Tools/tasm32/TASM85.TAB +++ /dev/null @@ -1,257 +0,0 @@ -"TASM 8085 Assembler. " -/**************************************************************************** -/* $Id: tasm85.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8085 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Gary Kirk Bach. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS */ -/*-----------------*/ -ACI * CE 2 NOP 1 -ADC B 88 1 NOP 1 -ADC C 89 1 NOP 1 -ADC D 8A 1 NOP 1 -ADC E 8B 1 NOP 1 -ADC H 8C 1 NOP 1 -ADC L 8D 1 NOP 1 -ADC M 8E 1 NOP 1 -ADC A 8F 1 NOP 1 -ADD B 80 1 NOP 1 -ADD C 81 1 NOP 1 -ADD D 82 1 NOP 1 -ADD E 83 1 NOP 1 -ADD H 84 1 NOP 1 -ADD L 85 1 NOP 1 -ADD M 86 1 NOP 1 -ADD A 87 1 NOP 1 -ADI * C6 2 NOP 1 -ANA B A0 1 NOP 1 -ANA C A1 1 NOP 1 -ANA D A2 1 NOP 1 -ANA E A3 1 NOP 1 -ANA H A4 1 NOP 1 -ANA L A5 1 NOP 1 -ANA M A6 1 NOP 1 -ANA A A7 1 NOP 1 -ANI * E6 2 NOP 1 -CALL * CD 3 NOP 1 -CC * DC 3 NOP 1 -CM * FC 3 NOP 1 -CMA "" 2F 1 NOP 1 -CMC "" 3F 1 NOP 1 -CMP B B8 1 NOP 1 -CMP C B9 1 NOP 1 -CMP D BA 1 NOP 1 -CMP E BB 1 NOP 1 -CMP H BC 1 NOP 1 -CMP L BD 1 NOP 1 -CMP M BE 1 NOP 1 -CMP A BF 1 NOP 1 -CNC * D4 3 NOP 1 -CNZ * C4 3 NOP 1 -CP * F4 3 NOP 1 -CPE * EC 3 NOP 1 -CPI * FE 2 NOP 1 -CPO * E4 3 NOP 1 -CZ * CC 3 NOP 1 -DAA "" 27 1 NOP 1 -DAD B 09 1 NOP 1 -DAD D 19 1 NOP 1 -DAD H 29 1 NOP 1 -DAD SP 39 1 NOP 1 -DCR B 05 1 NOP 1 -DCR C 0D 1 NOP 1 -DCR D 15 1 NOP 1 -DCR E 1D 1 NOP 1 -DCR H 25 1 NOP 1 -DCR L 2D 1 NOP 1 -DCR M 35 1 NOP 1 -DCR A 3D 1 NOP 1 -DCX B 0B 1 NOP 1 -DCX D 1B 1 NOP 1 -DCX H 2B 1 NOP 1 -DCX SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -EI "" FB 1 NOP 1 -HLT "" 76 1 NOP 1 -IN * DB 2 NOP 1 -INR B 04 1 NOP 1 -INR C 0C 1 NOP 1 -INR D 14 1 NOP 1 -INR E 1C 1 NOP 1 -INR H 24 1 NOP 1 -INR L 2C 1 NOP 1 -INR M 34 1 NOP 1 -INR A 3C 1 NOP 1 -INX B 03 1 NOP 1 -INX D 13 1 NOP 1 -INX H 23 1 NOP 1 -INX SP 33 1 NOP 1 -JC * DA 3 NOP 1 -JM * FA 3 NOP 1 -JMP * C3 3 NOP 1 -JNC * D2 3 NOP 1 -JNZ * C2 3 NOP 1 -JP * F2 3 NOP 1 -JPE * EA 3 NOP 1 -JPO * E2 3 NOP 1 -JZ * CA 3 NOP 1 -LDA * 3A 3 NOP 1 -LDAX B 0A 1 NOP 1 -LDAX D 1A 1 NOP 1 -LHLD * 2A 3 NOP 1 -LXI B,* 01 3 NOP 1 -LXI D,* 11 3 NOP 1 -LXI H,* 21 3 NOP 1 -LXI SP,* 31 3 NOP 1 -MOV B,B 40 1 NOP 1 -MOV B,C 41 1 NOP 1 -MOV B,D 42 1 NOP 1 -MOV B,E 43 1 NOP 1 -MOV B,H 44 1 NOP 1 -MOV B,L 45 1 NOP 1 -MOV B,M 46 1 NOP 1 -MOV B,A 47 1 NOP 1 -MOV C,B 48 1 NOP 1 -MOV C,C 49 1 NOP 1 -MOV C,D 4A 1 NOP 1 -MOV C,E 4B 1 NOP 1 -MOV C,H 4C 1 NOP 1 -MOV C,L 4D 1 NOP 1 -MOV C,M 4E 1 NOP 1 -MOV C,A 4F 1 NOP 1 -MOV D,B 50 1 NOP 1 -MOV D,C 51 1 NOP 1 -MOV D,D 52 1 NOP 1 -MOV D,E 53 1 NOP 1 -MOV D,H 54 1 NOP 1 -MOV D,L 55 1 NOP 1 -MOV D,M 56 1 NOP 1 -MOV D,A 57 1 NOP 1 -MOV E,B 58 1 NOP 1 -MOV E,C 59 1 NOP 1 -MOV E,D 5A 1 NOP 1 -MOV E,E 5B 1 NOP 1 -MOV E,H 5C 1 NOP 1 -MOV E,L 5D 1 NOP 1 -MOV E,M 5E 1 NOP 1 -MOV E,A 5F 1 NOP 1 -MOV H,B 60 1 NOP 1 -MOV H,C 61 1 NOP 1 -MOV H,D 62 1 NOP 1 -MOV H,E 63 1 NOP 1 -MOV H,H 64 1 NOP 1 -MOV H,L 65 1 NOP 1 -MOV H,M 66 1 NOP 1 -MOV H,A 67 1 NOP 1 -MOV L,B 68 1 NOP 1 -MOV L,C 69 1 NOP 1 -MOV L,D 6A 1 NOP 1 -MOV L,E 6B 1 NOP 1 -MOV L,H 6C 1 NOP 1 -MOV L,L 6D 1 NOP 1 -MOV L,M 6E 1 NOP 1 -MOV L,A 6F 1 NOP 1 -MOV M,B 70 1 NOP 1 -MOV M,C 71 1 NOP 1 -MOV M,D 72 1 NOP 1 -MOV M,E 73 1 NOP 1 -MOV M,H 74 1 NOP 1 -MOV M,L 75 1 NOP 1 -MOV M,A 77 1 NOP 1 -MOV A,B 78 1 NOP 1 -MOV A,C 79 1 NOP 1 -MOV A,D 7A 1 NOP 1 -MOV A,E 7B 1 NOP 1 -MOV A,H 7C 1 NOP 1 -MOV A,L 7D 1 NOP 1 -MOV A,M 7E 1 NOP 1 -MOV A,A 7F 1 NOP 1 -MVI B,* 06 2 NOP 1 -MVI C,* 0E 2 NOP 1 -MVI D,* 16 2 NOP 1 -MVI E,* 1E 2 NOP 1 -MVI H,* 26 2 NOP 1 -MVI L,* 2E 2 NOP 1 -MVI M,* 36 2 NOP 1 -MVI A,* 3E 2 NOP 1 -NOP "" 00 1 NOP 1 -ORA B B0 1 NOP 1 -ORA C B1 1 NOP 1 -ORA D B2 1 NOP 1 -ORA E B3 1 NOP 1 -ORA H B4 1 NOP 1 -ORA L B5 1 NOP 1 -ORA M B6 1 NOP 1 -ORA A B7 1 NOP 1 -ORI * F6 2 NOP 1 -OUT * D3 2 NOP 1 -PCHL "" E9 1 NOP 1 -POP B C1 1 NOP 1 -POP D D1 1 NOP 1 -POP H E1 1 NOP 1 -POP PSW F1 1 NOP 1 -PUSH B C5 1 NOP 1 -PUSH D D5 1 NOP 1 -PUSH H E5 1 NOP 1 -PUSH PSW F5 1 NOP 1 -RAL "" 17 1 NOP 1 -RAR "" 1F 1 NOP 1 -RC "" D8 1 NOP 1 -RET "" C9 1 NOP 1 -RIM "" 20 1 NOP 1 -RLC "" 07 1 NOP 1 -RM "" F8 1 NOP 1 -RNC "" D0 1 NOP 1 -RNZ "" C0 1 NOP 1 -RP "" F0 1 NOP 1 -RPE "" E8 1 NOP 1 -RPO "" E0 1 NOP 1 -RRC "" 0F 1 NOP 1 -RST 0 C7 1 NOP 1 -RST 1 CF 1 NOP 1 -RST 2 D7 1 NOP 1 -RST 3 DF 1 NOP 1 -RST 4 E7 1 NOP 1 -RST 5 EF 1 NOP 1 -RST 6 F7 1 NOP 1 -RST 7 FF 1 NOP 1 -RZ "" C8 1 NOP 1 -SBB B 98 1 NOP 1 -SBB C 99 1 NOP 1 -SBB D 9A 1 NOP 1 -SBB E 9B 1 NOP 1 -SBB H 9C 1 NOP 1 -SBB L 9D 1 NOP 1 -SBB M 9E 1 NOP 1 -SBB A 9F 1 NOP 1 -SBI * DE 2 NOP 1 -SHLD * 22 3 NOP 1 -SIM "" 30 1 NOP 1 -SPHL "" F9 1 NOP 1 -STA * 32 3 NOP 1 -STAX B 02 1 NOP 1 -STAX D 12 1 NOP 1 -STC "" 37 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB M 96 1 NOP 1 -SUB A 97 1 NOP 1 -SUI * D6 2 NOP 1 -XCHG "" EB 1 NOP 1 -XRA B A8 1 NOP 1 -XRA C A9 1 NOP 1 -XRA D AA 1 NOP 1 -XRA E AB 1 NOP 1 -XRA H AC 1 NOP 1 -XRA L AD 1 NOP 1 -XRA M AE 1 NOP 1 -XRA A AF 1 NOP 1 -XRI * EE 2 NOP 1 -XTHL "" E3 1 NOP 1 - diff --git a/branches/s100/Tools/tasm32/TASM96.TAB b/branches/s100/Tools/tasm32/TASM96.TAB deleted file mode 100644 index 25268138..00000000 --- a/branches/s100/Tools/tasm32/TASM96.TAB +++ /dev/null @@ -1,393 +0,0 @@ -"TASM 8096 Assembler." -/**************************************************************************** -/* $Id: tasm96.tab 1.5 1997/09/28 22:14:30 toma Exp $ -/**************************************************************************** -;* This is the instruction set definition table -;* for the 8096 version of TASM. -;* Thomas N. Anderson, Speech Technology Incorporated -;* -;* See TASM manual for info on table structure. -;* -;*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK -;*-------------------------------------------* -; Revisions: -; Added I7 rule for single arg direct/far (PUSH/POP) -; Changed ADDB *,*,*[*] entry from rule I1 to I6. -; -; Generate opcodes high byte first/ -.MSFIRST -.NOARGSHIFT -; -; Note: -; The I1 rule uses ARGVAL for arg validation. If the combined -; args AND ARGVAL is not equal to the combined args then an -; error message is generated. -; -; The I1 rule also uses ARGOR. The value of that mask is OR'd -; with the first byte of the args. -; -; ARGOR -; BYTES CLASS | -; | | | -;INST ARGS OP v RULE v v ARGVAL -;-----------------------------------------; -;OK ADD -ADD *,*,[*]+ 46 4 I1 1 01 00FeFeFe ; -ADD *,*,[*] 46 4 I1 1 00 00FeFeFe ; -ADD *,*,*[*] 47 6 I6 1 00 00FeFeFe ; -ADD *,*,#* 45 5 I1 1 00 FeFeFFFF ; -ADD *,[*]+ 66 3 I1 1 01 0000FFFe ; 1st arg must be even, make odd -ADD *,[*] 66 3 I1 1 00 0000FFFe ; 1st arg must be even -ADD *,*[*] 67 5 I6 1 00 00FFFFFF ; -ADD *,*,* 4701 6 I3 1 00 0000FeFe ; 3rd arg may be far -ADD *,#* 65 4 I1 1 00 00FeFFFF ; 1st arg must be even -ADD *,* 6701 5 I2 1 00 0000FeFe ; 2nd arg may be far - -;OK ADDB -ADDB *,*,[*]+ 56 4 I1 1 01 00000000 ; no validation yet -ADDB *,*,[*] 56 4 I1 1 00 00000000 ; no validation yet -ADDB *,*,*[*] 57 6 I6 1 00 00000000 ; no validation yet -ADDB *,*,#* 55 4 I1 1 00 00000000 ; no validation yet -ADDB *,[*]+ 76 3 I1 1 01 0000FFFe ; 1st arg must be even, make odd -ADDB *,[*] 76 3 I1 1 00 0000FFFe ; 1st arg must be even -ADDB *,*[*] 77 5 I6 1 00 00FeFFFe ; 1st,3rd must be even -ADDB *,*,* 5701 6 I3 1 00 00000000 ; 3rd arg may be far -ADDB *,#* 75 3 I1 1 00 00FFFFFF ; odd args ok for byte operations -ADDB *,* 7701 5 I2 1 00 00000000 ; 2nd arg may be far - -; No three arg forms for ADDC or ADDCB -ADDC *,[*]+ A6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ADDC *,[*] A6 3 I1 1 00 0000FFFe ;1st arg must be even -ADDC *,*[*] A7 5 I6 1 00 00FFFFFF ; -ADDC *,#* A5 4 I1 1 00 00FeFFFF ;1st arg must be even -ADDC *,* A701 5 I2 1 00 00000000 ;2nd arg may be far - -ADDCB *,[*]+ B6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ADDCB *,[*] B6 3 I1 1 00 0000FFFe ;1st arg must be even -ADDCB *,*[*] B7 5 I6 1 00 00FFFFFF ; -ADDCB *,#* B5 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ADDCB *,* B701 5 I2 1 00 00000000 ;2nd arg may be far - -; OK AND -AND *,*,[*]+ 42 4 I1 1 01 00000000 ;no validation yet -AND *,*,[*] 42 4 I1 1 00 00000000 ;no validation yet -AND *,*,*[*] 43 6 I6 1 00 00000000 ;no validation yet -AND *,*,#* 41 5 I1 1 00 00000000 ;no validation yet -AND *,[*]+ 62 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -AND *,[*] 62 3 I1 1 00 0000FFFe ;1st arg must be even -AND *,*[*] 63 5 I6 1 00 00FeFFFe ;1st,3rd must be even -AND *,*,* 4301 6 I3 1 00 00000000 ;3rd arg may be far -AND *,#* 61 4 I1 1 00 00FeFFFF ;1st arg must be even -AND *,* 6301 5 I2 1 00 00000000 ;2nd arg may be far - -ANDB *,*,[*]+ 52 4 I1 1 01 00000000 ;no validation yet -ANDB *,*,[*] 52 4 I1 1 00 00000000 ;no validation yet -ANDB *,*,*[*] 53 6 I6 1 00 00000000 ;no validation yet -ANDB *,*,#* 51 4 I1 1 00 00000000 ;no validation yet -ANDB *,[*]+ 72 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ANDB *,[*] 72 3 I1 1 00 0000FFFe ;1st arg must be even -ANDB *,*[*] 73 5 I6 1 00 00FFFFFF ; -ANDB *,*,* 5301 6 I3 1 00 00000000 ;3rd arg may be far -ANDB *,#* 71 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ANDB *,* 7301 5 I2 1 00 00000000 ;2nd arg may be far - -BMOV *,* C1 3 I1 2 00 0000FcFF ;long word ptr to two words -BMOVI *,* AD 3 I1 2 00 0000FcFF ;long word ptr to two words - -BR [*] E3 2 I1 1 00 00000000 ; -BR * 2000 2 I5 1 00 00000000 ; Same As SJMP - -CLR * 01 2 NOP 1 00 00000000 ; -CLRB * 11 2 NOP 1 00 00000000 ; -CLRC "" F8 1 NOP 1 00 00000000 ; -CLRVT "" FC 1 NOP 1 00 00000000 ; - -CMP *,[*]+ 8A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -CMP *,[*] 8A 3 I1 1 00 0000FFFe ;1st arg must be even -CMP *,*[*] 8B 5 I6 1 00 00FFFFFF ; -CMP *,#* 89 4 I1 1 00 00FeFFFF ;1st arg must be even -CMP *,* 8B01 5 I2 1 00 00000000 ;2nd arg may be far - -CMPB *,[*]+ 9A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -CMPB *,[*] 9A 3 I1 1 00 0000FFFe ;1st arg must be even -CMPB *,*[*] 9B 5 I6 1 00 00FFFFFF ; -CMPB *,#* 99 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -CMPB *,* 9B01 5 I2 1 00 00000000 ;2nd arg may be far - -CMPL *,* C5 3 I1 2 00 0000FcFc ;long align multiple of 4 - -DEC * 05 2 NOP 1 00 00000000 ; -DECB * 15 2 NOP 1 00 00000000 ; -DJNZ *,* E0 3 CREL 1 00 00000000 ; -DJNZW *,* E1 3 CREL 2 00 00000000 ; - -DI "" FA 1 NOP 1 00 00000000 ; - -DIVU *,[*]+ 8E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVU *,[*] 8E 3 I1 1 00 0000FFFe ;1st arg must be even -DIVU *,*[*] 8F 5 I6 1 00 0000FFFe ;1st arg must be even -DIVU *,#* 8D 4 I1 1 00 00FeFFFF ;1st arg must be even -DIVU *,* 8F01 5 I2 1 00 00000000 ;2nd arg may be far - -DIVUB *,[*]+ 9E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVUB *,[*] 9E 3 I1 1 00 0000FFFe ;1st arg must be even -DIVUB *,*[*] 9F 5 I6 1 00 0000FFFF ; -DIVUB *,#* 9D 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -DIVUB *,* 9F01 5 I2 1 00 00000000 ;2nd arg may be far - -DIV *,[*]+ FE8E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIV *,[*] FE8E 4 I1 1 00 0000FFFe ;1st arg must be even -DIV *,*[*] FE8F 6 I6 1 00 0000FFFe ;1st arg must be even -DIV *,#* FE8D 5 I1 1 00 00FeFFFF ;1st arg must be even -DIV *,* FE8F01 6 I2 1 00 00000000 ;2nd arg may be far - -DIVB *,[*]+ FE9E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVB *,[*] FE9E 4 I1 1 00 0000FFFe ;1st arg must be even -DIVB *,*[*] FE9F 6 I6 1 00 0000FFFF ; -DIVB *,#* FE9D 4 I1 1 00 00FFFFFF ;odd args ok for byte operations; -DIVB *,* FE9F01 6 I2 1 00 00000000 ;2nd arg may be far - -DPTS "" EC 1 NOP 2 00 00000000 ; -EPTS "" ED 1 NOP 2 00 00000000 ; - -EI "" FB 1 NOP 1 00 00000000 ; - -EXT * 06 2 NOP 1 00 00000000 ; -EXTB * 16 2 NOP 1 00 00000000 ; - -IDLPD #* F6 2 NOP 2 00 00000000 ; - -INC * 07 2 NOP 1 00 00000000 ; -INCB * 17 2 NOP 1 00 00000000 ; - -JC * DB 2 R1 1 00 00000000 -JNC * D3 2 R1 1 00 00000000 -JH * D9 2 R1 1 00 00000000 -JNH * D1 2 R1 1 00 00000000 -JE * DF 2 R1 1 00 00000000 -JNE * D7 2 R1 1 00 00000000 -JV * DD 2 R1 1 00 00000000 -JNV * D5 2 R1 1 00 00000000 -JGE * D6 2 R1 1 00 00000000 -JLT * DE 2 R1 1 00 00000000 -JVT * DC 2 R1 1 00 00000000 -JNVT * D4 2 R1 1 00 00000000 -JGT * D2 2 R1 1 00 00000000 -JLE * DA 2 R1 1 00 00000000 -JST * D8 2 R1 1 00 00000000 -JNST * D0 2 R1 1 00 00000000 - -JBC *,*,* 30 3 I4 1 00 00000000 -JBS *,*,* 38 3 I4 1 00 00000000 - -LJMP * E7 3 R2 1 00 00000000 -LCALL * EF 3 R2 1 00 00000000 - -LD *,[*]+ A2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LD *,[*] A2 3 I1 1 00 0000FFFe ;1st arg must be even -LD *,*[*] A3 5 I6 1 00 00FFFFFF ; -LD *,#* A1 4 I1 1 00 00FFFFFF ; -LD *,* A301 5 I2 1 00 00000000 ;2nd arg may be far - -LDB *,[*]+ B2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDB *,[*] B2 3 I1 1 00 0000FFFe ;1st arg must be even -LDB *,*[*] B3 5 I6 1 00 00FFFFFF ; -LDB *,#* B1 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDB *,* B301 5 I2 1 00 00000000 ;2nd arg may be far - -LDBSE *,[*]+ BE 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDBSE *,[*] BE 3 I1 1 00 0000FFFe ;1st arg must be even -LDBSE *,*[*] BF 5 I6 1 00 00FeFFFe ;1st,3rd must be even -LDBSE *,#* BD 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDBSE *,* BF01 5 I2 1 00 00000000 ;2nd arg may be far - -LDBZE *,[*]+ AE 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDBZE *,[*] AE 3 I1 1 00 0000FFFe ;1st arg must be even -LDBZE *,*[*] AF 5 I6 1 00 00FeFFFe ;1st,3rd must be even -LDBZE *,#* AD 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDBZE *,* AF01 5 I2 1 00 00000000 ;2nd arg may be far - -MULU *,*,[*]+ 4E 4 I1 1 01 00000000 ;no validation yet -MULU *,*,[*] 4E 4 I1 1 00 00000000 ;no validation yet -MULU *,*,*[*] 4F 6 I6 1 00 00000000 ;no validation yet -MULU *,*,#* 4D 5 I1 1 00 00000000 ;no validation yet -MULU *,[*]+ 6E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULU *,[*] 6E 3 I1 1 00 0000FFFe ;1st arg must be even -MULU *,*[*] 6F 5 I6 1 00 00FeFFFe ;1st,3rd must be even -MULU *,*,* 4F01 6 I3 1 00 00000000 ;3rd arg may be far -MULU *,#* 6D 4 I1 1 00 00FeFFFF ;1st arg must be even -MULU *,* 6F01 5 I2 1 00 00000000 ;2nd arg may be far - - -MULUB *,*,[*]+ 5E 4 I1 1 01 00000000 ;no validation yet -MULUB *,*,[*] 5E 4 I1 1 00 00000000 ;no validation yet -MULUB *,*,*[*] 5F 6 I6 1 00 00000000 ;no validation yet -MULUB *,*,#* 5D 4 I1 1 00 00000000 ;no validation yet -MULUB *,[*]+ 7E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULUB *,[*] 7E 3 I1 1 00 0000FFFe ;1st arg must be even -MULUB *,*[*] 7F 5 I6 1 00 00FFFFFF ; -MULUB *,*,* 5F01 6 I3 1 00 00000000 ;3rd arg may be far -MULUB *,#* 7D 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -MULUB *,* 7F01 5 I2 1 00 00000000 ;2nd arg may be far - -MUL *,*,[*]+ FE4E 5 I1 1 01 00000000 ;no validation yet -MUL *,*,[*] FE4E 5 I1 1 00 00000000 ;no validation yet -MUL *,*,*[*] FE4F 7 I6 1 00 00000000 ;no validation yet -MUL *,*,#* FE4D 6 I1 1 00 00000000 ;no validation yet -MUL *,[*]+ FE6E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -MUL *,[*] FE6E 4 I1 1 00 0000FFFe ;1st arg must be even -MUL *,*[*] FE6F 6 I6 1 00 00FeFFFe ;1st,3rd must be even -MUL *,*,* FE4F01 7 I3 1 00 00000000 ;3rd arg may be far -MUL *,#* FE6D 5 I1 1 00 00FFFFFF ;odd args ok for byte operations -MUL *,* FE6F01 6 I2 1 00 00000000 ;2nd arg may be far - -MULB *,*,[*]+ FE5E 5 I1 1 01 00000000 ;no validation yet -MULB *,*,[*] FE5E 5 I1 1 00 00000000 ;no validation yet -MULB *,*,*[*] FE5F 7 I6 1 00 00000000 ;no validation yet -MULB *,*,#* FE5D 5 I1 1 00 00000000 ;no validation yet -MULB *,[*]+ FE7E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULB *,[*] FE7E 4 I1 1 00 0000FFFe ;1st arg must be even -MULB *,*[*] FE7F 6 I6 1 00 00FFFFFF ; -MULB *,*,* FE5F01 7 I3 1 00 00000000 ;3rd arg may be far -MULB *,#* FE7D 4 I1 1 00 00FFFFFF ;odd args ok for byte operations -MULB *,* FE7F01 6 I2 1 00 00000000 ;2nd arg may be far - -NEG * 03 2 I1 1 00 000000FE ;arg must be even -NEGB * 13 2 I1 1 00 000000FF ; - -NOP "" FD 1 NOP 1 00 00000000 ; - -NORML *,* 0F 3 I1 1 00 0000FFFF ;long align - -NOT * 02 2 NOP 1 00 00000000 ; -NOTB * 12 2 NOP 1 00 00000000 ; - -OR *,[*]+ 82 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -OR *,[*] 82 3 I1 1 00 0000FFFe ;1st arg must be even -OR *,*[*] 83 5 I6 1 00 00FeFFFe ;1st,3rd must be even -OR *,#* 81 4 I1 1 00 00FeFFFF ;1st arg must be even -OR *,* 8301 5 I2 1 00 00000000 ;2nd arg may be far - -ORB *,[*]+ 92 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ORB *,[*] 92 3 I1 1 00 0000FFFe ;1st arg must be even -ORB *,*[*] 93 5 I6 1 00 00FFFFFF ; -ORB *,#* 91 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ORB *,* 9301 5 I2 1 00 00000000 ;2nd arg may be far - -PUSH #* C9 3 I1 1 00 00000000 ; -PUSH [*]+ CA 2 I1 1 01 000000Fe ;arg must be even -PUSH [*] CA 2 I1 1 00 000000Fe ;arg must be even -PUSH *[*] CB 4 I6 1 00 00FFFFFe ;arg must be even -PUSH * CB01 4 I7 1 00 0000FFFe ;arg must be even - -PUSHF "" F2 1 NOP 1 00 00000000 ; -PUSHA "" F4 1 NOP 1 00 00000000 ; - -POP [*]+ CE 2 I1 1 01 000000Fe ;arg must be even -POP [*] CE 2 I1 1 00 000000Fe ;arg must be even -POP *[*] CF 4 I6 1 00 00FFFFFE ; -POP * CF01 4 I7 1 00 0000FFFe ;arg must be even - -POPF "" F3 1 NOP 1 00 00000000 ; -POPA "" F5 1 NOP 1 00 00000000 ; - -RET "" F0 1 NOP 1 00 00000000 ; -RST "" FF 1 NOP 1 00 00000000 ; - -SJMP * 2000 2 I5 1 00 00000000 -SCALL * 2800 2 I5 1 00 00000000 - -SUB *,*,[*]+ 4A 4 I1 1 01 00000000 ;no validation yet -SUB *,*,[*] 4A 4 I1 1 00 00000000 ;no validation yet -SUB *,*,*[*] 4B 6 I6 1 00 00000000 ;no validation yet -SUB *,*,#* 49 5 I1 1 00 00000000 ;no validation yet -SUB *,[*]+ 6A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUB *,[*] 6A 3 I1 1 00 0000FFFe ;1st arg must be even -SUB *,*[*] 6B 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUB *,*,* 4B01 6 I3 1 00 00000000 ;3rd arg may be far -SUB *,#* 69 4 I1 1 00 00FeFFFF ;1st arg must be even -SUB *,* 6B01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBB *,*,[*]+ 5A 4 I1 1 01 00000000 ;no validation yet -SUBB *,*,[*] 5A 4 I1 1 00 00000000 ;no validation yet -SUBB *,*,*[*] 5B 6 I6 1 00 00000000 ;no validation yet -SUBB *,*,#* 59 4 I1 1 00 00000000 ;no validation yet -SUBB *,[*]+ 7A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBB *,[*] 7A 3 I1 1 00 0000FFFe ;1st arg must be even -SUBB *,*[*] 7B 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBB *,*,* 5B01 6 I3 1 00 00000000 ;3rd arg may be far -SUBB *,#* 79 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -SUBB *,* 7B01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBC *,[*]+ AA 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBC *,[*] AA 3 I1 1 00 0000FFFe ;1st arg must be even -SUBC *,*[*] AB 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBC *,#* A9 4 I1 1 00 00FeFFFF ;1st arg must be even -SUBC *,* AB01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBCB *,[*]+ BA 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBCB *,[*] BA 3 I1 1 00 0000FFFe ;1st arg must be even -SUBCB *,*[*] BB 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBCB *,#* B9 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -SUBCB *,* BB01 5 I2 1 00 00000000 ;2nd arg may be far - -SHL *,#* 09 3 I1 1 00 0000FE0F ; F -SHL *,* 09 3 I1 1 00 0000FEFF ; -SHLB *,#* 19 3 I1 1 00 0000FF0F ; -SHLB *,* 19 3 I1 1 00 0000FFFF ; -SHLL *,#* 0D 3 I1 1 00 0000FF0F ; -SHLL *,* 0D 3 I1 1 00 0000FFFF ; - -SHR *,#* 08 3 I1 1 00 0000FF0F ;word align -SHR *,* 08 3 I1 1 00 0000FFFF ;word align -SHRB *,#* 18 3 I1 1 00 0000FF0F ;byte align -SHRB *,* 18 3 I1 1 00 0000FFFF ;byte align -SHRL *,#* 0C 3 I1 1 00 0000FF0F ;long align -SHRL *,* 0C 3 I1 1 00 0000FFFF ;long align - -SHRA *,#* 0A 3 I1 1 00 0000FF0F ;word align -SHRA *,* 0A 3 I1 1 00 0000FFFF ;word align -SHRAB *,#* 1A 3 I1 1 00 0000FF0F ;byte align -SHRAB *,* 1A 3 I1 1 00 0000FFFF ;byte align -SHRAL *,#* 0E 3 I1 1 00 0000FF0F ;long align -SHRAL *,* 0E 3 I1 1 00 0000FFFF ;long align - -SETC "" F9 1 NOP 1 00 00000000 ; - - -SKIP "" 0000 2 NOP 1 00 00000000 ; -SKIP * 00 2 I1 1 00 00000000 ; - -ST *,[*]+ C2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ST *,[*] C2 3 I1 1 00 0000FFFe ;1st arg must be even -ST *,*[*] C3 5 I6 1 00 FFFFFFFe ;1st,3rd must be even -ST *,* C301 5 I2 1 00 00000000 ;2nd arg may be far - -STB *,[*]+ C6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -STB *,[*] C6 3 I1 1 00 0000FFFe ;1st arg must be even -STB *,*[*] C7 5 I6 1 00 FFFFFFFe ;1st,3rd must be even -STB *,* C701 5 I2 1 00 00000000 ;2nd arg may be far - -TRAP "" F7 1 NOP 1 00 00000000 ; - -TIJMP *,[*],#* E2 4 I8 2 00 00FEFEFF ; - -XCH *,*[*] 0B 5 I6 2 00 00FeFFFe ;1st,3rd must be even -XCH *,* 0B01 5 I2 2 0C 00000000 ;2nd arg may be far - -XCHB *,*[*] 1B 5 I6 2 00 00FFFFFF ; -XCHB *,* 1B01 5 I2 2 0C 00000000 ;2nd arg may be far - -XOR *,[*]+ 86 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -XOR *,[*] 86 3 I1 1 00 0000FFFe ;1st arg must be even -XOR *,*[*] 87 5 I6 1 00 00FeFFFe ;1st,3rd must be even -XOR *,#* 85 4 I1 1 00 00FeFFFF ;1st arg must be even -XOR *,* 8701 5 I2 1 00 00000000 ;2nd arg may be far - -XORB *,[*]+ 96 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -XORB *,[*] 96 3 I1 1 00 0000FFFe ;1st arg must be even -XORB *,*[*] 97 5 I6 1 00 00FFFFFF ; -XORB *,#* 95 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -XORB *,* 9701 5 I2 1 00 00000000 ;2nd arg may be far - - diff --git a/branches/s100/Tools/tasm32/TASMMAN.HTM b/branches/s100/Tools/tasm32/TASMMAN.HTM deleted file mode 100644 index 944ec1eb..00000000 --- a/branches/s100/Tools/tasm32/TASMMAN.HTM +++ /dev/null @@ -1,2865 +0,0 @@ - - - - - - - The Telemark Assembler (TASM) User Manual - - - - -
-

-The Telemark Assembler (TASM) User Manual

- -
Version 3.2
-
- -
Thomas N. Anderson
- -
Squak Valley Software
- -
837 Front Street South
- -
Issaquah, WA 98027
- -
email: andersontn@acm.org
- -
www.halcyon.com/squakvly/
-
- -
Copyright (C) 1985-2000 by Thomas N. Anderson. All rights reserved.
- -
-

-TABLE OF CONTENTS

- - - -
-

-INTRODUCTION

-The Telemark Assembler (TASM) is a table driven cross assembler for the -MS-DOS and LINUX environments. Assembly source code, written in the appropriate -dialect (generally very close to the manufacturers assembly language), -can be assembled with TASM, and the resulting object code transferred to -the target microprocessor system via PROM or other mechanisms. - -

The microprocessor families supported by TASM are: -

    -
  • -6502
  • - -
  • -6800/6801/68HC11
  • - -
  • -6805
  • - -
  • -8048
  • - -
  • -8051
  • - -
  • -8080/8085, Z80
  • - -
  • -TMS32010, TMS320C25
  • - -
  • -TMS7000
  • - -
  • -8096/80196
  • -
-The user so inclined may build tables for other microprocessors. The descriptions -of the various existing tables and instructions on building new tables -are not in this document but can be found in the TASMTABS.HTM file on the -TASM distribution disk. - -

TASM characteristics include: -

    -
  1. -Powerful expression parsing (17 operators).
  2. - -
  3. -Supports a subset of the 'C' preprocessor commands.
  4. - -
  5. -Macro capability (through use of DEFINE directive).
  6. - -
  7. -Multiple statements per line.
  8. - -
  9. -Four object file formats: Intel hex, MOS Technology hex, Motorola hex, -binary.
  10. - -
  11. -Absolute code generation only.
  12. - -
  13. -Source code available (in C).
  14. - -
  15. -Uniform syntax across versions for different target machines.
  16. - -
  17. -Features in support of PROM programming (preset memory, contiguous block).
  18. - -
  19. -Supports extended instructions for many of the supported microprocessor -families.
  20. - -
  21. -Tables read at run time - single TASM executable for all table versions.
  22. - -
  23. -Symbol table export for inclusion in subsequent assemblies.
  24. - -
  25. -Symbol table export file for import with some simulator products.
  26. -
- -
-

-SHAREWARE

-TASM is distributed as shareware. TASM is not in the public domain. The -TASM distribution files may be freely copied (excluding the source code -files) and freely used for the purpose of evaluating the suitability of -TASM for a given purpose. Use of TASM beyond a reasonable evaluation period -requires registration. Prolonged use without registration is unethical.  -
-

-INVOCATION

-TASM can be invoked as follows (optional fields shown in brackets, symbolic -fields in italics): -
  tasm -pn [-options ...] src_file [obj_file [lst_file [exp_file [sym_file]]]]
-Where options can be one or more of the following: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-table Specify version (table = table designation) 
-ttable Table (alternate form of above) 
-aamask Assembly control (optional error checking) 
-b Produce object in binary (.COM) format 
-c Object file written as a contiguous block 
-dmacro Define a macro (or just a macro label) 
-e Show source lines after macro expansion 
-ffillbyte Fill entire memory space with fillbyte (hex) 
-gobjtype Object file (0=Intel Hex, 1=MOS Tech, 2=Motorola, -3=binary,4=Intel Hex (Word)) 
-h Produce hex table of the assembled code (in list -file) 
-i Ignore case for labels 
-l[al] Produce a label table in the listing 
-m Produce object in MOS Technology format 
-oobytes Bytes per object record (for hex obj formats) 
-p[linesPage the listing file (lines per page. default=60) 
-q Quiet, disable the listing file 
-s Write a symbol table file 
-x[xmaskEnable extended instruction set (if any) 
-y Time the assembly 
-

The filename parameters are defined as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
src_file Source file name 
obj_file Object code file name 
lst_file Listing file name 
exp_file Symbol export file (only if the EXPORT directive -is used).
sym_file Symbol table file (only if the -s option -or the SYM/AVSYM directives are used). 
-

The source file must be specified. If not, some usage information is displayed. -Default file names for all the other files are generated if they are not -explicitly provided. The filename is formed by taking the source filename -and changing the extension to one of the following: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Extension File type 
.OBJ Object file 
.LST Listing file 
.EXP Symbol export file 
.SYM Symbol table file 
-

TASM has no built-in instruction set tables. Instruction set definition -files are read at run time. TASM determines which table to use based on -the '-table' field shown above. For example, to assemble the code -in a file called source.asm, one would enter -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tasm -48 source.asm for an 8048 assembly 
tasm -65 source.asm for a 6502 assembly 
tasm -51 source.asm for an 8051 assembly. 
tasm -85 source.asm for an 8085 assembly. 
tasm -80 source.asm for a Z80 assembly. 
tasm -05 source.asm for a 6805 assembly. 
tasm -68 source.asm for a 6800/6801/68HC11 assembly. 
tasm -70 source.asm for a TMS7000 assembly. 
tasm -3210 source.asm for a TMS32010 assembly. 
tasm -3225 source.asm for a TMS320C25 assembly. 
tasm -96 source.asm for a 8096/80196 assembly
-

-Tables are read from a file named by taking the digits specified after -the '-' and appending it to 'TASM' then appending the '.TAB' extension. -Thus, the -48 flag would cause the tables to be read from the file -'TASM48.TAB'. - -

It is possible to designate tables by non numeric part numbers if the --t flag is used. For example, if a user built a table called TASMF8.TAB -then TASM could be invoked as follows: -

    tasm -tf8 source.asm
-Each option flag must be preceded by a dash. Options need not precede the -file names. The various options are described in the sections that follow. -

-a - Assembly Control

-TASM can provide additional error checking by specifying the -a -option at the time of execution. If the -a is provided without a -digit following, then all the available error checking is done. If a digit -follows, then it is used as a mask to determine the error checks to be -made. The bits of the mask are defined as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bit Option Default Description 
-a1 OFF Check for apparent illegal use of indirection 
-a2 ON Check for unused data in the arguments 
-a4 ON Check for duplicate labels 
-a8 OFF Check for non-unary operators at start of expression. 
-

Combinations of the above bits can also be used. For example, -a5 -would enable the checking for illegal indirection and duplicate labels. - -

Illegal indirection applies to micros that use parenthesis around an -argument to indicate indirection. Since it is always legal to put an extra -pair of parenthesis around any expression (as far as the expression parser -is concerned), the user may think that he/she is indicating indirection -for an instruction that has no indirection and TASM would not complain. -Enabling this checking will result in an error message (warning) whenever -an outer pair of parenthesis is used and the instruction set definition -table does not explicitly indicate that to be a valid form of addressing. - -

Unused data in arguments applies to cases where a single byte of data -is needed from an argument, but the argument contains more than one byte -of data. If a full sixteen bit address is used in a 'Load Immediate' type -instruction that needs only a single byte, for example, an error message -would be generated. Here is an example (6502 code): -

    0001   1234                    .org $1234
-    test.asm line 0002: Unused data in MS byte of argument.
-    0002   1234 A9 34       start  lda  #start
-To make the above checks occur whenever you do an assembly, add a line -like this to your AUTOEXEC.BAT file: -
    SET TASMOPTS=-a
- -

-b - Binary Object Format

-This option causes the object file to be written in binary - one byte for -each byte of code/data. Note that no address information is included in -the object file in this format. The contiguous block (-c) output mode is -forced when this option is invoked. This flag is equivalent to -g3. -

-c - Contiguous Block Output

-If this option is specified, then all bytes in the range from the lowest -used byte to the highest will be defined in the object file. Normally, -with the default Intel Hex object format enabled, if the Program Counter -(PC) jumps forward because of an .ORG directive, the -bytes skipped over will not have any value assigned them in the object -file. With this option enabled, no output to the object file occurs until -the end of the assembly at which time the whole block is written. This -is useful when using TASM to generate code that will be put into a PROM -so that all locations will have a known value. This option is often used -in conjunction with the -f option to ensure all unused bytes will have -a known value. -

-d - Define a Macro

-Macros are defined on the command line generally to control the assembly -of various IFDEF's that are in the source file. This is a convenient way -to generate various versions of object code from a single source file. -

-e - Expand Source.

-Normally TASM shows lines in the listing file just as they are in the source -file. If macros are in use (via the DEFINE directive) -it is sometimes desirable to see the source lines after expansion. Use -the '-e' flag to accomplish this. -

-f - Fill Memory.

-This option causes the memory image that TASM maintains to be initialized -to the value specified by the two hex characters immediately following -the 'f'. TASM maintains a memory image that is a full 64K bytes in size -(even if the target processor cannot utilize that memory space). Invocation -of this option introduces a delay at start up time. -

-g - Object File Format.

-TASM can generate object code in the formats indicated below: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Option Description
-g0 Intel hex (default) 
-g1 MOS Technology hex (same as -m
-g2 Motorola hex 
-g3 binary (same as -b
-g4 Intel hex with word addresses
-

The -m and -b flags may also be used, as indicated above. -If both are used the right-most option on the command line will be obeyed. - -

See the section on OBJECT FILE FORMATS for descriptions of each -of the above. -

-h - Hex Object Code Table.

-This option causes a hex table of the produced object code to appear in -the listing file. Each line of the table shows sixteen bytes of code. -

-i - Ignore Case in Labels.

-TASM is normally case sensitive when dealing with labels. For those that -prefer case insensitivity, the '-i' command line option can be employed. -

-l - Label Table.

-This option causes a label table to appear in the listing file. Each label -is shown with its corresponding value. Macro labels (as established via -the DEFINE directives) do not appear. - -

Two optional suffixes may follow the -l option: -
  - - - - - - - - - - - - - - - - - - -
Suffix Description 
Use long form listing 
Show all labels (including local labels) 
-

The suffix should immediately follow the '-l'. Here are some examples: -
  - - - - - - - - - - - - - - - - - - - - - - - - -
-l to show non-local labels in the short form 
-la to show all labels in the short form 
-ll to show non-local labels in the long form 
-lal to show all labels in the long form 
- -

-m - MOS Technology Object Format.

-This option causes the object file to be written in MOS Technology hex -format rather than the default Intel hex format. See section on OBJECT -FILE FORMATS for a description of the format. -

-o - Set Number of Bytes per Object Record.

-When generating object code in either the MOS Technology format or the -Intel hex format, a default of 24 (decimal) bytes of object are defined -on each record. This can be altered by invoking the '-o' option immediately -followed by two hex digits defining the number of bytes per record desired. -For example, if 32 bytes per record are desired, one might invoke TASM -as: -
    tasm -48 -o20 source.asm
- -

-p - Page Listing File.

-This option causes the listing file to have top of page headers and form -feeds inserted at appropriate intervals (every sixty lines of output). -To override the default of sixty lines per page, indicate the desired number -of lines per page as a decimal number immediately following the '-p'. Here -is an example: -
    tasm -48 -p56 source.asm
- -

-q - Disable Listing File.

-This option causes all output to the listing file to be suppressed, unless -a .LIST directive is encountered in the source file (see LIST/NOLIST -directives). -

-s - Enable Symbol File Generation.

-If this flag is set, a symbol file is generated at the end of the assembly. -The format of the file is one line per label, each label starts in the -first column and is followed by white space and then four hexadecimal digits -representing the value of the label. The following illustrates the format: -
    label1         FFFE
-    label2         FFFF
-    label3         1000
-The symbol file name can be provided as the fifth file name on the command -line, or the name will be generated from the source file name with a '.SYM' -extension. The symbol table file can also be generated by invoking the -SYM directive. The AVSYM directive also generates the symbol file but in -a different format (see section on ASSEMBLER -DIRECTIVES). -

-t - Table Name.

-As an alternative to specifying the instruction set table as two decimal -digits, the table indication may be proceeded by the '-t' option. This -is useful if the desired table name starts with a non-numeric. Thus, a -table for an F8 might be selected as: -
    tasm -tf8 source.asm
-TASM would expect to read the instruction set definition tables from a -file named TASMF8.TAB. -

-x - Enable Extended Instruction Set.

-If a processor family has instructions that are valid for only certain -members, this option can be used to enable those beyond the basic standard -instruction set. A hex digit may follow the 'x' to indicate a mask value -used in selecting the appropriate instruction set. Bit 0 of the mask selects -the basic instruction set, thus a '-x1' would have no effect. A '-x3' would -enable the basic set plus whatever instructions have bit 1 set in their -class mask. A '-x' without a digit following is equivalent to a '-xf' which -sets all four of the mask bits. The following table indicates the current -extended instruction sets available in the TASM tables: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Base Table Base Family Ext 1 (-x3) Ext 2 (-x7) Ext 3 (-x5) Ext 4 (-x9) 
48 8048 8041A 8022 8021 
65 6502 R65C02 R65C00/21 
05 6805 M146805 CMOS HC05C4 
80 Z80 HD64180 
68 6800 6801/6803 68HC11 
51 8051 
85 8080 
3210 TMS32010 
3225 TMS320C25 TMS320C26 
70 TMS7000 
-  -
  - -

The above table does not attempt to show the many microprocessor family -members that may apply under a given column. - -

See the TASMTABS.HTM on-line document for details on each specific table. -

-y - Enable Assembly Timing

-If this option is enabled TASM will generate a statement of elapsed time -and assembled lines per second at the end of the assembly. -

- -
ENVIRONMENT VARIABLES

-The TASM environment can be customized by using the environment variables -listed below: -

-TASMTABS

-The TASMTABS variable specifies the path to be searched for TASM instruction -set definition tables. If it is not defined then the table(s) must exist -in the current working directory. The following examples illustrate possible -usage: -
  - - - - - - - - - - - - -
For MSDOS set TASMTABS=C:\TASM
For LINUX TASMTABS=/tasm
- -

-TASMOPTS

-This variable specifies TASM command line options that are to be invoked -every time TASM is executed. For example, if TASM is being used for 8048 -assemblies with binary object file output desired, the following statement -would be appropriate in the AUTOEXEC.BAT file: -
    set TASMOPTS=-48 -b
- -

-TASMERRFORMAT

-The TASMERRFORMAT variable provides user control of the format of error -messages.  The format string must be a valid printf format string -for ANSI C.  The default value is: -
    -
    "%s line %04d: %s %s"
    -
-Which provides error messages like this: -
    -
    Main.asm line 1234: No such label: Start
    -
-The four fields associated with an error message are: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field DescriptionAssociated Data Type (ANSI C)
File namechar *
Line number within fileint
Error descriptionchar *
Error data (optional)char *
- - -

No user control of the order of the error message fields is provided. -
Here are sample usages: - -

For MSDOS: -

    -
    set TASMERRFORMAT=”%s(%d) %s %s”
    -
-For LINUX: -
    -
    TASMERRFORMAT=”%s(%d) %s %s”
    -
- -
-

-EXIT CODES

-When TASM terminates, it will return to the OS the following exit codes: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Exit Code Definition
Normal completion, no assembly errors 
Normal completion, with assembly errors 
Abnormal completion, insufficient memory 
Abnormal completion, file access error 
Abnormal completion, general error 
-

Exit codes 2 and above will also be accompanied by messages to the console -concerning the error. -
-


-

-SOURCE FILE FORMAT

-Statements in the source file must conform to a format as follows (except -for assembler directive statements which are described in a subsequent -section): -
  -
    label operation operand comment
-All of the fields are optional, under appropriate circumstances. An arbitrary -amount of white space (space and tabs) can separate each field (as long -as the maximum line length of 255 characters is not exceeded). Each of -the fields are described in the following sections. -

-Label Field.

-If the first character of the line is alphabetic, it is assumed to be the -start of a label. Subsequent characters are accepted as part of that label -until a space, tab, or ':' is encountered. The assembler assigns a value -to the label corresponding to the current location counter. Labels can -be a maximum of 32 characters long. Labels can contain upper and lower -case letters, digits, underscores, and periods (the first character must -be alphabetic). Labels are case sensitive - the label 'START' is a different -label from 'start' - unless the '-i' (ignore case) option is enabled. -

-Operation Field.

-The operation field contains an instruction mnemonic which specifies the -action to be carried out by the target processor when this instruction -is executed. The interpretation of each mnemonic is dependent on the target -microprocessor (as indicated by the selected TASM table). The operation -field may begin in any column except the first. The operation field is -case insensitive. -

-Operand Field.

-The operand field specifies the data to be operated on by the instruction. -It may include expressions and/or special symbols describing the addressing -mode to be used. The actual format and interpretation is dependent on the -target processor. For a description of the format for currently supported -processors, see the TASMTABS.DOC file on the TASM distribution disk. -

-Comment Field.

-The comment field always begins with a semicolon. The rest of the line -from the semicolon to the end of the line is ignored by TASM, but passed -on to the listing file for annotation purposes. The comment field must -be the last field on a line, but it may be the only field, starting in -column one, if desired. -

-Multiple Statement Lines.

-If the backslash character is encountered on a source line, it is treated -as a newline. The remainder of the line following the backslash will be -processed as an independent line of source code. This allows one to put -multiple statements on a line. This facility is not so useful of itself, -but when coupled with the capability of the DEFINE directive, powerful -multiple statement macros can be constructed (see section on ASSEMBLER -DIRECTIVES). Note that when using the statement separator, the -character immediately following it should be considered the first character -of a new line, and thus must either be a start of a label or white space -(not an instruction). As the examples show, a space is put between the -backslash and the start of the next instruction. -

-Sample Source Listing.

-Some examples of valid source statements follow (6502 mnemonics shown): -
  lab1       lda    byte1   ;get the first byte
-             dec    byte1
-             jne    label1
-  ;            
-  lab2       sta    byte2,X
-  ;  a multiple statement line follows
-             lda    byte1\ sta byte1+4\ lda byte2\ sta byte2+4
- -
-

-EXPRESSIONS

-Expressions are made up of various syntactic elements combined according -to a set of syntactical rules. Expressions can be comprised of the following -elements: -
    -
  • -Labels
  • - -
  • -Constants
  • - -
  • -Location Counter Symbol
  • - -
  • -Operators
  • - -
  • -Parenthesis
  • -
- -

-Labels

-Labels are strings of characters that have a numeric value associated with -them, generally representing an address. Labels can contain upper and lower -case letters, digits, underscores, and periods. The first character must -be a letter or the local label prefix (default '_'). The value of a label -is limited to 32 bit precision. Labels can contain up to 32 characters, -all of which are significant (none are ignored when looking at a label's -value, as in some assemblers). Case is significant unless the '-i' command -line option is invoked. - -

Local labels must only be unique within the scope of the current module. -Modules are defined with the MODULE directive. Here -is an example: -

          .MODULE xxx
-          lda regx
-          jne _skip
-          dec
-   _skip  rts
-          .MODULE yyy
-          lda regy
-          jne _skip
-          dec
-   _skip  rts
-In the above example, the _skip label is reused without harm. As -a default, local labels are not shown in the label table listing (resulting -from the '-l' command line option). See also sections on MODULE -and LOCALLABELCHAR directives. -

-Numeric Constants

-Numeric constants must always begin with a decimal digit (thus hexadecimal -constants that start with a letter must be prefixed by a '0' unless the -'$' prefix is used). The radix is determined by a letter immediately following -the digit string according to the following table: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Radix Suffix Prefix 
B or b 
O or o 
10 D or d (or nothing) 
16 H or h 
- -

Decimal is the default radix, so decimal constants need no suffix or prefix. - -

The following representations are equivalent: -

    1234H          or     $1234
-    100d           or     100
-    177400o        or     @177400
-    01011000b      or     %01011000
-The prefixes are provided for compatibility with some other source code -formats but introduce a problem of ambiguity. Both '%' and '$' have alternate -uses ('%' for modulo, '$' for location counter symbol). The ambiguity is -resolved by examining the context. The '%' character is interpreted as -the modulo operator only if it is in a position suitable for a binary operator. -Similarly, if the first character following a '$' is a valid hexadecimal -digit, it is assumed to be a radix specifier and not the location counter. -

-Character Constants

-Character constants are single characters surrounded by single quotes. -The ASCII value of the character in the quotes is returned. No escape provision -exists to represent non-printable characters within the quotes, but this -is not necessary since these can be just as easily represented as numeric -constants (or using the TEXT directive which does allow -escapes). -

-String Constants.

-String constants are one or more characters surrounded by double quotes. -Note that string constants are not allowed in expressions. They are only -allowable following the TITLE, BYTE, -DB, and TEXT assembler directives. -The quoted strings may also contain escape sequences to put in unprintable -values. The following escape sequences are supported: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Escape Sequence Description 
\n Line Feed 
\r Carriage return 
\b Backspace 
\t Tab 
\f Formfeed 
\\ Backslash 
\" Quote 
\000 Octal value of character 
- -

-Location Counter Symbol

-The current value of the location counter (PC) can be used in expressions -by placing a '$' in the desired place. The Location Counter Symbol is allowable -anywhere a numeric constant is. (Note that if the '$' is followed by a -decimal digit then it is taken to be the hexadecimal radix indicator instead -of the Location Counter symbol, as mentioned above). The '*' may also be -used to represent the location counter, but is less preferred because of -its ambiguity with the multiplicative operator. -

-Operators

-Expressions can optionally contain operators to perform some alterations -or calculations on particular values. The operators are summarized as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operator Type Description 
Additive addition 
subtraction 
Multiplicative multiplication 
division 
modulo 
<<logical shift left 
>> logical shift right 
Unary bit inversion (one's complement) 
unary negation 
Relational equal 
== equal 
!= not equal 
<less than 
>greater than 
<= less than or equal 
>= greater than or equal 
&Binary binary 'and' 
binary 'or' 
binary 'exclusive or' 
- -

The syntax is much the same as in ANSI C with the following notes: - -

    -
  1. -No operator precedence is in effect. Evaluation is from left to right unless -grouped by parenthesis (see example below).
  2. - -
  3. -All evaluations are done with 32 bit signed precision.
  4. - -
  5. -Both '=' and '==' are allowable equality checkers. This is allowed since -the syntax does not provide assignment capability (as '=' would normally -imply).
  6. -
-The relational operators return a value of 1 if the relation is true and -0 if it is false. Thirty-two bit signed arithmetic is used. - -

It is always a good idea to explicitly indicate the desired order of -evaluation with parenthesis, especially to maintain portability since TASM -does not evaluate expressions in the same manner as many other assemblers. -To understand how it does arrive at the values for expressions, consider -the following example: -

    1 + 2*3 + 4
-TASM would evaluate this as: -
    (((1 + 2) * 3) + 4) = 13
-Typical rules of precedence would cause the (2*3) to be evaluated first, -such as: -
    1 + (2*3) + 4      = 11
-To make sure you get the desired order of evaluation, use parenthesis liberally. -Here are some examples of valid expressions: -
    (0f800H + tab)
-    (label_2 >> 8)
-    (label_3 << 8) & $f000
-    $ + 4
-    010010000100100b + 'a'
-    (base + ((label_4 >> 5) & (mask << 2))
- -
-

-ASSEMBLER DIRECTIVES

-Most of the assembler directives have a format similar to the machine instruction -format. However, instead of specifying operations for the processor to -carry out, the directives cause the assembler to perform some function -related to the assembly process. TASM has two types of assembler directives -- those that mimic the 'C' preprocessor functions, and those that resemble -the more traditional assembler directive functions. Each of these will -be discussed. - -

The ANSI C preprocessor style directives are invoked with a '#' as the -first character of the line followed by the appropriate directive (just -as in 'C'). Thus, these directives cannot have a label preceding them (on -the same line). Note that in the examples directives are shown in upper -case, however, either upper or lower case is acceptable. -

-ADDINSTR

-The ADDINSTR directive can be used to define additional instructions for -TASM to use in this assembly. The format is: -
    [label] .ADDINSTR inst args opcode nbytes rule class shift binor
-The fields are separated by white space just as they would appear in an -instruction definition file. See the TASMTABS.HTM file on the TASM distribution -disk for more detail. -

-AVSYM

-See SYM/AVSYM. -

-BLOCK

-The BLOCK directive causes the Instruction Pointer to advance the specified -number of bytes without assigning values to the skipped over locations. -The format is: -
    [label] .BLOCK        expr
-Some valid examples are: -
    word1   .BLOCK     2
-    byte1   .block     1
-    buffer  .block     80
- -

-BSEG/CSEG/DSEG/NSEG/XSEG

-These directives can be invoked to indicate the appropriate address space -for symbols and labels defined in the subsequent code. The invocation of -these directives in no way affects the code generated, only provides more -information in the symbol table file if the AVSYM directive is employed. -Segment control directives such as these are generally supported by assemblers -that generate relocatable object code. TASM does not generate relocatable -object code and does not support a link phase, so these directives have -no direct effect on the resulting object code. The segments are defined -as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directive Segment Description 
BSEG Bit address 
CSEG Code address 
DSEG Data address (internal RAM) 
NSEG Number or constant (EQU) 
XSEG External data address (external RAM) 
- -

-BYTE

-The BYTE directive allows a value assignment to the byte pointed to by -the current Instruction Pointer. The format is: -
    [label] .BYTE   expr [, expr ...]
-Only the lower eight bits of expr are used. Multiple bytes may be -assigned by separating them with commas or (for printable strings) enclosed -in double quotes. Here are some examples: -
    label1   .BYTE     10010110B
-             .byte     'a'
-             .byte     0
-             .byte     100010110b,'a',0
-             .byte     "Hello", 10, 13, "World"
- -

-CHK

-The CHK directive causes a checksum to be computed and deposited at the -current location. The starting point of the checksum calculation is indicated -as an argument. Here is the format: -
    [label]    .CHK    starting_addr
-Here is an example: -
    start: NOP
-           LDA #1
-           .CHK start
-The checksum is calculated as the simple arithmetic sum of all bytes starting -at the starting_addr up to but not including the address of the -CHK directive. The least significant byte is all that -is used. -

-CODES/NOCODES

-The CODES/NOCODES directives can be used to alternately turn on or off -the generation of formatted listing output with line numbers, opcodes, -data, etc. With NOCODES in effect, the source lines are sent to the listing -file untouched. This is useful around blocks of comments that need a full -80 columns of width for clarity. -

-DB

-This is alternate form of the BYTE directive. -

-DW

-This is alternate form of the WORD directive. -

-DEFINE

-The DEFINE directive is one of the most powerful of the directives and -allows string substitution with optional arguments (macros). The format -is as follows: -
    #DEFINE  macro_label[(arg_list)]  [macro_definition]
-Where: -
-
-macro_label
- -
-character string to be expanded when found in the source file
- -
-arg_list
- -
-optional argument list for variable substitution in macro expansion
- -
-macro_def
- -
-string to replace the occurrences of macro_label in the source file.
-
-The simplest form of the DEFINE directive might look like this: -
    #DEFINE         MLABEL
-Notice that no substitutionary string is specified. The purpose of a statement -like this would typically be to define a label for the purpose of controlling -some subsequent conditional assembly (IFDEF or IFNDEF). - -

A more complicated example, performing simple substitution, might look -like this: -

    #DEFINE         VAR1_LO         (VAR1 & 255)
-This statement would cause all occurrences of the string 'VAR1_LO' in the -source to be substituted with '(VAR1 & 255)'. - -

As a more complicated example, using the argument expansion capability, -consider this: -

    #DEFINE  ADD(xx,yy)    clc\ lda xx\ adc yy\ sta xx
-If the source file then contained a line like this: -
    ADD(VARX,VARY)
-It would be expanded to: -
    clc\ lda VARX\ adc VARY\ sta VARX
-The above example shows the use of the backslash ('\') character as a multiple -instruction statement delimiter. This approach allows the definition of -fairly powerful, multiple statement macros. The example shown generates -6502 instructions to add one memory location to another. - -

Some rules associated with the argument list: -

    -
  1. -Use a maximum of 10 arguments.
  2. - -
  3. -Each argument should be a maximum of 15 characters.
  4. -
-Note that macros can be defined on the TASM command line, also, with the --d option flag. -

-DEFCONT

-The DEFCONT directive can be used to add to the last macro started with -a DEFINE directive. This provides a convenient way -to define long macros without running off the edge of the page. The ADD -macro shown above could be defined as follows: -
    #DEFINE         ADD(xx,yy)     clc
-    #DEFCONT                     \ lda xx
-    #DEFCONT                     \ adc yy
-    #DEFCONT                     \ sta xx
- -

-ECHO

-The ECHO directive can be used to send output to the console (stderr). -It can accept either a quoted text string (with the standard escape sequences -allowed) or a valid expression. It can accept only one or the other, however. -Multiple instances of the directive may be used to create output that contains -both. Consider the following example: -
    .ECHO "The size of the table is "
-    .ECHO (table_end - table_start)
-    .ECHO " bytes long.\n"
-This would result in a single line of output something like this: -
    The size of the table is 196 bytes long.
- -

-EJECT

-The EJECT directive can be used to force a top-of-form and the generation -of a page header on the list file. It has no effect if the paging mode -is off (see PAGE/NOPAGE). The format is: -
    [label]    .EJECT
- -

-ELSE

-The ELSE directive can optionally be used with IFDEF, IFNDEF and IF to -delineate an alternate block of code to be assembled if the block immediately -following the IFDEF, IFNDEF or IF is not assembled. - -

Here are some examples of the use of IFDEF, IFNDEF, IF, ELSE, and ENDIF: -

    #IFDEF   label1
-        lda      byte1
-        sta      byte2
-    #ENDIF   
-
-    #ifdef   label1
-        lda      byte1
-    #else    
-        lda      byte2
-    #endif   
-
-    #ifndef  label1
-        lda      byte2
-    #else    
-        lda      byte1
-    #endif   
-
-    #if ($ >= 1000h)
-    ; generate an invalid statement to cause an error
-    ;  when we go over the 4K boundary.
-    !!! PROM bounds exceeded.
-    #endif
- -

-END

-The END directive should follow all code/data generating statements in -the source file. It forces the last record to be written to the object -file. The format is: -
    [label]       .END [addr]
-The optional addr will appear in the last object record (Motorola -S9 record type) if the object format is Motorola hex. The addr field -is ignored for all other object formats. -

-ENDIF

-The ENDIF directive must always follow an IFDEF, IFNDEF, or IF directive -and signifies the end of the conditional block. -

-EQU

-The EQU directive can be used to assign values to labels. The labels can -then be used in expressions in place of the literal constant. The format -is: -
    label   .EQU   expr
-Here is an example: -
    MASK   .EQU  0F0H
-    ;
-           lda   IN_BYTE
-           and   MASK
-           sta   OUT_BYTE
-An alternate form of the EQU directive is '='. The previous example is -equivalent to any of the following: -
    MASK    =   0F0H
-    MASK    =0F0H
-    MASK    =$F0
-White space must exist after the label, but none is required after -the '='. -

-EXPORT

-The EXPORT directive can be used to define labels (symbols) that are to -be written to the export symbol file. The symbols are written as equates -(using the .EQU directive) so that the resulting file can be included in -a subsequent assembly. This feature can help overcome some of the deficiencies -of TASM due to its lack of a relocating linker. The format is: -
    [label]  .EXPORT      label [,label...]
-The following example illustrates the use of the EXPORT directive and the -format of the resulting export file: - -

Source file: -

    EXPORT        read_byte
-    EXPORT        write_byte, open_file
-Resulting export file: -
    read_byte      .EQU   $1243
-    write_byte     .EQU   $12AF
-    open_file      .EQU   $1301
- -

-FILL

-The FILL directive can be used to fill a selected number of object bytes -with a fixed value. Object memory is filled from the current program counter -forward. The format is as follows: -
    [label]  .FILL      number_of_bytes [,fill_value]
-The number_of_bytes value can be provided as any valid expression. -The optional fill_value can also be any valid expression. If fill_value -is not provided, a default value of 255 ($FF) is used. -

-IFDEF

-The IFDEF directive can be used to optionally assemble a block of code. -It has the following form: -
    #IFDEF  macro_label
-When invoked, the list of macro labels (established via DEFINE -directives) is searched. If the label is found, the following lines of -code are assembled. If not found, the input file is skipped until an ENDIF -or ELSE directive is found. - -

Lines that are skipped over still appear in the listing file, but a -'~' will appear immediately after the current PC and no object code will -be generated (this is applicable to IFDEF, IFNDEF, and IF). -

-IFNDEF

-The IFNDEF directive is the opposite of the IFDEF directive. The block -of code following is assembled only if the specified macro_label -is undefined. It has the following form: -
    #IFNDEF  macro_label
-When invoked, the list of macro labels (established via DEFINE directives) -is searched. If the label is not found, the following lines of code are -assembled. If it is found, the input file is skipped until an ENDIF or -ELSE directive is found. -

-IF

-The IF directive can be used to optionally assemble a block of code dependent -on the value of a given expression. The format is as follows: -
    #IF     expr
-If the expression expr evaluates to non-zero, the following block -of code is assembled (until an ENDIF or ELSE is encountered). -

-INCLUDE

-The INCLUDE directive reads in and assembles the indicated source file. -INCLUDEs can be nested up to four levels. This allows a convenient means -to keep common definitions, declarations, or subroutines in files to be -included as needed. The format is as follows: -
#INCLUDE        filename
-The filename must be enclosed in double quotes. Here are some examples: -
    #INCLUDE       "macros.h"
-    #include       "equates"
-    #include       "subs.asm"
- -

-LIST/NOLIST

-The LIST and NOLIST directives can be used to alternately turn the output -to the list file on (LIST) or off (NOLIST). The formats are: -
    .LIST
-    .NOLIST
- -

-LOCALLABELCHAR

-The LOCALLABELCHAR directive can be used to override the default "_" as -the label prefix indicating a local label. For example, to change the prefix -to "?" do this: -
    [label]   .LOCALLABELCHAR "?"
-Be careful to use only characters that are not operators for expression -evaluation. To do so causes ambiguity for the expression evaluator. Some -safe characters are "?", "{", and "}".  See Labels -for an example of local label usage. -

-LSFIRST/MSFIRST

-The LSFIRST and MSFIRST directives determine the byte order rule to be -employed for the WORD directive. The default (whether -correct or not) for all TASM versions is the least significant byte first -(LSFIRST). The following illustrates its effect: -
    0000  34 12    .word $1234
-    0002           .msfirst
-    0002  12 34    .word $1234
-    0004           .lsfirst
-    0004  34 12    .word $1234
- -

-MODULE

-The MODULE directive defines the scope of local labels. The format is: -
    [label]   .MODULE label
-Here is an example: -
          .MODULE module_x
-          lda regx
-          jne _skip
-          dec
-   _skip  rts
-          .MODULE module_y
-          lda regy
-          jne _skip
-          dec
-   _skip  rts
-In the above example, the local label _skip is reused without harm -since the two usages are in separate modules. See also section LOCALLABELCHAR -directive. -

-ORG

-The ORG directive provides the means to set the Instruction Pointer (a.k.a. -Program Counter) to the desired value. The format is: -
    [label] .ORG    expr
-The label is optional. The Instruction pointer is assigned the value -of the expr. For example, to generate code starting at address 1000H, -the following could be done: -
    start   .ORG    1000H
-The expression (expr) may contain references to the current Instruction -Pointer, thus allowing various manipulations to be done. For example, to -align the Instruction Pointer on the next 256 byte boundary, the following -could be done: -
    .ORG  (($ + 0FFH) & 0FF00H)
-ORG can also be used to reserve space without assigning values: -
    .ORG    $+8
-An alternate form of ORG is '*=' or '$='. Thus the following two examples -are exactly equivalent to the previous example: -
    *=*+8
-    $=$+8
- -

-PAGE/NOPAGE

-The PAGE/NOPAGE directives can be used to alternately turn the paging mode -on (PAGE) or off (NOPAGE). If paging is in effect, then every sixty lines -of output will be followed by a Top of Form character and a two line header -containing page number, filename, and the title. The format is: -
    
-    .PAGE
-    .NOPAGE
-The number of lines per page can be set with the '-p' command line option. -

-SET

-The SET directive allows the value of an existing label to be changed. -The format is: -
    label   .SET    expr
-The use of the SET directive should be avoided since changing the value -of a label can sometimes cause phase errors between pass 1 and pass 2 of -the assembly. -

-SYM/AVSYM

-These directives can be used to cause a symbol table file to be generated. -The format is: -
    .SYM    ["symbol_filename"]
-    .AVSYM  ["symbol_filename"]
-For example: -
    .SYM       "symbol.map"
-    .SYM       
-    .AVSYM     "prog.sym"
-    .AVSYM
-The two directives are similar, but result in a different format of the -symbol table file. The format of the SYM file is one line per symbol, each -symbol starts in the first column and is followed by white space and then -four hexadecimal digits representing the value of the symbol. The following -illustrates the format: -
    label1         FFFE
-    label2         FFFF
-    label3         1000
-The AVSYM directive is provided to generate symbol tables compatible with -the Avocet 8051 simulator. The format is similar, but each line is prefixed -by an 'AS' and each symbol value is prefixed by a segment indicator: -
    AS     start          C:1000
-    AS     read_byte      C:1245
-    AS     write_byte     C:1280
-    AS     low_nib_mask   N:000F
-    AS     buffer         X:0080
-The segment prefixes are determined by the most recent segment directive -invoked (see BSEG/CSEG/DSEG/NSEG/XSEG directives). -

-TEXT

-This directive allows an ASCII string to be used to assign values to a -sequence of locations starting at the current Instruction Pointer. The -format is: -
    [label] .TEXT   "string"
-The ASCII value of each character in string is taken and assigned to the -next sequential location. Some escape sequences are supported as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Escape Sequence Description 
\n Line Feed 
\r Carriage return 
\b Backspace 
\t Tab 
\f Formfeed 
\\ Backslash 
\" Quote 
\000 Octal value of character 
- -

Here are some examples: - -

    message1   .TEXT   "Disk I/O error"
-    message2   .text   "Enter file name "
-               .text   "abcdefg\n\r"
-               .text   "I said \"NO\""
- -

-TITLE

-The TITLE directive allows the user to define a title string that appears -at the top of each page of the list file (assuming the PAGE mode is on). -The format is: -
    [label]    .TITLE  "string"
-The string should not exceed 80 characters. Here are some examples: -
    .TITLE  "Controller version 1.1"
-    .title  "This is the title of the assembly"
-    .title  ""
- -

-WORD

-The WORD directive allows a value assignment to the next two bytes pointed -to by the current Instruction Pointer. The format is: -
    [label] .WORD expr [,expr...]
-The least significant byte of expr is put at the current Instruction Pointer -with the most significant byte at the next sequential location (unless -the MSFIRST directive has been invoked). Here are some examples: -
    data_table     .WORD   (data_table + 1)
-                   .word   $1234
-                   .Word   (('x' - 'a')  << 2)
-                   .Word  12, 55, 32
- -
-

-OBJECT FILE FORMATS

-TASM can generate object code in the formats indicated below: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Option Description
-g0 Intel hex (default) 
-g1 MOS Technology hex (same as -m
-g2 Motorola hex 
-g3 binary (same as -b
-g4 Intel hex with word addresses
-

The -m and -b flags may also be used, as indicated above. -If both are used the right-most option on the command line will be obeyed. -

-Intel Hex Object Format

-This is the default object file format. This format is line oriented and -uses only printable ASCII characters except for the carriage return/line -feed at the end of each line. The format is symbolically represented as: - -

:NN AAAA RR HH CC CRLF - -

Where: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
:Record Start Character (colon)
NNByte Count (2 hex digits)
AAAAAddress of first byte (4 hex digits)
RRRecord Type (00 except for last record -which is 01)
HHData Bytes (a pair of hex digits for each byte -of data in the record)
CCCheck Sum (2 hex digits)
CRLFLine Terminator (CR/LF for DOS, LF for LINUX)
-

The last line of the file will be a record conforming to the above format -with a byte count of zero. - -

The checksum is defined as: - -

sum = byte_count+address_hi+address_lo+record_type+(sum of all data -bytes) -
checksum = ((-sum) & ffh) - -

Here is a sample listing file followed by the resulting object file: -

0001   0000             
-0002   1000                     .org   $1000
-0003   1000 010203040506        .byte  1, 2, 3, 4, 5, 6, 7, 8
-0003   1006 0708
-0004   1008 090A0B0C0D0E        .byte  9,10,11,12,13,14,15,16
-0004   100E 0F10
-0005   1010 111213141516        .byte 17,18,19,20,21,22,23,24,25,26
-0005   1016 1718191A
-0006   101A                     .end
- -
    :181000000102030405060708090A0B0C0D0E0F101112131415161718AC
-    :02101800191AA3
-    :00000001FF
- -

-Intel Hex Word Address Object Format

-This format is identical to the Intel Hex Object Format except that -the address for each line of object code is divided by two thus converting -it to a word address (16 bit word). All other fields are identical. - -

Here is an example: -

:180800000102030405060708090A0B0C0D0E0F101112131415161718AC
-:02080C00191AA3
-:00000001FF
- -

-MOS Technology Hex Object Format

-This format is line oriented and uses only printable ASCII characters except -for the carriage return/line feed at the end of each line. Each line in -the file is of the following format: - -

:NN AAAA HH CC CRLF - -

Where: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;Record Start Character (semicolon)
NNByte Count (2 hex digits)
AAAAAddress of first byte (4 hex digits)
HHData Bytes (a pair of hex digits for each byte -of data in the record)
CCCCCheck Sum (4 hex digits)
CRLFLine Terminator (CR/LF for DOS, LF for LINUX)
-

The last line of the file will be a record conforming to the above format -with a byte count of zero. - -

The checksum is defined as: - -

sum =byte_count+address_hi+address_lo+record_type+(sum of all data -bytes) -
checksum = (sum & ffffh) - -

Here is a sample object file: -

;1810000102030405060708090A0B0C0D0E0F1011121314151617180154
-;021018191A005D
-;00
- -

-Motorola Hex Object Format

-This format is line oriented and uses only printable ASCII characters except -for the carriage return/line feed at the end of each line. The format is -symbolically represented as: - -

S1 NN AAAA HH CCCC CRLF - -

Where: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
S1Record Start tag 
NNByte Count (2 hex digits) (data byte count + -3)
AAAAAddress of first byte (4 hex digits)
HHData Bytes (a pair of hex digits for each byte -of data in the record)
CCCheck Sum (2 hex digits)
CRLFLine Terminator (CR/LF for DOS, LF for LINUX)
- -

The checksum is defined as: - -

sum = byte_count+address_hi+address_lo+(sum of all data bytes) -
checksum = ((~sum) & ffh) - -

Here is a sample file: -

S11B10000102030405060708090A0B0C0D0E0F101112131415161718A8
-S1051018191A9F
-S9030000FC
-

The last line of the file will be a record with a byte count of zero and -a tag of S9. The address field will be 0000 unless and address was provided -with the END directive in which case it will appear in the address field. -

-Binary Object Format.

-This file format is essentially a memory image of the object code without -address, checksum or format description information. - -

Note that when this object format is selected (-b option), the -c option -is forced. This is done so that no ambiguity results from the lack of address -information in the file. Without the -c option, discontinuous blocks of -object code would appear contiguous. -
  - -

-


-

-LISTING FILE FORMAT

-Each line of source code generates one (or more) lines of output in the -listing file. The fields of the output line are as follows: -
    -
  1. -Current source file line number (4 decimal digits).
  2. - -
  3. -An optional '+' appears if this is an 'INCLUDE' file. (One '+' for each -level of INCLUDE invoked).
  4. - -
  5. -Current Instruction Pointer (4 hex digits). An optional '~' follows the -Instruction Pointer if the line of source code is not being assembled because -of an IFDEF, IFNDEF, or IF directive.
  6. - -
  7. -Resulting code/data generated from this source line (two hex digits per -byte, each byte separated by a space, up to six bytes per line).
  8. - -
  9. -The source line exactly as it appears in the source file.
  10. -
-If paging is enabled (by either the '-p' option flag or the .PAGE directive) -some additional fields will be inserted into the listing file every 60 -lines. These fields are: -
    -
  1. -Top of Form (form feed).
  2. - -
  3. -Assembler identifier (e.g. "TASM 6502 Assembler").
  4. - -
  5. -Initial source file name.
  6. - -
  7. -Page number.
  8. - -
  9. -Title.
  10. -
-If errors are encountered, then error messages will be interspersed in -the listing. TASM outputs error messages proceeding the offending line. -The following example illustrates the format: -
    0001   0000             label1  .equ  40h
-    0002   0000             label2  .equ  44h
-    0003   0000 
-    0004   1000             start:  .org  1000h
-    0005   1000 E6 40               inc   label1
-    0006   1002 E6 44               inc   label2
-    tt.asm line 0007: Label not found: (label3)
-    0007   1004 EE 00 00            inc   label3
-    0008   1007 4C 00 10            jmp   start
-    0009   100A                     .end  
-    0010   100A                            
-    tasm: Number of errors = 1
- -
-

-PROM PROGRAMMING

-A wide variety of PROM programming equipment is available that can use -object code in one or more of the formats supported by TASM. Here are some -notes concerning the generation of code to be programmed into PROMs: -

-PRESET MEMORY

-It is often desirable to have all bytes in the PROM programmed even if -not explicitly assigned a value in the source code (e.g. the bytes are -skipped over with a .ORG statement). This can be accomplished by using -the -c (contiguous block) and the -f (fill) command line -option flags. The -c will ensure that every byte from the lowest -byte assigned a value to the highest byte assigned a value will be in the -object file with no gaps. The -f flag will assign the specified -value to all bytes before the assembly begins so that when the object file -is written, all bytes not assigned a value in the source code will have -a known value. As an example, the following command line will generate -object code in the default Intel Hex format with all bytes not assigned -a value in the source set to EA (hex, 6502 NOP instruction): -
    tasm -65 -c -fEA test.asm
- -

-CONTIGUOUS BLOCKS

-To ensure that TASM generates object code to cover the full address range -of the target PROM, put a .ORG statement at the end of the source file -set to the last address desired. For example, to generate code to be put -in a 2716 EPROM (2 Kbytes) from hex address $1000 to $17ff, do something -like this in the source file: -
    ;start of the file
-        .ORG    $1000
-    ;rest of the source code follows
-    source code
-    ;end of the source code
-        .ORG    $17ff
-        .BYTE   0
-        .END
-Now, to invoke TASM to generate the code in the binary format with all -unassigned bytes set to 00 (6502 BRK instruction), do the following: -
tasm -65 -b -f00 test.asm
-Note: -b forces the -c option. -
-
-

-ERROR MESSAGES

- -

-Error Message Format

-TASM error messages take the following general form: -
    filename line line_number: error_message
-For example: -
    main.asm line 0032: Duplicate label (start)
-Many editors and IDE’s can run assemblies from within and parse the error -messages to make it convenient to jump to each error and correct.  -If the above format is not satisfactory for your editor or IDE, use the -TASMERRFORMAT environment variable to alter -the error message format. - -

When using automatic invocation of TASM from within an editor or IDE, -it may be useful to use the TASMOPTS environment -variable to set other command line options.  For example, to cause -TASM to perform 6502 assemblies, set TASMOPTS like this: -

    -
    SET TASMOPTS=-65
    -
- -

-ERROR MESSAGE DESCRIPTIONS

- -
-
-Binary operator where value expected
- -
-Two binary operators in a row indicate a missing value.
- -
-Branch off of current 2K page
- -
-An instruction is attempting to branch to a location not within the current -2K byte page.
- -
-Branch off of current page
- -
-An instruction is attempting to branch to a location not within the current -256 byte page.
- -
-Cannot malloc for label storage
- -
-Insufficient memory to store more labels. See LIMITATIONS.
- -
-Duplicate label
- -
-The label for the current line has already been assigned a value. Duplicate -label checks are optionally enabled by the -a option.
- -
-File name too short
- -
-A file name on the command line is fewer than 3 characters. A two character -file name may be valid, of course, but it is detected as an error to prevent -a garbled option flag from being taken as a source file, which in turn -can result in the true source file being taken as the object file. Since -the object file is truncated at startup time, the source file could be -clobbered.
- -
-Forward reference in equate
- -
-An EQU directive is using a label on the right hand side that has not yet -been defined.
- -
-Heap overflow on label definition
- -
-TASM was unable to allocate memory to store the label.
- -
-Imbalanced conditional.
- -
-An end-of-file was encountered at which time the level of descent in conditional -directives was different from when the file was entered. Conditional directives -include IF, IFDEF, and IFNDEF.
- -
-Invalid Object file type.
- -
-An object file type was requested by the -g command line option that is -not valid. See section on Option g - Object File Format.
- -
-Invalid operand.
- -
-No indirection for this instruction. The first character of an operand -was a left parenthesis for an instruction that does not explicitly specify -that as the format. Some micros use the parenthesis as an indicator of -indirection, but putting a layer of parenthesis around an expression is -always a valid thing to do (as far as the expression evaluator is concerned). -The test for this case is only done if the -a4 option is selected. -See section on ASSEMBLY CONTROL.
- -
-Invalid token where value expected.
- -
-Two binary operators in a row are not allowed.
- -
-Label too long.
- -
-Labels are limited to 31 characters.
- -
-Label value misaligned
- -
-The value of a label appears to have a different value on the second pass -then it was computed to have on the first pass. This is generally due to -Zero Page Addressing mode problems with the 6502 version of TASM. Labels -that are used in operands for statements that could utilize Zero Page addressing -mode should always be defined before used as an operand.
- -
-Label not found
- -
-A label used in an expression was not found in the current label table.
- -
-Label must pre-exist for SET.
- -
-The SET directive can only be applied to an existing label.
- -
-Label table overflow
- -
-To many labels have been encountered.
- -
-List file open error
- -
-TASM was not able to open the specified list file.
- -
-Macro expansion too long.
- -
-The expansion of a macro resulted in a line that exceeded the maximum length.
- -
-Max number of nested conditionals exceeded
- -
-Too many levels of IF, IFDEF, or IFNDEF.
- -
-Maximum number of args exceeded
- -
-Too many macro arguments.
- -
-Maximum number of macros exceeded
- -
-Too many macros (DEFINEs) have been encountered.
- -
-No END directive before EOF
- -
-The source file did not have an END directive in it. This is not fatal, -but may cause the last object file record to be lost.
- -
-No files specified
- -
-TASM was invoked with no source file specified.
- -
-No such label
- -
-A SET directive was encountered for a label not yet defined. The value -of labels that are modified by the SET directive must already exist.
- -
-No terminating quote
- -
-A double quote was used at the start of a a text string but was not used -at the end of the string.
- -
-No indirection for this instruction.
- -
-A parenthesis was found around the operand expression. This may indicate -an attempt to use indirection where it is inappropriate.
- -
-Non-unary operator at start of expression
- -
-A binary operator (such as '*') was found at the beginning of an expression. -Some micros use '*' as an indirection operator. Since it is also a legitimate -operator in an expression, some ambiguity can arise. If a particular instruction/addressing -mode does not allow indirection, and a '*' is placed in front of the associated -expression, the assembler will assume this error. See the -a8 option -of ASSEMBLY CONTROL.
- -
-Object file open error
- -
-TASM was not able to open the specified object file.
- -
-Range of argument exceeded
- -
-The value of an argument exceeds the valid range for the current instruction -and addressing mode.
- -
-Range of relative branch exceeded
- -
-A branch instruction exceeds the maximum range.
- -
-Source file open error
- -
-TASM was not able to open the specified source file.
- -
-Unrecognized directive
- -
-A statement starting with a '.' or '#' has a mnemonic that is not defined -as a directive.
- -
-Unrecognized instruction
- -
-A statement has an opcode mnemonic that is not defined.
- -
-Unrecognized argument
- -
-A statement has an operand format that is not defined.
- -
-Unknown token
- -
-Unexpected characters were encountered while parsing an expression.
- -
-Unused data in MS byte of argument
- -
-An instruction or directive used the least significant byte of an argument -and left the most significant byte unused, but it was non-zero.
- -
-Unknown option Flag.
- -
-Invalid option flag has been specified on the command line. invoke TASM -with nothing on the command line to see a list of valid options.
-
- -
-

-LIMITATIONS

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Maximum number of labels 15000 
Maximum length of labels 32 characters 
Maximum address space 64 Kbytes (65536 bytes) 
Maximum number of nested INCLUDES
Maximum length of TITLE string 79 characters 
Maximum source line length 511 characters 
Maximum length after macro expansion 511 characters 
Maximum length of expressions 511 characters 
Maximum length of pathnames 79 characters 
Maximum length of command line 127 characters 
Maximum number of instructions (per table) 1200 
Maximum number of macros 1000 
Maximum number of macro arguments 10 
Maximum length of macro argument 16 characters 
Memory requirements 512K 
- -

-Other Limitations

- -
    -
  1. -The 8048 version of TASM does not check for use of memory beyond any reasonable -bounds (e.g. an 8048 has a maximum address space of 4 Kbytes but TASM will -let you pretend that you have 64 Kbytes).
  2. - -
  3. -Expression evaluation has no operator precedence in effect which can make -for unexpected results if not explicitly grouped with parenthesis.
  4. - -
  5. -First page of listing file will not show a user defined title (defined -via TITLE directive).
  6. -
- -
-
Top - - diff --git a/branches/s100/Tools/tasm32/TASMTABS.HTM b/branches/s100/Tools/tasm32/TASMTABS.HTM deleted file mode 100644 index 0f8297a7..00000000 --- a/branches/s100/Tools/tasm32/TASMTABS.HTM +++ /dev/null @@ -1,2989 +0,0 @@ - - - -TASM Table Syntax - -

TASM TABLE SYNTAX DESCRIPTION

-

The tables that control TASM's interpretation of the source file are read -from a file at run time. The table file name is determined by taking the -numeric option field specified on the TASM command line and appending it to the -string "TASM", then a ".TAB" extension is added. Thus, -if the following command line is entered: -

-
        tasm -51  test.asm
-
-

then TASM would read the table file named "TASM51.TAB". -

-

The following rules apply to the structure of the table file: -

-
    -
  • The first line of the file should contain a string surrounded by double -quotes that should identify the version of the assembler table. This string -will appear at the top of each page in the list file. It should be limited to -24 characters.
  • -
  • Any line that starts with a '.' is considered a directive. Directives -should preceed instruction defintion lines. The following directives are -available: -
- - - - - - - - - - - - - - - - - - -
DIRECTIVEDESCRIPTION
MSFIRSTGenerate opcodes MS byte first. Useful for tables with multibyte opcodes.
ALTWILDUse '@' instead of '*' as the wild card in the table. Useful if the -instruction syntax uses '*' to denote certain addressing modes.
NOARGSHIFTSuppress the shift/or operation that applies if the optional SHIFT and OR -fields are provided. Some RULEs use the SHIFT/OR fields for other purposes.
REGSETDefine a register mnemonic and associated bit field. See example below.
WORDADDRSSet word addressing mode (one word = 2 bytes)
-
    -
  • Any line whose first character is not a '.' and is not alphabetic is -considered to be a comment and is discarded.
  • -
  • Any line that has an alphabetic character as the first character is assumed -to be an instruction definition record and is parsed to build the internal -representation of the instruction set tables. Eight fields (separated by white -space) are expected, as follows: -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field Name Description
INSTRUCTION Instruction Mnemonic
ARGS Argument definition
OPCODE Opcode value
NBYTES Number of bytes
RULE Modifier operation
CLASS Instruction class
SHIFT Argument left shift count
OR Argument bitwise OR mask
-

The fields are further defined below:

-
-
INSTRUCTION
-
The INSTRUCTION field should contain the string to be used as the mnemonic -for this instruction. Upper case letters should be used (the source statements -are converted to upper case before comparison).
-
ARGS.
-
The ARGS field should contain a string describing the format of the operand -field. All characters are taken literally except the '*' which denotes the -presence of a valid TASM expression. Multiple '*'s can be used, but all but the -last one must be followed by a comma, '[', or ']'. If a single '*' appears in -the ARGS field, then the default action of TASM will be to determine the value -of the expression that matches the field and insert one or two bytes of it into -the object file depending on the NBYTES field. If multiple '*'s are used, then -special operators (RULE) must be used to take advantage of them (see the -examples below). An ARGS field of a pair of double quotes means that no -arguments are expected. -
-
OPCODE.
-
The OPCODE field should contain the opcode value (two to six hex digits) -for this instruction and address mode. Each pair of hex digits represent a -single byte of the opcode, ordered with the right most pair being placed in the -lowest memory location. -
-
NBYTES.
-
The NBYTES field should specify the number of bytes this instruction is to -occupy (a single decimal digit). This number includes both opcode bytes and -argument bytes, thus, the number of bytes of argument is computed by subtracting -the number of bytes of opcode (dictated by the length of the OPCODE field) from -NBYTES. -
-
RULE.
-
The RULE field determines if any special operations need to be performed -on the code generated for this instruction. For example, the zero-page -addressing mode of the 6502 is a special case of the absolute addressing mode, -and is handled by a special RULE code. See the Encoding Rules below. -
-
CLASS.
-
The CLASS field is used to specify whether this instruction is part of the -standard instruction set or a member of a set of extended instructions. Bit 0 of -this field should be set to denote a member of the standard instruction set. -Other bits can be used as needed to establish several classes (or sets) of -instructions that can be enabled or disabled via the '-x' command line option. - -
-
SHIFT (optional).
-
The SHIFT field is used to cause the first argument of the given -instruction to be shifted left the specified number of bits. (Except T1, TDMA, -TAR RULES as noted below). -
-
OR (optional).
-
The OR field is used to perform a bitwise OR with the first argument of the -given instruction. Specified as hex digits. (Except T1, TDMA, TAR RULES as -noted below). -
-

Note that the SHIFT/OR fields are used somewhat differently for T1, TDMA, -and TAR RULES. In those cases, the SHIFT and OR fields are used but the OR -field is really an AND mask and the result is OR'd with the opcode. -

-

Encoding Rules

-

The following encoding rules are available:

-
-
NOTOUCH or NOP
-
Do nothing to instruction or args
-
JMPPAGE
-
Put bits 8-10 of first arg into bits 5-7 of opcode (8048 JMP)
-
ZPAGE
-
If arg < 256 then use zero-page (6502)
-
R1
-
Make arg relative to PC (single byte)
-
R2
-
Make arg relative to PC (two byte)
-
CREL
-
Combine LS bytes of first two args making the second one relative to PC
-
SWAP
-
Swap bytes of first arg
-
COMBINE
-
Combine LS bytes of first two args into first arg (arg1 -> LSB, arg2 ->MSB).
-
CSWAP
-
Combine LS bytes of first two args into first arg and swap.
-
ZBIT
-
Z80 bit instructions.
-
ZIDX
-
Z80 Indexed Instructions (e.g. ADC A,(IX+x))
-
MBIT
-
Motorola (6805) bit instructions
-
MZERO
-
Motorola (6805) zero page (direct)
-
3ARG
-
Three args, one byte each.
-
3REL
-
Three args, one byte each, last one relative
-
T1
-
TMS320 instruction with one arg. Shift according to SHIFT and mask with OR -and OR into opcode. If a second arg exists assume it is an arp and OR intoLSB -of opcode.
-
TDMA
-
TMS320 instruction with first arg dma. Second arg gets shift/and/or -treatment as with T1.
-
TAR
-
TMS320 instruction with first arg ar. Second arg gets shift/and/or -treatment as with T1.
-
I1
-
I8096 Combine
-
I2
-
I8096 two far args
-
I3
-
I8096 three far args
-
I4
-
I8096 Jump with bit mask
-
I5
-
I8096 Relative
-
I6
-
I8096 Indirect
-
I7
-
I8096 One far arg
-
I8
-
I8096 Jump
-

Encoding Examples

-

Note that the reason for the combining of arguments (COMBINE and CSWAP) is -that TASM assumes that all object bytes to be inserted in the object file are -derived from a variable representing the value of the first argument (argval). -If two arguments are in the ARGS field, then one of the previously mentioned -RULE`s must be used. They have the effect of combining the low bytes of the -first two arguments into the variable (argval) from which the object code will -be generated. TASM`s argument parsing routine can handle a large number of -arguments, but the code that generates the object code is less capable. -

-

The following table shows possible instruction definition records, followed -by possible source statements that would match it, followed by the resulting -object code that would be generated (in hex): -

-
                                          EXAMPLE         EXAMPLE
-INSTRUCTION DEFINITION                    SOURCE          OBJECT
--------------------------------------------------------------------
-XYZ  *      FF   3  NOTOUCH 1             xyz 1234h       FF 34 12
-XYZ  *      FF   2  NOTOUCH 1             xyz 1234h       FF 34
-ZYX  *      FE   3  SWAP    1             zyx 1234h       FE 12 34
-ZYX  *      FE   3  R2      1             zyx $+4         FE 01 00
-ABC  *,*    FD   3  COMBINE 1             abc 45h,67h     FD 45 67
-ABC  *,*    FD   3  CSWAP   1             abc 45h,67h     FD 67 45
-ADD  A,#*   FC   2  NOTOUCH 1             add A,#'B'      FC 42
-RET  ""     FB   1  NOTOUCH 1             ret             FB
-LD   IX,*   21DD 4  NOTOUCH 1             ld  IX,1234h    DD 21 34 12
-LD   IX,*   21DD 4  NOTOUCH 1 1 0         ld  IX,1234h    DD 21 68 24
-LD   IX,*   21DD 4  NOTOUCH 1 0 1         ld  IX,1234h    DD 21 35 12
-LD   IX,*   21DD 4  NOTOUCH 1 1 1         ld  IX,1234h    DD 21 69 24
-LD   IX,*   21DD 4  NOTOUCH 1 8 12        ld  IX,34h      DD 21 12 34
-
-

The order of the entries for various addressing modes of a given instruction -is important. Since the wild card matches anything, it is important to specify -the ARGS for the addressing modes that have the most qualifying characters -first. For example, if an instruction had two addressing modes, one that -accepted any expression, and another that required a pound sign in front of an -expression, the pound sign entry should go first otherwise all occurrences of -the instruction would match the more general ARGS expression that it -encountered first. The following entries illustrate the proper sequencing: -

-
        ADD #*  12 3 NOTOUCH 1
-        ADD *   13 3 NOTOUCH 1
-
-

Table Lookup Method

-

The current version of TASM uses a very simple hashing method based on the -first character of the nmemonic. A search is begun at the first table entry -that starts with that letter. Thus, the table should be sorted alphabetically -for optimum lookup speed. If the table is not sorted in this way it will not -break anything, but just slow it down a bit.

-

REGSET Directive

-

For instruction sets that have a well defined set of registers that map to a -bit field in the opcode it may be convenient to use the REGSET directive. The -value field following each register definition is OR'd into the opcode when a -match is found. The '!' character is used to indicate the expected occurance of -a register. Consider the following example:

-
.REGSET R0  00 1
-.REGSET R1  01 1
-.REGSET R2  02 1
-.REGSET R3  03 1
-.REGSET R4  04 1
-.REGSET R5  05 1
-.REGSET R6  06 1
-.REGSET R7  07 1
-
-...
-INC !  E0  1 NOP
-...
-
-

A source instruction INC R3 would be encoded by ORing E0 with 03 -resulting in E3.

-
-

6502 INSTRUCTIONS AND ADDRESSING MODES

-

The acceptable 6502 opcode mnemonics for TASM are as follows: -

-
 ADC  AND  ASL  BCC  BCS  BEQ  BNE  BMI  BPL  BVC  BVS  BIT
- BRK  CLC  CLD  CLI  CLV  CMP  CPX  CPY  DEC  DEX  DEY  EOR
- INC  INX  INY  JMP  JSR  LDA  LDX  LDY  LSR  NOP  ORA  PHA
- PHP  PLA  PLP  ROL  ROR  RTI  RTS  SBC  SEC  SED  SEI  STA
- STX  STY  TAX  TAY  TSX  TXA  TXS  TYA
-
-

TASM also supports the following instructions that are part of the -Rockwell R65C02 and R65C00/21 microprocessor instruction sets. Those that - are marked as set A are applicable to the R65C02 and those marked as set B -are applicable to the R65C00/21 (A+B for both): -

-
        Mnemonic        Description                Address Mode  Set
-        ---------------------------------------------------------------
-        ADC             Add with carry             (IND)         A
-        AND             And memory with A          (IND)         A
-        BIT             Test memory bits with A    ABS,X         A
-        BIT             Test memory bits with A    ZP,X          A
-        BIT             Test memory bits with A    IMM           A
-        CMP             Compare memory with A      (IND)         A
-        DEC             Decrement A                A             A
-        EOR             Exclusive OR memory with A (IND)         A
-        INC             Increment A                A             A
-        JMP             Jump                       (ABS,X)       A
-        LDA             Load A with memory         (IND)         A
-        ORA             OR A with memory           (IND)         A
-        SBC             Subtract memory form A     (IND)         A
-        STA             Store A in memory          (IND)         A
-        STZ             Store zero                 ABS           A
-        STZ             Store zero                 ABS,X         A
-        STZ             Store zero                 ZP            A
-        STZ             Store zero                 ZP,X          A
-        TRB             Test and reset memory bit  ABS           A
-        TRB             Test and reset memory bit  ZP            A
-        TSB             Test and set memory bit    ABS           A
-        TSB             Test and set memory bit    ZP            A
-
-        BRA             Branch Always              REL           A+B
-
-        BBR0            Branch on Bit 0 Reset      ZP,REL        A+B
-        BBR1            Branch on Bit 1 Reset      ZP,REL        A+B
-        BBR2            Branch on Bit 2 Reset      ZP,REL        A+B
-        BBR3            Branch on Bit 3 Reset      ZP,REL        A+B
-        BBR4            Branch on Bit 4 Reset      ZP,REL        A+B
-        BBR5            Branch on Bit 5 Reset      ZP,REL        A+B
-        BBR6            Branch on Bit 6 Reset      ZP,REL        A+B
-        BBR7            Branch on Bit 7 Reset      ZP,REL        A+B
-
-        BBS0            Branch on Bit 0 Set        ZP,REL        A+B
-        BBS1            Branch on Bit 1 Set        ZP,REL        A+B
-        BBS2            Branch on Bit 2 Set        ZP,REL        A+B
-        BBS3            Branch on Bit 3 Set        ZP,REL        A+B
-        BBS4            Branch on Bit 4 Set        ZP,REL        A+B
-        BBS5            Branch on Bit 5 Set        ZP,REL        A+B
-        BBS6            Branch on Bit 6 Set        ZP,REL        A+B
-        BBS7            Branch on Bit 7 Set        ZP,REL        A+B
-
-        MUL             Multiply                   Implied       B
-
-        PHX             Push Index X               Implied       A+B
-        PHY             Push Index Y               Implied       A+B
-        PLX             Pull Index X               Implied       A+B
-        PLY             Pull Index Y               Implied       A+B
-
-        RMB0            Reset Memory Bit 0         ZP            A+B
-        RMB1            Reset Memory Bit 1         ZP            A+B
-        RMB2            Reset Memory Bit 2         ZP            A+B
-        RMB3            Reset Memory Bit 3         ZP            A+B
-        RMB4            Reset Memory Bit 4         ZP            A+B
-        RMB5            Reset Memory Bit 5         ZP            A+B
-        RMB6            Reset Memory Bit 6         ZP            A+B
-        RMB7            Reset Memory Bit 7         ZP            A+B
-
-        SMB0            Set   Memory Bit 0         ZP            A+B
-        SMB1            Set   Memory Bit 1         ZP            A+B
-        SMB2            Set   Memory Bit 2         ZP            A+B
-        SMB3            Set   Memory Bit 3         ZP            A+B
-        SMB4            Set   Memory Bit 4         ZP            A+B
-        SMB5            Set   Memory Bit 5         ZP            A+B
-        SMB6            Set   Memory Bit 6         ZP            A+B
-        SMB7            Set   Memory Bit 7         ZP            A+B
-
-

Addressing modes are denoted as follows: -

-
ABS               Absolute
-ZP                Zero Page
-ABS,X             Absolute X
-ZP,X              Zero Page X
-ABS,Y             Absolute Y
-ZP,Y              Zero Page Y
-A                 Accumulator
-(IND,X)           Indirect X
-(IND),Y           Indirect Y
-(IND)             Indirect
-#IMM              Immediate
-REL               Relative (Branch instructions only)
-ZP,REL            Zero Page, Relative
-Implied           Implied
-
-

Note that Zero Page addressing can not be explicitly requested. It is used -if the value of the operand is representable in a single byte for the -applicable statements. -

-

The '-x' command line option can be used to enable the extended -instructions. A '-x' with no digit following will enable the standard set plus -both extended sets. The 6502 version of TASM uses three bits in the instruction -class mask to determine whether a given instruction is enabled or not. Bit 0 -enables the basic set, bit 1 enables set A (R65C02) and bit 2 enables set B -(R65C00/21). The following table shows various options: -

-
Class Mask        Enabled Instructions
-                BASIC   R65C02  R65C00/21
---------------------------------------------
-1               yes     no      no
-2               no      yes     no
-3               yes     yes     no
-4               no      no      yes
-5               yes     no      yes
-6               no      yes     yes
-7               yes     yes     yes
-
-

Thus, to enable the basic set plus the R65C02 instructions, invoke the -'-x3' command line option. -

-

See manufacturer's data for a more complete description of the meaning of -the mnemonics and addressing modes. -

-
-

68xx INSTRUCTIONS AND ADDRESSING MODES -

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 6800/68HC11 version of TASM. Symbolic -fields are defined as follows: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr8_             Absolute address (8 bits)
-_addr16_            Absolute address (16 bits)
-                      Values that can fit in 8 bits can
-                      result in the DIRECT addressing mode.
-_addr16_no8_        Absolute address (16 bits)
-                      DIRECT addressing not applicable.
-_bmsk_              Bit mask (8 bits)
-_rel8_              Relative address (8 bit signed)
-_immed8_            Immediate data (8 bits)
-_immed16_           Immediate data (16 bits)
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-

The lines that are marked with an 'a' or 'b' are extended instructions that -are available only if a -x option has been invoked on the command line. The -classes of instructions (and their bit assignment in the class mask) are shown -below: -

-
BIT     PROCESSOR      EXT LABEL     COMMAND LINE OPTION
---------------------------------------------------------
-0       6800
-1       6801/6803       a            -x3
-2       68HC11          b            -x7
-
-

Thus, to enable the 68HC11 instructions, a -x7 could be used on the command -line. -

-

TASM deviates from standard Motorola syntax for the BSET, BRSET, BCLR, -and BRCLR instructions. TASM requires commas separating all arguments. -Motorola assemblers use white space to separate the last one or two -arguments for these instructions. Here are examples of each applicable -instruction: -

-
TASM                                MOTOROLA
-----------------------              --------------------
-BCLR    _addr8_,Y,_bmsk_            BCLR    _addr8_,Y _bmsk_
-BCLR    _addr8_,X,_bmsk_            BCLR    _addr8_,X _bmsk_
-BCLR    _addr8_  ,_bmsk_            BCLR    _addr8_   _bmsk_
-BSET    _addr8_,Y,_bmsk_            BSET    _addr8_,Y _bmsk_
-BSET    _addr8_,X,_bmsk_            BSET    _addr8_,X _bmsk_
-BSET    _addr8_  ,_bmsk_            BSET    _addr8_   _bmsk_
-BRCLR   _addr8_,Y,_bmsk_,_rel8_     BRCLR   _addr8_,Y _bmsk_ _rel8_
-BRCLR   _addr8_,X,_bmsk_,_rel8_     BRCLR   _addr8_,X _bmsk_ _rel8_
-BRCLR   _addr8_  ,_bmsk_,_rel8_     BRCLR   _addr8_   _bmsk_ _rel8_
-BRSET   _addr8_,Y,_bmsk_,_rel8_     BRSET   _addr8_,Y _bmsk_ _rel8_
-BRSET   _addr8_,X,_bmsk_,_rel8_     BRSET   _addr8_,X _bmsk_ _rel8_
-BRSET   _addr8_  ,_bmsk_,_rel8_     BRSET   _addr8_   _bmsk_ _rel8_
-
-
OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-ABA                          Add Accumulator B to Accumulator A
-ABX                     a    Add Accumulator B to Index Reg X
-ABY                     b    Add Accumulator B to Index reg Y
-
-ADCA    #_immed8_            Add with carry immediate  to Reg A
-ADCA    _addr8_,X            Add with carry indirect,X to Reg A
-ADCA    _addr8_,Y       b    Add with carry indirect,Y to Reg A
-ADCA    _addr16_             Add with carry extended   to Reg A
-
-ADCB    #_immed8_            Add with carry immediate  to Reg B
-ADCB    _addr8_,X            Add with carry indirect,X to Reg B
-ADCB    _addr8_,Y       b    Add with carry indirect,Y to Reg B
-ADCB    _addr16_             Add with carry extended   to Reg B
-
-ADDA    #_immed8_            Add w/o  carry immediate  to Reg A
-ADDA    _addr8_,X            Add w/o  carry indirect,X to Reg A
-ADDA    _addr8_,Y       b    Add w/o  carry indirect,Y to Reg A
-ADDA    _addr16_             Add w/o  carry extended   to Reg A
-
-ADDB    #_immed8_            Add w/o  carry immediate  to Reg B
-ADDB    _addr8_,X            Add w/o  carry indirect,X to Reg B
-ADDB    _addr8_,Y       b    Add w/o  carry indirect,Y to Reg B
-ADDB    _addr16_             Add w/o  carry extended   to Reg B
-
-ADDD    #_immed8_       a    Add double immediate  to Reg D
-ADDD    _addr8_,X       a    Add double indirect,X to Reg D
-ADDD    _addr8_,Y       b    Add double indirect,Y to Reg D
-ADDD    _addr16_        a    Add double extended   to Reg D
-
-ANDA    #_immed8_            AND immediate  to Reg A
-ANDA    _addr8_,X            AND indirect,X to Reg A
-ANDA    _addr8_,Y       b    AND indirect,Y to Reg A
-ANDA    _addr16_             AND extended   to Reg A
-
-ANDB    #_immed8_            AND immediate  to Reg B
-ANDB    _addr8_,X            AND indirect,X to Reg B
-ANDB    _addr8_,Y       b    AND indirect,Y to Reg B
-ANDB    _addr16_             AND extended   to Reg B
-
-ASL     _addr8_,X            Arithmetic shift left indirect,X
-ASL     _addr8_,Y       b    Arithmetic shift left indirect,Y
-ASL     _addr16_             Arithmetic shift left extended
-ASLA                         Arithmetic shift left Reg A
-ASLB                         Arithmetic shift left Reg B
-ASLD                    a    Arithmetic shift left double Reg D
-
-ASR     _addr8_,X            Arithmetic shift right indirect,X
-ASR     _addr8_,Y       b    Arithmetic shift right indirect,Y
-ASR     _addr16_             Arithmetic shift right extended
-ASRA                         Arithmetic shift right Reg A
-ASRB                         Arithmetic shift right Reg B
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-BCC     _rel8_               Branch if carry clear
-BCS     _rel8_               Branch if carry set
-BEQ     _rel8_               Branch if equal
-BGE     _rel8_               Branch if greater or equal
-BGT     _rel8_               Branch if greater
-BHI     _rel8_               Branch if higher
-BHS     _rel8_               Branch if higher or same
-BRA     _rel8_               Branch always
-
-BITA    #_immed8_            AND immediate  with Reg A (set condition codes)
-BITA    _addr8_,X            AND indirect,X with Reg A (set condition codes)
-BITA    _addr8_,Y       b    AND indirect,Y with Reg A (set condition codes)
-BITA    _addr16_             AND extended   with Reg A (set condition codes)
-
-BITB    #_immed8_            AND immediate  with Reg B (set condition codes)
-BITB    _addr8_,X            AND indirect,X with Reg B (set condition codes)
-BITB    _addr8_,Y       b    AND indirect,Y with Reg B (set condition codes)
-BITB    _addr16_             AND extended   with Reg B (set condition codes)
-
-BLE     _rel8_               Branch if less than or equal
-BLO     _rel8_               Branch if lower (same as BCS)
-BLS     _rel8_               Branch if lower or same
-BLT     _rel8_               Branch if less than zero
-BMI     _rel8_               Branch if minus
-BNE     _rel8_               Branch if not equal
-BPL     _rel8_               Branch if plus
-BRA     _rel8_               Branch always
-
-BRCLR _addr8_,X,_bmsk_,_rel8_  b Branch if bits clear indirect X
-BRCLR _addr8_,Y,_bmsk_,_rel8_  b Branch if bits clear indirect Y
-BRCLR _addr8_,_bmsk_,  _rel8_  b Branch if bits clear direct
-
-BRN     _rel8_               Branch never
-
-BRSET _addr8_,X,_bmsk_,_rel8_  b Branch if bits set indirect X
-BRSET _addr8_,Y,_bmsk_,_rel8_  b Branch if bits set indirect Y
-BRSET _addr8_,_bmsk_,  _rel8_  b Branch if bits set direct
-
-BSET    _addr8_,X,_bmsk_ b   Bit set indirect X
-BSET    _addr8_,Y,_bmsk_ b   Bit set indirect Y
-BSET    _addr8_,_bmsk_   b   Bit set direct
-BSET    _addr8_,#_bmsk_  b   Bit set direct (alternate form)
-
-BSR     _rel8_               Branch subroutine
-BVC     _rel8_               Branch if overflow clear
-BVS     _rel8_               Branch if overflow set
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-CBA                          Compare registers A & B
-CLC                          Clear Carry
-CLI                          Clear Interrupt Mask
-
-CLR     _addr8_,X            Arithmetic shift right indirect,X
-CLR     _addr8_,Y       b    Arithmetic shift right indirect,Y
-CLR     _addr16_             Arithmetic shift right extended
-CLRA                         Arithmetic shift right Reg A
-CLRB                         Arithmetic shift right Reg B
-
-CLV                          Clear Overflow Bit
-
-CMPA    #_immed8_            Compare immediate  with Reg A
-CMPA    _addr8_,X            Compare indirect,X with Reg A
-CMPA    _addr8_,Y       b    Compare indirect,Y with Reg A
-CMPA    _addr16_             Compare extended   with Reg A
-
-CMPB    #_immed8_            Compare immediate  with Reg B
-CMPB    _addr8_,X            Compare indirect,X with Reg B
-CMPB    _addr8_,Y       b    Compare indirect,Y with Reg B
-CMPB    _addr16_             Compare extended   with Reg B
-
-COM     _addr8_,X            Complement indirect,X
-COM     _addr8_,Y       b    Complement indirect,Y
-COM     _addr16_             Complement extended
-COMA                         Complement Reg A
-COMB                         Complement Reg B
-
-CPD     #_immed16_      b    Compare double immediate  to Reg D
-CPD     _addr8_,X       b    Compare double indirect,X to Reg D
-CPD     _addr8_,Y       b    Compare double indirect,Y to Reg D
-CPD     _addr16_        b    Compare double extended   to Reg D
-
-CPX     #_immed8_            Compare double immediate  to Reg X
-CPX     _addr8_,X            Compare double indirect,X to Reg X
-CPX     _addr8_,Y       b    Compare double indirect,Y to Reg X
-CPX     _addr16_             Compare double extended   to Reg X
-
-CPY     #_immed8_       b    Compare double immediate  to Reg Y
-CPY     _addr8_,X       b    Compare double indirect,X to Reg Y
-CPY     _addr8_,Y       b    Compare double indirect,Y to Reg Y
-CPY     _addr16_        b    Compare double extended   to Reg Y
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-DAA                          Decimal Adjust Reg A
-
-DEC     _addr8_,X            Decrement indirect,X
-DEC     _addr8_,Y            Decrement indirect,Y
-DEC     _addr16_no8_         Decrement extended
-DECA                         Decrement Reg A
-DECB                         Decrement Reg B
-DES                          Decrement stack pointer
-DEX                          Decrement Reg X
-DEY                     b    Decrement Reg Y
-
-EORA    #_immed8_            Exclusive OR immediate  with Reg A
-EORA    _addr8_,X            Exclusive OR indirect,X with Reg A
-EORA    _addr8_,Y       b    Exclusive OR indirect,Y with Reg A
-EORA    _addr16_             Exclusive OR extended   with Reg A
-
-EORB    #_immed8_            Exclusive OR immediate  with Reg B
-EORB    _addr8_,X            Exclusive OR indirect,X with Reg B
-EORB    _addr8_,Y       b    Exclusive OR indirect,Y with Reg B
-EORB    _addr16_             Exclusive OR extended   with Reg B
-
-FDIV                    b    Fractional Divide (ACCD/IX)
-IDIV                    b    Integer Divide (ACCD/IX)
-
-INC     _addr8_,X            Increment indirect,X
-INC     _addr8_,Y            Increment indirect,Y
-INC     _addr16_no8_         Increment extended
-INCA                         Increment Reg A
-INCB                         Increment Reg B
-INS                          Increment stack pointer
-INX                          Increment Reg X
-INY                     b    Increment Reg Y
-
-JMP     _addr8_,X            Jump indirect,X
-JMP     _addr8_,Y       b    Jump indirect,Y
-JMP     _addr16_no8_         Jump extended
-
-JSR     _addr8_,X            Jump Subroutine indirect,X
-JSR     _addr8_,Y       b    Jump Subroutine indirect,Y
-JSR     _addr16_             Jump Subroutine extended
-
-LDAA    #_immed8_            Load Accumulator immediate  with Reg A
-LDAA    _addr8_,X            Load Accumulator indirect,X with Reg A
-LDAA    _addr8_,Y       b    Load Accumulator indirect,Y with Reg A
-LDAA    _addr16_             Load Accumulator extended   with Reg A
-
-LDAB    #_immed8_            Load Accumulator immediate  with Reg B
-LDAB    _addr8_,X            Load Accumulator indirect,X with Reg B
-LDAB    _addr8_,Y       b    Load Accumulator indirect,Y with Reg B
-LDAB    _addr16_             Load Accumulator extended   with Reg B
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-LDD     #_immed16_      a    Load double immediate  to Reg D
-LDD     _addr8_,X       a    Load double indirect,X to Reg D
-LDD     _addr8_,Y       b    Load double indirect,Y to Reg D
-LDD     _addr16_        a    Load double extended   to Reg D
-
-LDS     #_immed16_           Load double immediate  to Reg D
-LDS     _addr8_,X            Load double indirect,X to Reg D
-LDS     _addr8_,Y       b    Load double indirect,Y to Reg D
-LDS     _addr16_             Load double extended   to Reg D
-
-LDX     #_immed16_           Load immediate  to Reg X
-LDX     _addr8_,X            Load indirect,X to Reg X
-LDX     _addr8_,Y       b    Load indirect,Y to Reg X
-LDX     _addr16_             Load extended   to Reg X
-
-LDY     #_immed16_      b    Load immediate  to Reg Y
-LDY     _addr8_,X       b    Load indirect,X to Reg Y
-LDY     _addr8_,Y       b    Load indirect,Y to Reg Y
-LDY     _addr16_        b    Load extended   to Reg Y
-
-LSL     _addr8_,X            Logical Shift Left indirect,X
-LSL     _addr8_,Y       b    Logical Shift Left indirect,Y
-LSL     _addr16_no8_         Logical Shift Left extended
-LSLA                         Logical Shift Left Reg A
-LSLB                         Logical Shift Left Reg B
-LSLD                         Logical Shift Left Double Reg D
-
-LSR     _addr8_,X            Logical Shift Right indirect,X
-LSR     _addr8_,Y       b    Logical Shift Right indirect,Y
-LSR     _addr16_no8_         Logical Shift Right extended
-LSRA                         Logical Shift Right Reg A
-LSRB                         Logical Shift Right Reg B
-LSRD                         Logical Shift Right Double Reg D
-
-MUL                          Multiply Unsigned
-
-NEG     _addr8_,X            Negate indirect,X
-NEG     _addr8_,Y       b    Negate indirect,Y
-NEG     _addr16_no8_         Negate extended
-NEGA                         Negate Reg A
-NEGB                         Negate Reg B
-
-NOP                          No Operation
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-ORAA    #_immed8_            Inclusive OR immediate  with Reg A
-ORAA    _addr8_,X            Inclusive OR indirect,X with Reg A
-ORAA    _addr8_,Y       b    Inclusive OR indirect,Y with Reg A
-ORAA    _addr16_             Inclusive OR extended   with Reg A
-
-ORAB    #_immed8_            Inclusive OR immediate  with Reg B
-ORAB    _addr8_,X            Inclusive OR indirect,X with Reg B
-ORAB    _addr8_,Y       b    Inclusive OR indirect,Y with Reg B
-ORAB    _addr16_             Inclusive OR extended   with Reg B
-
-PSHA                         Push Reg A onto stack
-PSHB                         Push Reg B onto stack
-PSHX                         Push Reg X onto stack
-PSHY                         Push Reg Y onto stack
-
-PULA                         Pull Reg A from stack
-PULB                         Pull Reg B from stack
-PULX                         Pull Reg X from stack
-PULY                         Pull Reg Y from stack
-
-ROL     _addr8_,X            Rotate Left indirect,X
-ROL     _addr8_,Y            Rotate Left indirect,Y
-ROL     _addr16_no8_         Rotate Left extended
-ROLA                         Rotate Left Reg A
-ROLB                         Rotate Left Reg B
-
-ROR     _addr8_,X            Rotate Right indirect,X
-ROR     _addr8_,Y            Rotate Right indirect,Y
-ROR     _addr16_no8_         Rotate Right extended
-RORA                         Rotate Right Reg A
-RORB                         Rotate Right Reg B
-RTI                          Return from Interrupt
-RTS                          Return from subroutine
-
-SBA                          Subtract Accumulators
-SBCA    #_immed8_            Subtract with Carry immediate  with Reg A
-SBCA    _addr8_,X            Subtract with Carry indirect,X with Reg A
-SBCA    _addr8_,Y       b    Subtract with Carry indirect,Y with Reg A
-SBCA    _addr16_             Subtract with Carry extended   with Reg A
-SBCB    #_immed8_            Subtract with Carry immediate  with Reg B
-SBCB    _addr8_,X            Subtract with Carry indirect,X with Reg B
-SBCB    _addr8_,Y       b    Subtract with Carry indirect,Y with Reg B
-SBCB    _addr16_             Subtract with Carry extended   with Reg B
-SEC                          Set Carry
-SEI                          Set Interrupt Mask
-SEV                          Set Twos Complement Overflow Bit
-STAA    _addr8_,X            Store Reg A indirect,X
-STAA    _addr8_,Y       b    Store Reg A indirect,Y
-STAA    _addr16_             Store Reg A extended
-
-STAB    _addr8_,X            Store Reg B indirect,X
-STAB    _addr8_,Y       b    Store Reg B indirect,Y
-STAB    _addr16_             Store Reg B extended
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-STD     _addr8_,X            Store Double Acc indirect,X to Reg B
-STD     _addr8_,Y       b    Store Double Acc indirect,Y to Reg B
-STD     _addr16_             Store Double Acc extended   to Reg B
-
-STOP                         Stop Processing
-
-STS     _addr8_,X            Store Accumulator indirect,X
-STS     _addr8_,Y       b    Store Accumulator indirect,Y
-STS     _addr16_             Store Accumulator extended
-
-STX     _addr8_,X            Store Index Reg X indirect,X
-STX     _addr8_,Y       b    Store Index Reg X indirect,Y
-STX     _addr16_             Store Index Reg X extended
-
-STY     _addr8_,X       b    Store Index Reg Y indirect,X
-STY     _addr8_,Y       b    Store Index Reg Y indirect,Y
-STY     _addr16_        b    Store Index Reg Y extended
-
-SUBA    #_immed8_            Subtract immediate  from Reg A
-SUBA    _addr8_,X            Subtract indirect,X from Reg A
-SUBA    _addr8_,Y       b    Subtract indirect,Y from Reg A
-SUBA    _addr16_             Subtract extended   from Reg A
-
-SUBB    #_immed8_            Subtract immediate  from Reg B
-SUBB    _addr8_,X            Subtract indirect,X from Reg B
-SUBB    _addr8_,Y       b    Subtract indirect,Y from Reg B
-SUBB    _addr16_             Subtract extended   from Reg B
-
-SUBD    #_immed16_      b    Subtract double immediate  from Reg D
-SUBD    _addr8_,X       b    Subtract double indirect,X from Reg D
-SUBD    _addr8_,Y       b    Subtract double indirect,Y from Reg D
-SUBD    _addr16_        b    Subtract double extended   from Reg D
-
-SWI                          Software Interrupt
-
-TAB                          Transfer Reg A to Reg B
-TAP                          Transfer Reg A to Condition Code Reg
-TPA                          Transfer Condition Code Reg to Reg A
-TBA                          Transfer Reg B to Reg A
-
-TST     _addr8_,X            Test indirect,X
-TST     _addr8_,Y            Test indirect,Y
-TST     _addr16_no8_         Test extended
-TSTA                         Test Reg A
-TSTB                         Test Reg B
-
-TSX                          Transfer Stack Pointer to Reg X
-TSY                     b    Transfer Stack Pointer to Reg Y
-TXS                          Transfer Reg X to Stack Pointer
-TYS                     b    Transfer Reg Y to Stack Pointer
-
-WAI                          Wait for Interrupt
-XGDX                    b    Exchange Double Reg D and Reg X
-XGDY                    b    Exchange Double Reg D and Reg Y
-
-
-
-

8048 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 8048 version of TASM. Where 'Rn' is seen, -R0 through R7 may be substituted. Other symbolic fields are as follows: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr8_             Absolute address (8 bits)
-_addr11_            Absolute address (11 bits)
-_immed_             Immediate data
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-

The lines that are marked with an (8041), (8022), or (8021) on the far -right are extended instructions that are available only if a -x option has been -invoked on the command line. The classes of instructions (and their bit -assignment in the class mask) are shown below: -

-
BIT     PROCESSOR
--------------------------------
-0       8X48, 8035, 8039, 8049
-1       8X41A
-2       8022
-3       8021
-
-

Thus, to enable the basic 8048 set plus the 8022 set, a -x5 could be used on -the command line. -

-

Note that some of the base instructions should be disabled for the 8041, -8022, and 8021, but are not. -

-
OPCODE  OPERANDS        DESCRIPTION
--------------------------------------------------------------------
-ADD     A,Rn            Add Register to Acc
-ADD     A,@R0           Add Indirect RAM to Acc
-ADD     A,@R1           Add Indirect RAM to Acc
-ADD     A,#_immed_      Add Immediate data to Acc
-
-ADDC    A,Rn            Add Register to Acc with carry
-ADDC    A,@R0           Add Indirect RAM to Acc with carry
-ADDC    A,@R1           Add Indirect RAM to Acc with carry
-ADDC    A,#_immed_      Add Immediate data to Acc with carry
-
-ANL     A,Rn            AND Register to Acc
-ANL     A,@R0           AND Indirect RAM to Acc
-ANL     A,@R1           AND Indirect RAM to Acc
-ANL     A,#_immed_      AND Immediate data to Acc
-ANL     BUS,#_immed_    AND Immediate data to BUS
-ANL     P1,#_immed_     AND Immediate data to port P1
-ANL     P2,#_immed_     AND Immediate data to port P2
-
-ANLD    P4,A            AND Acc to Expander port P4
-ANLD    P5,A            AND Acc to Expander port P5
-ANLD    P6,A            AND Acc to Expander port P6
-ANLD    P7,A            AND Acc to Expander port P7
-
-CALL    _addr11_        Call subroutine
-
-CLR     A               Clear Acc
-CLR     C               Clear Carry
-CLR     F0              Clear Flag 0
-CLR     F1              Clear Flag 1
-
-CPL     A               Complement Acc
-CPL     C               Complement Carry
-CPL     F0              Complement Flag F0
-CPL     F1              Complement Flag F1
-
-DA      A               Decimal adjust Acc
-
-DEC     A               Decrement Acc
-DEC     Rn              Decrement Register
-
-DIS     I               Disable Interrupts
-DIS     TCNTI           Disable Timer/Counter Interrupt
-
-DJNZ    Rn,_addr8_      Decrement Register and Jump if nonzero
-
-EN      DMA             Enable DMA                           (8041)
-EN      FLAGS           Enable Flags                         (8041)
-EN      I               Enable External Interrupt
-EN      TCNTI           Enable Timer/Counter Interrupt
-ENT0    CLK             Enable Clock Output
-
-IN      A,DBB           Input Data Bus to Acc                (8041)
-IN      A,P0            Input Port 0 to Acc                  (8021)
-IN      A,P1            Input Port 1 to Acc
-IN      A,P2            Input Port 2 to Acc
-
-INC     A               Increment Acc
-INC     Rn              Increment Register
-INC     @R0             Increment Indirect RAM
-INC     @R1             Increment Indirect RAM
-
-INS     A,BUS           Strobed Input of Bus to Acc
-
-JB0     _addr8_         Jump if Acc bit 0 is set
-JB1     _addr8_         Jump if Acc bit 1 is set
-JB2     _addr8_         Jump if Acc bit 2 is set
-JB3     _addr8_         Jump if Acc bit 3 is set
-JB4     _addr8_         Jump if Acc bit 4 is set
-JB5     _addr8_         Jump if Acc bit 5 is set
-JB6     _addr8_         Jump if Acc bit 6 is set
-JB7     _addr8_         Jump if Acc bit 7 is set
-JMP     _addr11_        Jump
-JC      _addr8_         Jump if Carry is set
-JF0     _addr8_         Jump if Flag F0 is set
-JF1     _addr8_         Jump if Flag F1 is set
-JNC     _addr8_         Jump if Carry is clear
-JNI     _addr8_         Jump if Interrupt input is clear
-JNIBF   _addr8_         Jump if IBF is clear                 (8041)
-JNT0    _addr8_         Jump if T0 is clear
-JNT1    _addr8_         Jump if T1 is clear
-JNZ     _addr8_         Jump if Acc is not zero
-JOBF    _addr8_         Jump if OBF is set                   (8041)
-JTF     _addr8_         Jump if Timer Flag is set
-JT0     _addr8_         Jump if T0 pin is high
-JT1     _addr8_         Jump if T1 pin is high
-JZ      _addr8_         Jump if Acc is zero
-JMPP    @A              Jump Indirect (current page)
-
-MOV     A,PSW           Move PSW to Acc
-MOV     A,Rn            Move Register to Acc
-MOV     A,T             Move Timer/Counter to Acc
-MOV     A,@R0           Move Indirect RAM to Acc
-MOV     A,@R1           Move Indirect RAM to Acc
-MOV     A,#_immed_      Move Immediate data to Acc
-MOV     PSW,A           Move Acc to PSW
-MOV     Rn,A            Move Acc to Register
-MOV     Rn,#_immed_     Move Immediate data to Register
-MOV     STS,A           Move Acc to STS                      (8041)
-MOV     T,A             Move Acc to Timer/Counter
-MOV     @R0,A           Move Acc to Indirect RAM
-MOV     @R1,A           Move Acc to Indirect RAM
-MOV     @R0,#_immed_    Move Immediate data to Indirect RAM
-MOV     @R1,#_immed_    Move Immediate data to Indirect RAM
-
-MOVD    A,P4            Move half-byte Port 4 to Acc (lower nibble)
-MOVD    A,P5            Move half-byte Port 5 to Acc (lower nibble)
-MOVD    A,P6            Move half-byte Port 6 to Acc (lower nibble)
-MOVD    A,P7            Move half-byte Port 7 to Acc (lower nibble)
-MOVD    P4,A            Move lower nibble of Acc to Port 4
-MOVD    P5,A            Move lower nibble of Acc to Port 5
-MOVD    P6,A            Move lower nibble of Acc to Port 6
-MOVD    P7,A            Move lower nibble of Acc to Port 7
-
-MOVP    A,@A            Move Indirect Program data to Acc
-MOVP3   A,@A            Move Indirect Program data to Acc (page 3)
-
-MOVX    A,@R0           Move Indirect External RAM to Acc
-MOVX    A,@R1           Move Indirect External RAM to Acc
-MOVX    @R0,A           Move Acc to Indirect External RAM
-MOVX    @R1,A           Move Acc to Indirect External RAM
-
-NOP                     No operation
-
-ORL     A,Rn            OR Register to Acc
-ORL     A,@R0           OR Indirect RAM to Acc
-ORL     A,@R1           OR Indirect RAM to Acc
-ORL     A,#_immed_      OR Immediate data to Acc
-ORL     BUS,#_immed_    OR Immediate data to BUS
-ORL     P1,#_immed_     OR Immediate data to port P1
-ORL     P2,#_immed_     OR Immediate data to port P2
-
-ORLD    P4,A            OR lower nibble of Acc with P4
-ORLD    P5,A            OR lower nibble of Acc with P5
-ORLD    P6,A            OR lower nibble of Acc with P6
-ORLD    P7,A            OR lower nibble of Acc with P7
-
-OUTL    BUS,A           Output Acc to Bus
-OUT     DBB,A           Output Acc to DBB                    (8041)
-OUTL    P0,A            Output Acc to Port P0                (8021)
-OUTL    P1,A            Output Acc to Port P1
-OUTL    P2,A            Output Acc to Port P2
-
-RAD                     Move A/D Converter to Acc            (8022)
-
-RET                     Return from subroutine
-RETI                    Return from Interrupt w/o PSW restore(8022)
-RETR                    Return from Interrupt w/  PSW restore
-
-RL      A               Rotate Acc Left
-RLC     A               Rotate Acc Left through Carry
-RR      A               Rotate Acc Right
-RRC     A               Rotate Acc Right through Carry
-
-SEL     AN0             Select Analog Input 0                (8022)
-SEL     AN1             Select Analog Input 1                (8022)
-SEL     MB0             Select Memory Bank 0
-SEL     MB1             Select Memory Bank 1
-SEL     RB0             Select Register Bank 0
-SEL     RB1             Select Register Bank 1
-
-STOP    TCNT            Stop Timer/Counter
-STRT    CNT             Start Counter
-STRT    T               Start Timer
-
-SWAP    A               Swap nibbles of Acc
-
-XCH     A,Rn            Exchange Register with Acc
-XCH     A,@R0           Exchange Indirect RAM with Acc
-XCH     A,@R1           Exchange Indirect RAM with Acc
-
-XCHD    A,@R0           Exchange lower nibble of Indirect RAM w/ Acc
-XCHD    A,@R1           Exchange lower nibble of Indirect RAM w/ Acc
-
-XRL     A,Rn            Exclusive OR Register to Acc
-XRL     A,@R0           Exclusive OR Indirect RAM to Acc
-XRL     A,@R1           Exclusive OR Indirect RAM to Acc
-XRL     A,#_immed_      Exclusive OR Immediate data to Acc
-
-

See manufacturer's data for a more complete description of the meaning of -the mnemonics and addressing modes. -

-
-

8051 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 8051 version of TASM. Where 'Rn' is -seen, R0 through R7 may be substituted. Other symbolic fields are as -follows: -

-
        
-SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr11_            Absolute address (11 bits)
-_addr16_            Absolute address (16 bits)
-_bit_               Bit address
-_immed_             Immediate data
-_direct_            Direct RAM address
-_rel_               Relative address
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-
OPCODE  OPERAND             DESCRIPTION
---------------------------------------------------------------------
-ACALL   _addr11_            Absolute Call
-ADD     A,Rn                Add Register to Acc
-ADD     A,@R0               Add Indirect RAM to Acc
-ADD     A,@R1               Add Indirect RAM to Acc
-ADD     A,#_immed_          Add Immediate data to Acc
-ADD     A,_direct_          Add Direct RAM to Acc
-ADDC    A,Rn                Add Register to Acc with carry
-ADDC    A,@R0               Add Indirect RAM to Acc with carry
-ADDC    A,@R1               Add Indirect RAM to Acc with carry
-ADDC    A,#_immed_          Add Immediate data to Acc with carry
-ADDC    A,_direct_          Add Direct RAM to Acc with carry
-
-AJMP    _addr11_            Absolute Jump
-
-ANL     A,Rn                AND Register and Acc
-ANL     A,@R0               AND Indirect RAM and Acc
-ANL     A,@R1               AND Indirect RAM and Acc
-ANL     A,#_immed_          AND Immediate data and Acc
-ANL     A,_direct_          AND Direct RAM and Acc
-ANL     C,/_bit_            AND Complement of direct bit to Carry
-ANL     C,bit>              AND direct bit to Carry
-ANL     _direct_,A          AND Acc to direct RAM
-ANL     _direct_,#_immed_   AND Immediate data and direct RAM
-
-CJNE    A,#_immed_,_rel_    Compare Immediate to Acc   and JNE
-CJNE    A,_direct_,_rel_    Compare direct RAM to Acc and JNE
-CJNE    Rn,#_immed_,_rel_   Compare Immediate to Register and JNE
-CJNE    @R0,#_immed_,_rel_  Compare Immediate to Indirect RAM and JNE
-CJNE    @R1,#_immed_,_rel_  Compare Immediate to Indirect RAM and JNE
-
-CLR     A                   Clear Accumulator
-CLR     C                   Clear Carry
-CLR     _bit_               Clear Bit
-
-CPL     A                   Complement Accumulator
-CPL     C                   Complement Carry
-CPL     _bit_               Complement Bit
-
-DA      A                   Decimal Adjust Accumulator
-DEC     A                   Decrement Acc
-DEC     Rn                  Decrement Register
-DEC     @R0                 Decrement Indirect RAM
-DEC     @R1                 Decrement Indirect RAM
-DEC     _direct_            Decrement Direct RAM
-
-DIV     AB                  Divide Acc by B
-
-DJNZ    Rn,_rel_            Decrement Register and JNZ
-DJNZ    _direct_,_rel_      Decrement Direct RAM and JNZ
-
-INC     A                   Increment Acc
-INC     Rn                  Increment Register
-INC     @R0                 Increment Indirect RAM
-INC     @R1                 Increment Indirect RAM
-INC     DPTR                Increment Data Pointer
-INC     _direct_            Increment Direct RAM
-
-JB      _bit_,_rel_         Jump if Bit is set
-JBC     _bit_,_rel_         Jump if Bit is set & clear Bit
-JC      _rel_               Jump if Carry is set
-JMP     @A+DPTR             Jump indirect relative to Data Pointer
-JNB     _bit_,_rel_         Jump if Bit is clear
-JNC     _rel_               Jump if Carry is clear
-JNZ     _rel_               Jump if Acc is not zero
-JZ      _rel_               Jump if Acc is zero
-
-LCALL   _addr16_            Long Subroutine Call
-LJMP    _addr16_            Long Jump
-
-MOV     A,Rn                Move Register to Acc
-MOV     A,@R0               Move Indirect RAM to Acc
-MOV     A,@R1               Move Indirect RAM to Acc
-MOV     A,#_immed_          Move Immediate data to Acc
-MOV     A,_direct_          Move direct RAM to Acc
-MOV     C,_bit_             Move bit to Acc
-MOV     DPTR,#_immed_       Move immediate data to Data Pointer
-MOV     Rn,A                Move Acc to Register
-MOV     Rn,#_immed_         Move Immediate data to Register
-MOV     Rn,_direct_         Move Direct RAM to Register
-MOV     @R0,A               Move Acc to Indirect RAM
-MOV     @R1,A               Move Acc to Indirect RAM
-MOV     @R0,#_immed_        Move Immediate data to Indirect RAM
-MOV     @R1,#_immed_        Move Immediate data to Indirect RAM
-MOV     @R0,_direct_        Move Direct RAM to Indirect RAM
-MOV     @R1,_direct_        Move Direct RAM to Indirect RAM
-MOV     _direct_,A          Move Acc to Direct RAM
-MOV     _bit_,C             Move Carry to Bit
-MOV     _direct_,Rn         Move Register to Direct RAM
-MOV     _direct_,@R0        Move Indirect RAM to Direct RAM
-MOV     _direct_,@R1        Move Indirect RAM to Direct RAM
-MOV     _direct_,#_immed_   Move Immediate data to Direct RAM
-MOV     _direct_,_direct_   Move Direct RAM to Direct RAM
-MOVC    A,@A+DPTR           Move code byte relative to DPTR to Acc
-MOVC    A,@A+PC             Move code byte relative to PC to Acc
-
-MOVX    A,@R0               Move external RAM to Acc
-MOVX    A,@R1               Move external RAM to Acc
-MOVX    A,@DPTR             Move external RAM to Acc (16 bit addr)
-MOVX    @R0,A               Move Acc to external RAM
-MOVX    @R1,A               Move Acc to external RAM
-MOVX    @DPTR,A             Move Acc to external RAM (16 bit addr)
-
-MUL     AB                  Multiply Acc by B
-
-NOP                         No operation
-
-ORL     A,Rn                OR Register and Acc
-ORL     A,@R0               OR Indirect RAM and Acc
-ORL     A,@R1               OR Indirect RAM and Acc
-ORL     A,#_immed_          OR Immediate data and Acc
-ORL     A,_direct_          OR Direct RAM and Acc
-ORL     C,/_bit_            OR Complement of direct bit to Carry
-ORL     C,_bit_             OR direct bit to Carry
-ORL     _direct_,A          OR Acc to direct RAM
-ORL     _direct_,#_immed_   OR Immediate data and direct RAM
-
-POP     _direct_            Pop  from Stack and put in Direct RAM
-PUSH    _direct_            Push from Direct RAM to Stack
-
-RET                         Return from subroutine
-RETI                        Return from Interrupt
-
-RL      A                   Rotate Acc left
-RLC     A                   Rotate Acc left through Carry
-RR      A                   Rotate Acc right
-RRC     A                   Rotate Acc right through Carry
-
-SETB    C                   Set the Carry Bit
-SETB    _bit_               Set Direct Bit
-
-SJMP    _rel_               Short jump
-
-SUBB    A,Rn                Subtract Register from Acc with Borrow
-SUBB    A,@R0               Subtract Indirect RAM from Acc w/ Borrow
-SUBB    A,@R1               Subtract Indirect RAM from Acc w/ Borrow
-SUBB    A,#_immed_          Subtract Immediate data from Acc w/ Borrow
-SUBB    A,_direct_          Subtract Direct RAM from Acc w/ Borrow
-
-SWAP    A                   Swap nibbles of Acc
-
-XCH     A,Rn                Exchange Acc with Register
-XCH     A,@R0               Exchange Acc with Indirect RAM
-XCH     A,@R1               Exchange Acc with Indirect RAM
-XCH     A,_direct_          Exchange Acc with Direct RAM
-
-XCHD    A,@R0               Exchange Digit in Acc with Indirect RAM
-XCHD    A,@R1               Exchange Digit in Acc with Indirect RAM
-
-XRL     A,Rn                Exclusive OR Register and Acc
-XRL     A,@R0               Exclusive OR Indirect RAM and Acc
-XRL     A,@R1               Exclusive OR Indirect RAM and Acc
-XRL     A,#_immed_          Exclusive OR Immediate data and Acc
-XRL     A,_direct_          Exclusive OR Direct RAM and Acc
-XRL     _direct_,A          Exclusive OR Acc to direct RAM
-XRL     _direct_,#_immed_   Exclusive OR Immediate data and direct RAM
-
-

Note that the above tables do not automatically define the various -mnemonics that may be used for addressing the special function registers -of the 8051. The user may wish to set up a file of equates (EQU's) that -can be included in the source file for this purpose. The following -illustrates some of the appropriate equates: -

-
P0      .equ    080H    ;Port 0
-SP      .equ    081H    ;Stack pointer
-DPL     .equ    082H
-DPH     .equ    083H
-PCON    .equ    087H
-TCON    .equ    088H
-TMOD    .equ    089H
-TL0     .equ    08AH
-TL1     .equ    08BH
-TH0     .equ    08CH
-TH1     .equ    08DH
-P1      .equ    090H    ;Port 1
-SCON    .equ    098H
-SBUF    .equ    099H
-P2      .equ    0A0H    ;Port 2
-IEC     .equ    0A8H
-P3      .equ    0B0H    ;Port 3
-IPC     .equ    0B8H
-PSW     .equ    0D0H
-ACC     .equ    0E0H    ;Accumulator
-B       .equ    0F0H    ;Secondary Accumulator
-;Now some bit addresses
-P0.0    .equ    080H    ;Port 0 bit 0
-P0.1    .equ    081H    ;Port 0 bit 1
-P0.2    .equ    082H    ;Port 0 bit 2
-P0.3    .equ    083H    ;Port 0 bit 3
-P0.4    .equ    084H    ;Port 0 bit 4
-P0.5    .equ    085H    ;Port 0 bit 5
-P0.6    .equ    086H    ;Port 0 bit 6
-P0.7    .equ    087H    ;Port 0 bit 7
-ACC.0   .equ    0E0H    ;Acc bit 0
-ACC.1   .equ    0E1H    ;Acc bit 1
-ACC.2   .equ    0E2H    ;Acc bit 2
-ACC.3   .equ    0E3H    ;Acc bit 3
-ACC.4   .equ    0E4H    ;Acc bit 4
-ACC.5   .equ    0E5H    ;Acc bit 5
-ACC.6   .equ    0E6H    ;Acc bit 6
-ACC.7   .equ    0E7H    ;Acc bit 7
-
-

See the manufacturer's data sheets for more information. -

-
-

8085 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 8085 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr_              Absolute address (16 bits)
-_data_              Immediate data (8 bits)
-_data16_            Immediate data (16 bits)
-_reg_               Register (A,B,C,D,E,H,L)
-_rp_                Register pair (B,D,H,SP)
-_port_              Port address (0-255)
-_int_               Interrupt level (0 - 7)
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics except _reg_, _rp_ and _int_. -

-
OPCODE  OPERAND        DESCRIPTION
---------------------------------------------------------------------
-ACI      _data_         Add immediate to A with carry
-ADC      _reg_          Add _reg_ to A with carry
-ADC      M              Add indirect memory (HL) with carry
-ADD      _reg_          Add _reg_ to A
-ADD      M              Add indirect memory (HL) to A
-ADI      _data_         Add immediate to A
-
-ANA      _reg_          And register with A
-ANA      M              And indirect memory (HL) to A
-ANI      _data_         And immediate to A
-
-CALL     _addr_         Call subroutine at _addr_
-CC       _addr_         Call subroutine if carry set
-CNC      _addr_         Call subroutine if carry clear
-CZ       _addr_         Call subroutine if zero
-CNZ      _addr_         Call subroutine if non zero
-CP       _addr_         Call subroutine if positive
-CM       _addr_         Call subroutine if negative
-CPE      _addr_         Call subroutine if even parity
-CPO      _addr_         Call subroutine if odd  parity
-CMA                     Complement A
-CMC                     Complemennt carry
-CMP      _reg_          Compare register with A
-CMP      M              Compare indirect memory (HL) with A
-CPI      _data_         Compare immediate data with A
-
-DAA                     Decimal adjust A
-DAD      _rp_           Add register pair to HL
-DCR      _reg_          Decrement register
-DCR      M              Decrement indirect memory (HL)
-DCX      _rp_           Decrement register pair
-
-DI                      Disable interrupts
-EI                      Enable interrupts
-HLT                     Halt
-
-IN       _port_         Input on port
-INR      _reg_          Increment register
-INR      M              Increment indirect memory (HL)
-INX      _rp_           Increment register pair
-
-JMP      _addr_         Jump
-JC       _addr_         Jump if carry set
-JNC      _addr_         Jump if carry clear
-JZ       _addr_         Jump if zero
-JNZ      _addr_         Jump if not zero
-JM       _addr_         Jump if minus
-JP       _addr_         Jump if plus
-JPE      _addr_         Jump if parity even
-JPO      _addr_         Jump if parity odd
-
-LDA      _addr_         Load A direct from memory
-LDAX     B              Load A indirect from memory using BC
-LDAX     D              Load A indirect from memory using DE
-LHLD     _addr_         Load HL direct from memory
-LXI      _rp_,_data16_  Load register pair with immediate data
-
-MOV      _reg_,_reg_    Move register to register
-MOV      _reg_,M        Move indirect memory (HL) to register
-MVI      _reg_,_data_   Move immediate data to register
-
-NOP                     No operation
-
-ORA      _reg_          Or register with A
-ORA      M              Or indirect memory (HL) with A
-ORI      _data_         Or immediate data to A
-OUT      _port_         Ouput to port
-
-PCHL                    Jump to instruction at (HL)
-POP      _rp_           Pop  register pair (excluding SP) from stack
-PUSH     _rp_           Push register pair (excluding SP) onto stack
-POP      PSW            Pop  PSW from stack
-PUSH     PSW            Pop  PSW onto stack
-
-RAL                     Rotate A left  with carry
-RAR                     Rotate A right with carry
-RLC                     Rotate A left  with branch carry
-RRC                     Rotate A right with branch carry
-
-RET                     Return from subroutine
-RZ                      Return if zero
-RNZ                     Return if non zero
-RC                      Return if carry set
-RNC                     Return if carry clear
-RM                      Return if minus
-RP                      Return if plus
-RPE                     Return if parity even
-RPO                     Return if parity odd
-
-RIM                     Read interrupt mask
-RST      _int_          Restart at vector _int_
-
-SBB      _reg_          Subtract _reg_ from A         with borrow
-SBB      M              Subtract indirect memory (HL) with borrow
-SBI      _data_         Subtract immediate from A     with borrow
-SUB      _reg_          Subtract _reg_ from A
-SUB      M              Subtract indirect memory (HL) from A
-SUI      _data_         Subtract immediate from A
-
-SHLD     _addr_         Store HL
-SIM                     Store Interrupt mask
-SPHL                    Exchange SP with HL
-
-STA      _addr_         Store A direct memory
-STAX     B              Store A indirect using BC
-STAX     D              Store A indirect using DE
-
-STC                     Set carry
-
-XRA      _reg_          Exclusive OR A with register
-XRA      M              Exclusive Or A with indirect memory (HL)
-XRI      _data_         Exclusive Or A with immediate data
-XCHG                    Exchange DE with HL
-XTHL                    Exchange HL with top of stack
-
-
-

See the manufacturer's data sheets for more information. -

-
-

Z80 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the Z80 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr_              Absolute address (16 bits)
-_bit_               Bit address
-_data_              Immediate data (8 bits)
-_data16_            Immediate data (16 bits)
-_disp_              Relative address
-_reg_               Register (A, B, C, D, E, H, or L)
-_rp_                Register pair (BC, DE, HL, or SP)
-_port_              Port (0 - 255)
-_cond_              Condition
-			NZ - not zero
-			Z  - zero
-			NC - not carry
-			C  - carry
-			PO - parity odd
-			PE - parity even
-			P  - positive
-			M  - minus
-
-
-

Any valid TASM expression can appear in the place of the _addr_, _bit_, -_data_, _data16_, or _disp_ symbolics. -

-
OPCODE  OPERAND         DESCRIPTION
---------------------------------------------------------------------
-ADC  A,_data_           Add immediate with carry to accumulator
-ADC  A,_reg_            Add register with carry to accumulator
-ADC  A,(HL)             Add indirect memory with carry to accumulator
-ADC  A,(IX+_disp_)      Add indirect memory with carry to accumulator
-ADC  A,(IY+_disp_)      Add indirect memory with carry to accumulator
-ADC  HL,_rp_            Add register pair with carry to HL
-
-ADD  A,_data_           Add immediate to accumulator
-ADD  A,_reg_            Add register to accumulator
-ADD  A,(HL)             Add indirect memory to accumulator
-ADD  A,(IX+_disp_)      Add indirect memory to accumulator
-ADD  A,(IY+_disp_)      Add indirect memory to accumulator
-ADD  HL,_rp_            Add register pair to HL
-ADD  IX,_rp_            Add register pair to index register
-ADD  IY,_rp_            Add register pair to index register
-
-AND  _data_             And immediate with accumulator
-AND  _reg_              And register  with accumulator
-AND  (HL)               And memory with accumulator
-AND  (IX+_disp_)        And memory with accumulator
-AND  (IY+_disp_)        And memory with accumulator
-
-BIT  _bit_,_reg_        Test _bit_ in register
-BIT  _bit_,(HL)         Test _bit_ in indirect memory
-BIT  _bit_,(IY+_disp_)  Test _bit_ in indirect memory
-BIT  _bit_,(IX+_disp_)  Test _bit_ in indirect memory
-
-CALL _addr_             Call the routine at _addr_
-CALL _cond_,_addr_      Call the routine if _cond_ is satisfied
-
-CCF                     Complement carry flag
-
-CP   _data_             Compare immediate data with accumulator
-CP   _reg_              Compare register with accumulator
-CP   (HL)               Compare indirect memory with accumulator
-CP   (IX+_disp_)        Compare indirect memory with accumulator
-CP   (IY+_disp_)        Compare indirect memory with accumulator
-CPD                     Compare accumulator with memory and
-                            decrement address and byte counters
-CPDR                    Compare accumulator with memory and
-                            decrement address and byte counter,
-                            continue until match is found or
-                            byte counter is zero
-
-CPI                     Compare accumulator with memory and
-                            increment address and byte counters
-CPIR                    Compare accumulator with memory and
-                            increment address and byte counter,
-                            continue until match is found or
-                            byte counter is zero
-CPL                     Complement the accumulator
-DAA                     Decimal adjust accumulator
-DEC  _reg_              Decrement register contents
-DI                      Disable interrupts
-DJNZ _disp_             Decrement reg B and jump relative if zero
-EI                      Enable interrupts
-EX   AF,AF'             Exchange program status and alt program stat
-EX   DE,HL              Exchange DE and HL contents
-EX   (SP),HL            Exchange contents of HL and top of stack
-EX   (SP),IX            Exchange contents of IX and top of stack
-EX   (SP),IY            Exchange contents of IY and top of stack
-EXX                     Exchange register pairs and alt reg pairs
-HALT                    Program execution stops
-IM   0                  Interrupt mode 0
-IM   1                  Interrupt mode 1
-IM   2                  Interrupt mode 2
-IN   A,_port_           Input port to accumulator
-INC  _reg_              Increment contents of register
-INC  _rp_               Increment contents of register pair
-INC  IX                 Increment IX
-INC  IY                 Increment IY
-INC  (HL)               Increment indirect memory
-INC  (IX+_disp_)        Increment indirect memory
-INC  (IY+_disp_)        Increment indirect memory
-IND                     Input to memory and decrement pointer
-INDR                    Input to memory and decrement pointer until
-                            byte counter is zero
-INI                     Input to memory and increment pointer
-INIR                    Input to memory and increment pointer until
-                            byte counter is zero
-IN   _reg_,(C)          Input to register
-
-JP   _addr_             Jump to location
-JP   _cond_,_addr_      Jump to location if condition satisifed
-JP   (HL)               Jump to location pointed to by HL
-JP   (IX)               Jump to location pointed to by IX
-JP   (IY)               Jump to location pointed to by IY
-
-JR   _disp_             Jump relative
-JR   C,_disp_           Jump relative if carry is set
-JR   NC,_disp_          Jump relative if carry bit is reset
-JR   NZ,_disp_          Jump relative if zero flag is reset
-JR   Z,_disp_           Jump relative if zero flag is set
-
-LD   A,I                Move interrupt vector contents to accumulator
-LD   A,R                Move refresh reg contents to accumulator
-LD   A,(_addr_)         Load accumulator indirect from memory
-LD   A,(_rp_)           Load accumulator indirect from memory by _rp_
-LD   _reg_,_reg_        Load source register to destination register
-LD   _rp_,(_addr_)      Load register pair indirect from memory
-LD   IX,(_addr_)        Load IX indirect from memory
-LD   IY,(_addr_)        Load IY indirect from memory
-LD   I,A                Load interrup vector from accumulator
-LD   R,A                Load refresh register from accumulator
-LD   _reg_,_data_       Load register with immediate data
-LD   _rp_,_data16_      Load register pair with immediate data
-LD   IX,_data16_        Load  IX  with immediate data
-LD   IY,_data16_        Load  IY  with immediate data
-LD   _reg_,(HL)         Load register indirect from memory
-LD   _reg_,(IX+_disp_)  Load register indirect from memory
-LD   _reg_,(IY+_disp_)  Load register indirect from memory
-LD   SP,HL              Load contents of HL to stack pointer
-LD   SP,IX              Load contents of IX to stack pointer
-LD   SP,IY              Load contents of IY to stack pointer
-LD   (addr),A           Load contents of A to memory
-LD   (_addr_),HL        Load contents of HL to memory
-LD   (_addr_),_rp_      Load contents of register pair to memory
-LD   (_addr_),IX        Load contents of IX to memory
-LD   (_addr_),IY        Load contents of IY to memory
-LD   (HL),_data_        Load immediate into indirect memory
-LD   (IX+_disp_),_data_ Load immediate into indirect memory
-LD   (IY+_disp_),_data_ Load immediate into indirect memory
-LD   (HL),_reg_         Load register  into indirect memory
-LD   (IX+_disp_),_reg_  Load register  into indirect memory
-LD   (IY+_disp_),_reg_  Load register  into indirect memory
-LD   (_rp_),A           Load accumulator into indirect memory
-LDD                     Transfer data between memory and decrement
-                            destination and source addresses
-LDDR                    Transfer data between memory until byte
-                            counter is zero, decrement destintation
-                            and source addresses
-LDI                     Transfer data between memory and increment
-                            destination and source addresses
-LDIR                    Transfer data between memory until byte
-                            counter is zero, increment destination
-                            and source addresses
-NEG                     Negate contents of accumulator
-NOP                     No operation
-OR   _data_             Or immediate with accumulator
-OR   _reg_              Or register with accumulator
-OR   (HL)               Or indirect memory with accumulator
-OR   (IX+_disp_)        Or indirect memory with accumulator
-OR   (IY+_disp_)        Or indirect memory with accumulator
-OUT  (C),_reg_          Output from registor
-OUTD                    Output from memory, decrement address
-OTDR                    Output from memory, decrement address
-                            continue until reg B is zero
-OUTI                    Output from memory, increment address
-OTIR                    Output from memory, increment address
-                            continue until reg B is zero
-OUT  _port_,A           Output from accumulator
-POP  _rp_               Load register pair from top of stack
-POP  IX                 Load IX from top of stack
-POP  IY                 Load IY from top of stack
-PUSH _rp_               Store resister pair on top of stack
-PUSH IX                 Store IX on top of stack
-PUSH IY                 Store IY on top of stack
-RES  _bit_,_reg_        Reset register bit
-RES  _bit_,(HL)         Reset bit at indirect memory location
-RES  _bit_,(IX+disp)    Reset bit at indirect memory location
-RES  _bit_,(IY+_disp_)  Reset bit at indirect memory location
-RET                     Return from subroutine
-RET  _cond_             Return from subroutine if condition true
-RETI                    Return from interrupt
-RETN                    Return from non-maskable interrupt
-RL   _reg_              Rotate left through carry register contents
-RL   (HL)               Rotate left through carry indirect memory
-RL   (IX+_disp_)        Rotate left through carry indirect memory
-RL   (IY+_disp_)        Rotate left through carry indirect memory
-RLA                     Rotate left through carry accumulator
-RLC  _reg_              Rotate left branch  carry register contents
-RLC  (HL)               Rotate left branch  carry indirect memory
-RLC  (IX+_disp_)        Rotate left branch  carry indirect memory
-RLC  (IY+_disp_)        Rotate left branch  carry indirect memory
-RLCA                    Rotate left accumulator
-RLD                     Rotate one BCD digit left between the
-                            accumulator and memory
-RR   _reg_              Rotate right through carry register contents
-RR   (HL)               Rotate right through carry indirect memory
-RR   (IX+_disp_)        Rotate right through carry indirect memory
-RR   (IY+_disp_)        Rotate right through carry indirect memory
-RRA                     Rotate right through carry accumulator
-RRC  _reg_              Rotate right branch  carry register contents
-RRC  (HL)               Rotate right branch  carry indirect memory
-RRC  (IX+_disp_)        Rotate right branch  carry indirect memory
-RRC  (IY+_disp_)        Rotate right branch  carry indirect memory
-RRCA                    Rotate right branch  carry accumulator
-RRD                     Rotate one BCD digit right between the
-                            accumulator and memory
-RST                     Restart
-SBC  A,_data_           Subtract data            from A with borrow
-SBC  A,_reg_            Subtract register        from A with borrow
-SBC  A,(HL)             Subtract indirect memory from A with borrow
-SBC  A,(IX+_disp_)      Subtract indirect memory from A with borrow
-SBC  A,(IY+_disp_)      Subtract indirect memory from A with borrow
-SBC  HL,_rp_            Subtract register pair from HL with borrow
-SCF                     Set carry flag
-SET  _bit_,_reg_        Set register bit
-SET  _bit_,(HL)         Set indirect memory bit
-SET  _bit_,(IX+_disp_)  Set indirect memory bit
-SET  _bit_,(IY+_disp_)  Set indirect memory bit
-SLA  _reg_              Shift register left arithmetic
-SLA  (HL)               Shift indirect memory left arithmetic
-SLA  (IX+_disp_)        Shift indirect memory left arithmetic
-SLA  (IY+_disp_)        Shift indirect memory left arithmetic
-SRA  _reg_              Shift register right arithmetic
-SRA  (HL)               Shift indirect memory right arithmetic
-SRA  (IX+_disp_)        Shift indirect memory right arithmetic
-SRA  (IY+_disp_)        Shift indirect memory right arithmetic
-SRL  _reg_              Shift register right logical
-SRL  (HL)               Shift indirect memory right logical
-SRL  (IX+_disp_)        Shift indirect memory right logical
-SRL  (IY+_disp_)        Shift indirect memory right logical
-SUB  _data_             Subtract immediate from accumulator
-SUB  _reg_              Subtract register from accumulator
-SUB  (HL)               Subtract indirect memory from accumulator
-SUB  (IX+_disp_)        Subtract indirect memory from accumulator
-SUB  (IY+_disp_)        Subtract indirect memory from accumulator
-XOR  _data_             Exclusive or immediate with accumulator
-XOR  _reg_              Exclusive or register with accumulator
-XOR  (HL)               Exclusive or indirect memory with accumulator
-XOR  (IX+_disp_)        Exclusive or indirect memory with accumulator
-XOR  (IY+_disp_)        Exclusive or indirect memory with accumulator
-
-

See the manufacturer's data sheets for more information. -

-
-

6805 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 6805 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr_              Absolute address (16 bits)
-_addr8_             Absolute address (8 bits)
-_bit_               Bit address
-_data_              Immediate data (8 bits)
-_rel_               Relative address
-
-
-

Any valid TASM expression can appear in the place of the _addr_, _addr8_, -_bit_, _data_, or _rel_ symbolics. -

-
OPCODE  OPERAND         DESCRIPTION
---------------------------------------------------------------
-ADC     #_data_         Add with carry, immediate
-ADC     ,X              Add with carry, indexed, no offset
-ADC     _addr8_,X       Add with carry, indexed, 1 byte offset
-ADC     _addr_,X        Add with carry, indexed, 2 byte offset
-ADC     _addr8_         Add with carry, direct
-ADC     _addr_          Add with carry, extended
-
-ADD     #_data_         Add, immediate
-ADD     ,X              Add, indexed, no offset
-ADD     _addr8_,X       Add, indexed, 1 byte offset
-ADD     _addr_,X        Add, indexed, 2 byte offset
-ADD     _addr8_         Add, direct
-ADD     _addr_          Add, extended
-
-AND     #_data_         And, immediate
-AND     ,X              And, indexed, no offset
-AND     _addr8_,X       And, indexed, 1 byte offset
-AND     _addr_,X        And, indexed, 2 byte offset
-AND     _addr8_         And, direct
-AND     _addr_          And, extended
-
-ASLA                    Arithmetic Shift Left, accumulator
-ASLX                    Arithmetic Shift Left, index register
-ASL     _addr8_         Arithmetic Shift Left, direct
-ASL     ,X              Arithmetic Shift Left, indexed, no offset
-ASL     _addr8_,X       Arithmetic Shift Left, indexed, 1 byte offset
-
-ASRA                    Arithmetic Shift Right, accumulator
-ASRX                    Arithmetic Shift Right, index register
-ASR     _addr8_         Arithmetic Shift Right, direct
-ASR     ,X              Arithmetic Shift Right, indexed, no offset
-ASR     _addr8_,X       Arithmetic Shift Right, indexed, 1 byte offset
-
-BCC     _rel_           Branch if carry clear
-BCLR    _bit_,_addr8_   Bit Clear in memory
-BCS     _rel_           Branch if carry set
-BEQ     _rel_           Branch if equal
-BHCC    _rel_           Branch if half carry clear
-BHCS    _rel_           Branch if half carry set
-BHI     _rel_           Branch if higher
-BHS     _rel_           Branch if higher or same
-BIH     _rel_           Branch if interrupt line is high
-BIL     _rel_           Branch if interrupt is low
-
-BIT     #_data_         Bit test, immediate
-BIT     ,X              Bit test, indexed, no offset
-BIT     _addr8_,X       Bit test, indexed, 1 byte offset
-BIT     _addr_,X        Bit test, indexed, 2 byte offset
-BIT     _addr8_         Bit test, direct
-BIT     _addr_          Bit test, extended
-
-BLO     _rel_           Branch if lower
-BLS     _rel_           Branch if lower or same
-BMC     _rel_           Branch if interrupt mask is clear
-BMI     _rel_           Branch if minus
-BMS     _rel_           Branch if interuupt mask bit is set
-BNE     _rel_           Branch if not equal
-BPL     _rel_           Branch if plus
-BRA     _rel_           Branch always
-BRCLR   _bit_,_addr8_,_rel_     Branch if bit is clear
-BRN     _rel_           Branch never
-BRSET   _bit_,_addr8_,_rel_     Branch if bit is set
-BSET    _bit_,_addr8_   Bit set in memory
-BSR     _rel_           Branch to subroutine
-
-CLC                     Clear carry bit
-CLI                     Clear interuupt mask bit
-
-CLRA                    Clear, accumulator
-CLRX                    Clear, index register
-CLR     _addr8_         Clear, direct
-CLR     ,X              Clear, indexed, no offset
-CLR     _addr8_,X       Clear, indexed, 1 byte offset
-
-CMP     #_data_         Compare Acc, immediate
-CMP     ,X              Compare Acc, indexed, no offset
-CMP     _addr8_,X       Compare Acc, indexed, 1 byte offset
-CMP     _addr_,X        Compare Acc, indexed, 2 byte offset
-CMP     _addr8_         Compare Acc, direct
-CMP     _addr_          Compare Acc, extended
-
-COMA                    Complement, accumulator
-COMX                    Complement, index register
-COM     _addr8_         Complement, direct
-COM     ,X              Complement, indexed, no offset
-COM     _addr8_,X       Complement, indexed, 1 byte offset
-
-CPX     #_data_         Compare Index, immediate
-CPX     ,X              Compare Index, indexed, no offset
-CPX     _addr8_,X       Compare Index, indexed, 1 byte offset
-CPX     _addr_,X        Compare Index, indexed, 2 byte offset
-CPX     _addr8_         Compare Index, direct
-CPX     _addr_          Compare Index, extended
-
-DECA                    Decrement, accumulator
-DECX                    Decrement, index register
-DEX                     Decrement, index register (alternate of DECX)
-DEC     _addr8_         Decrement, direct
-DEC     ,X              Decrement, indexed, no offset
-DEC     _addr8_,X       Decrement, indexed, 1 byte offset
-
-EOR     #_data_         Exclusive OR, immediate
-EOR     ,X              Exclusive OR, indexed, no offset
-EOR     _addr8_,X       Exclusive OR, indexed, 1 byte offset
-EOR     _addr_,X        Exclusive OR, indexed, 2 byte offset
-EOR     _addr8_         Exclusive OR, direct
-EOR     _addr_          Exclusive OR, extended
-
-INCA                    Increment, accumulator
-INCX                    Increment, index register
-INX                     Increment, index register (alternate of INCX)
-INC     _addr8_         Increment, direct
-INC     ,X              Increment, indexed, no offset
-INC     _addr8_,X       Increment, indexed, 1 byte offset
-
-JMP     ,X              Jump, indexed, no offset
-JMP     _addr8_,X       Jump, indexed, 1 byte offset
-JMP     _addr_,X        Jump, indexed, 2 byte offset
-JMP     _addr8_         Jump, direct
-JMP     _addr_          Jump, extended
-
-JSR     ,X              Jump Subroutine, indexed, no offset
-JSR     _addr8_,X       Jump Subroutine, indexed, 1 byte offset
-JSR     _addr_,X        Jump Subroutine, indexed, 2 byte offset
-JSR     _addr8_         Jump Subroutine, direct
-JSR     _addr_          Jump Subroutine, extended
-
-LDA     #_data_         Load Acc, immediate
-LDA     ,X              Load Acc, indexed, no offset
-LDA     _addr8_,X       Load Acc, indexed, 1 byte offset
-LDA     _addr_,X        Load Acc, indexed, 2 byte offset
-LDA     _addr8_         Load Acc, direct
-LDA     _addr_          Load Acc, extended
-
-LDX     #_data_         Load Index, immediate
-LDX     ,X              Load Index, indexed, no offset
-LDX     _addr8_,X       Load Index, indexed, 1 byte offset
-LDX     _addr_,X        Load Index, indexed, 2 byte offset
-LDX     _addr8_         Load Index, direct
-LDX     _addr_          Load Index, extended
-
-LSLA                    Logical Shift Left, accumulator
-LSLX                    Logical Shift Left, index register
-LSL     _addr8_         Logical Shift Left, direct
-LSL     ,X              Logical Shift Left, indexed, no offset
-LSL     _addr8_,X       Logical Shift Left, indexed, 1 byte offset
-
-LSRA                    Logical Shift Right, accumulator
-LSRX                    Logical Shift Right, index register
-LSR     _addr8_         Logical Shift Right, direct
-LSR     ,X              Logical Shift Right, indexed, no offset
-LSR     _addr8_,X       Logical Shift Right, indexed, 1 byte offset
-
-NEGA                    Negate, accumulator
-NEGX                    Negate, index register
-NEG     _addr8_         Negate, direct
-NEG     ,X              Negate, indexed, no offset
-NEG     _addr8_,X       Negate, indexed, 1 byte offset
-
-NOP                     No Operation
-
-ORA     #_data_         Inclusive OR Acc, immediate
-ORA     ,X              Inclusive OR Acc, indexed, no offset
-ORA     _addr8_,X       Inclusive OR Acc, indexed, 1 byte offset
-ORA     _addr_,X        Inclusive OR Acc, indexed, 2 byte offset
-ORA     _addr8_         Inclusive OR Acc, direct
-ORA     _addr_          Inclusive OR Acc, extended
-
-ROLA                    Rotate Left thru Carry, accumulator
-ROLX                    Rotate Left thru Carry, index register
-ROL     _addr8_         Rotate Left thru Carry, direct
-ROL     ,X              Rotate Left thru Carry, indexed, no offset
-ROL     _addr8_,X       Rotate Left thru Carry, indexed, 1 byte offset
-
-RORA                    Rotate Right thru Carry, accumulator
-RORX                    Rotate Right thru Carry, index register
-ROR     _addr8_         Rotate Right thru Carry, direct
-ROR     ,X              Rotate Right thru Carry, indexed, no offset
-ROR     _addr8_,X       Rotate Right thru Carry, indexed, 1 byte offset
-
-RSP                     Reset Stack Pointer
-RTI                     Return from Interrupt
-RTS                     Return from Subroutine
-
-SBC     #_data_         Subtract with Carry, immediate
-SBC     ,X              Subtract with Carry, indexed, no offset
-SBC     _addr8_,X       Subtract with Carry, indexed, 1 byte offset
-SBC     _addr_,X        Subtract with Carry, indexed, 2 byte offset
-SBC     _addr8_         Subtract with Carry, direct
-SBC     _addr_          Subtract with Carry, extended
-
-SEC                     Set carry bit
-SEI                     Set interrupt Mask bit
-
-STA     #_data_         Store Acc, immediate
-STA     ,X              Store Acc, indexed, no offset
-STA     _addr8_,X       Store Acc, indexed, 1 byte offset
-STA     _addr_,X        Store Acc, indexed, 2 byte offset
-STA     _addr8_         Store Acc, direct
-STA     _addr_          Store Acc, extended
-
-STOP                    Enable IRQ, Stop Oscillator
-
-STX     #_data_         Store Index, immediate
-STX     ,X              Store Index, indexed, no offset
-STX     _addr8_,X       Store Index, indexed, 1 byte offset
-STX     _addr_,X        Store Index, indexed, 2 byte offset
-STX     _addr8_         Store Index, direct
-STX     _addr_          Store Index, extended
-
-SUB     #_data_         Subtract, immediate
-SUB     ,X              Subtract, indexed, no offset
-SUB     _addr8_,X       Subtract, indexed, 1 byte offset
-SUB     _addr_,X        Subtract, indexed, 2 byte offset
-SUB     _addr8_         Subtract, direct
-SUB     _addr_          Subtract, extended
-
-SWI                     Software Interrupt
-
-TAX                     Transfer Acc to Index
-
-TSTA                    Test for neg or zero, accumulator
-TSTX                    Test for neg or zero, index register
-TST     _addr8_         Test for neg or zero, direct
-TST     ,X              Test for neg or zero, indexed, no offset
-TST     _addr8_,X       Test for neg or zero, indexed, 1 byte offset
-
-TXA                     Transfer Index to Acc
-
-WAIT                    Enable Interrupt, Stop Processor
-
-
-

See the manufacturer's data sheets for more information. -

-
-

TMS32010 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the TMS32010 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_ar_                Auxiliary register (AR0, AR1)
-_arp_               Auxiliary register pointer
-_dma_               Direct memory address
-_pma_               Program memory address
-_port_              Port address (0 - 7)
-_shift_             Shift count  (0 - 15)
-_const1_            Constant (1 bit)
-_const8_            Constant (8 bit)
-_const13_           Constant (13 bit)
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-
OPCODE   OPERAND            DESCRIPTION
---------------------------------------------------------------------
-ABS                         Absolute value of ACC
-
-ADD      *+,_shift_,_arp_   Add to ACC with shift
-ADD      *-,_shift_,_arp_
-ADD      *, _shift_,_arp_
-ADD      *+,_shift_
-ADD      *-,_shift_
-ADD      *, _shift_
-ADD      *+
-ADD      *-
-ADD      *
-ADD      _dma_,_shift_
-ADD      _dma_
-
-ADDH     *+,_arp_           Add to high-order ACC bits
-ADDH     *-,_arp_
-ADDH     *, _arp_
-ADDH     *+
-ADDH     *-
-ADDH     *
-ADDH     _dma_
-
-ADDS     *+,_arp_           Add to ACC with no sign extension
-ADDS     *-,_arp_
-ADDS     *, _arp_
-ADDS     *+
-ADDS     *-
-ADDS     *
-ADDS     _dma_
-
-AND      *+,_arp_           AND with ACC
-AND      *-,_arp_
-AND      *, _arp_
-AND      *+
-AND      *-
-AND      *
-AND      _dma_
-
-APAC                        Add P register to ACC
-
-B        _pma_              Branch unconditionally
-BANZ     _pma_              Branch on auxiliary register not zero
-BGEZ     _pma_              Branch if ACC >= 0
-BGZ      _pma_              Branch if ACC >  0
-BIOZ     _pma_              Branch on BIO- = 0
-BLEZ     _pma_              Branch if ACC <= 0
-BLZ      _pma_              Branch if ACC <  0
-BNZ      _pma_              Branch if ACC 
-
 0
-BV       _pma_              Branch on overflow
-BZ       _pma_              Branch if ACC =  0
-
-CALA                        Call subroutine from ACC
-CALL     _pma_              Call subroutine at _pma_
-
-DINT                        Disable interrupt
-
-DMOV     *+,_arp_           Data move in memory
-DMOV     *-,_arp_
-DMOV     *, _arp_
-DMOV     *+
-DMOV     *-
-DMOV     *
-DMOV     _dma_
-
-EINT                        Enable Interrupt
-
-IN       *+,_port_ ,_arp_   Input data from port
-IN       *-,_port_ ,_arp_
-IN       * ,_port_ ,_arp_
-IN       *+,_port_
-IN       *-,_port_
-IN       * ,_port_
-IN       _dma_,_port_
-
-LAC      *+,_shift_,_arp_   Load ACC with shift
-LAC      *-,_shift_,_arp_
-LAC      *, _shift_,_arp_
-LAC      *+,_shift_
-LAC      *-,_shift_
-LAC      *, _shift_
-LAC      *+
-LAC      *-
-LAC      *
-LAC      _dma_,_shift_
-LAC      _dma_
-
-LACK     _const8_                   Load ACC with 8 bit constant
-
-LAR      _ar_,*+,_arp_              Load auxiliary Register
-LAR      _ar_,*-,_arp_
-LAR      _ar_,*, _arp_
-LAR      _ar_,*+
-LAR      _ar_,*-
-LAR      _ar_,*
-LAR      _ar_,_dma_
-
-LARK     _ar_,_const8_              Load aux register with constant
-LARP     _const1_                   Load aux register pointer immed
-
-LDP      *+,_arp_                   Load data memory page pointer
-LDP      *-,_arp_
-LDP      *, _arp_
-LDP      *+
-LDP      *-
-LDP      *
-LDP      _dma_
-
-LDPK     _const1_                   Load data page pointer immediate
-
-LST      *+,_arp_                   Load status from data memory
-LST      *-,_arp_
-LST      *, _arp_
-LST      *+
-LST      *-
-LST      *
-LST      _dma_
-
-LT       *+,_arp_                   Load T register
-LT       *-,_arp_
-LT       *, _arp_
-LT       *+
-LT       *-
-LT       *
-LT       _dma_
-
-LTA      *+,_arp_                   Load T register and accumulate
-LTA      *-,_arp_                     product
-LTA      *, _arp_
-LTA      *+
-LTA      *-
-LTA      *
-LTA      _dma_
-
-LTD      *+,_arp_                   Load T reg, accumulate product,
-LTD      *-,_arp_                     and move
-LTD      *, _arp_
-LTD      *+
-LTD      *-
-LTD      *
-LTD      _dma_
-
-MAR      *+,_arp_                   Modify auxiliary register
-MAR      *-,_arp_
-MAR      *, _arp_
-MAR      *+
-MAR      *-
-MAR      *
-MAR      _dma_
-
-MPY      *+,_arp_                   Multiply
-MPY      *-,_arp_
-MPY      *, _arp_
-MPY      *+
-MPY      *-
-MPY      *
-MPY      _dma_
-
-MPYK     _const13_                  Multiply immediate
-
-NOP                                 No Operation
-
-OR       *+,_arp_                   OR  with low order bits of ACC
-OR       *-,_arp_
-OR       *, _arp_
-OR       *+
-OR       *-
-OR       *
-OR       _dma_
-
-OUT      *+,_port_,_arp_            Output data to port
-OUT      *-,_port_,_arp_
-OUT      *, _port_,_arp_
-OUT      *+,_port_
-OUT      *-,_port_
-OUT      *, _port_
-OUT      _dma_,_port_
-
-PAC                                 Load ACC with P register
-POP                                 Pop top of stack to ACC
-PUSH                                Push ACC onto stack
-RET                                 Return from subroutine
-ROVM                                Reset overflow mode register
-
-SACH     *+,_shift_,_arp_           Store ACC high with shift
-SACH     *-,_shift_,_arp_             Note: shift can only be 0, 1,
-SACH     *, _shift_,_arp_                   or 4
-SACH     *+,_shift_
-SACH     *-,_shift_
-SACH     *, _shift_
-SACH     *+
-SACH     *-
-SACH     *
-SACH     _dma_,_shift_
-SACH     _dma_
-
-SACL     *+,_arp_                   Store ACC low
-SACL     *-,_arp_
-SACL     *, _arp_
-SACL     *+
-SACL     *-
-SACL     *
-SACL     _dma_
-
-SAR      _ar_,*+,_arp_              Store auxiliary Register
-SAR      _ar_,*-,_arp_
-SAR      _ar_,*, _arp_
-SAR      _ar_,*+
-SAR      _ar_,*-
-SAR      _ar_,*
-SAR      _ar_,_dma_
-
-SOVM                                Set overflow mode register
-SPAC                                Subtract P register from ACC
-
-SST      *+,_arp_                   Store status
-SST      *-,_arp_
-SST      *, _arp_
-SST      *+
-SST      *-
-SST      *
-SST      _dma_
-
-SUB      *+,_shift_,_arp_           Subtract from ACC with shift
-SUB      *-,_shift_,_arp_
-SUB      *, _shift_,_arp_
-SUB      *+,_shift_
-SUB      *-,_shift_
-SUB      *, _shift_
-SUB      *+
-SUB      *-
-SUB      *
-SUB      _dma_,_shift_
-SUB      _dma_
-
-SUBC     *+,_arp_                   Conditional subtract
-SUBC     *-,_arp_
-SUBC     *, _arp_
-SUBC     *+
-SUBC     *-
-SUBC     *
-SUBC     _dma_
-
-SUBH     *+,_arp_                   Subtract from high-order ACC
-SUBH     *-,_arp_
-SUBH     *, _arp_
-SUBH     *+
-SUBH     *-
-SUBH     *
-SUBH     _dma_
-
-SUBS     *+,_arp_                   Subtract from low ACC with
-SUBS     *-,_arp_                     sign-extension suppressed
-SUBS     *, _arp_
-SUBS     *+
-SUBS     *-
-SUBS     *
-SUBS     _dma_
-
-TBLR     *+,_arp_                   Table Read
-TBLR     *-,_arp_
-TBLR     *, _arp_
-TBLR     *+
-TBLR     *-
-TBLR     *
-TBLR     _dma_
-
-TBLW     *+,_arp_                   Table Write
-TBLW     *-,_arp_
-TBLW     *, _arp_
-TBLW     *+
-TBLW     *-
-TBLW     *
-TBLW     _dma_
-
-XOR      *+,_arp_                   Exclusive OR with low bits of ACC
-XOR      *-,_arp_
-XOR      *, _arp_
-XOR      *+
-XOR      *-
-XOR      *
-XOR      _dma_
-
-ZAC                                 Zero the ACC
-
-ZALH     *+,_arp_                   Zero ACC and load high
-ZALH     *-,_arp_
-ZALH     *, _arp_
-ZALH     *+
-ZALH     *-
-ZALH     *
-ZALH     _dma_
-
-ZALS     *+,_arp_                   Zero ACC and load low with
-ZALS     *-,_arp_                     sign extension suppressed
-ZALS     *, _arp_
-ZALS     *+
-ZALS     *-
-ZALS     *
-ZALS     _dma_
-
-

See manufacturer's data for more information. -

-
-

TMS32025 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the TMS32025 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_ar_                Auxiliary register (AR0, AR1, ...)
-_arp_               Auxiliary register pointer
-_nextarp_           Auxiliary register pointer (for next operation)
-_dma_               Direct memory address
-_pma_               Program memory address
-_port_              Port address (0 - 7)
-_shift_             Shift count  (0 - 15)
-_const1_            Constant (1 bit)
-_const2_            Constant (2 bit)
-_const8_            Constant (8 bit)
-_const13_           Constant (13 bit)
-_ind_               Indirect addressing mode indicator
-                      (see following table)
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics except for _ind_. The _ind_ symbolic must be one of the following: -

-
        
-_ind_
--------
-*BR0+
-*BR0-
-*0+
-*0-
-*+
-*-
-*
-
-OPCODE   OPERAND                DESCRIPTION
---------------------------------------------------------------------
-ABS                             Absolute value of ACC
-
-ADD  _ind_,_shift_,_nextarp_    Add to ACC with shift
-ADD  _ind_,_shift_
-ADD  _ind_
-ADD  _dma_,_shift_
-ADD  _dma_
-
-ADDC _ind_,_nextarp_            Add to ACC with carry
-ADDC _ind_
-ADDC _dma_
-
-ADDH _ind_,_nextarp_            Add to high ACC
-ADDH _ind_
-ADDH _dma_
-
-ADDK _const8_                   Add to ACC short immediate
-ADDS _ind_,_nextarp_            Add to ACC with sign-extension suppressed
-ADDS _ind_
-ADDS _dma_
-
-ADDT _ind_,_nextarp_            Add to ACC with shift specified by T reg
-ADDT _ind_
-ADDT _dma_
-
-ADLK _const8_,_shift_           Add to ACC long immediate with shift
-ADLK _const8_
-
-ADRK _const8_                   Add to aux register short immediate
-
-AND  _ind_,_nextarp_            And with ACC
-AND  _ind_
-AND  _dma_
-
-ANDK _const8_,_shift_           And immediate with ACC with shift
-ANDK _const8_
-
-APAC                            Add P register to ACC
-
-B    _pma_,_ind_,_nextarp_      Branch unconditionally
-B    _pma_,_ind_
-B    _pma_
-
-BACC                            Branch to address specified by ACC
-
-BANZ _pma_,_ind_,_nextarp_      Branch on Aux register not zero
-BANZ _pma_,_ind_
-BANZ _pma_
-
-BBNZ _pma_,_ind_,_nextarp_      Branch on TC bit not zero
-BBNZ _pma_,_ind_
-BBNZ _pma_
-
-BBZ  _pma_,_ind_,_nextarp_      Branch on TC bit equal to zero
-BBZ  _pma_,_ind_
-BBZ  _pma_
-
-BC   _pma_,_ind_,_nextarp_      Branch on carry
-BC   _pma_,_ind_
-BC   _pma_
-
-BGEZ _pma_,_ind_,_nextarp_      Branch if ACC >= zero
-BGEZ _pma_,_ind_
-BGEZ _pma_
-
-BGZ  _pma_,_ind_,_nextarp_      Branch if ACC > zero
-BGZ  _pma_,_ind_
-BGZ  _pma_
-
-BIOZ _pma_,_ind_,_nextarp_      Branch on I/O status = zero
-BIOZ _pma_,_ind_
-BIOZ _pma_
-
-BIT  _ind_,_bitcode_,_nextarp_  Test bit
-BIT  _ind_,_bitcode_
-BIT  _dma_,_bitcode_
-
-BITT _ind_,_nextarp_            Test bit specified by T register
-BITT _ind_
-BITT _dma_
-
-BLEZ _pma_,_ind_,_nextarp_      Branch if ACC <= zero
-BLEZ _pma_,_ind_
-BLEZ _pma_
-
-BLKD _dma_,_ind_,_nextarp_      Block move from data mem to data mem
-BLKD _dma_,_ind_
-BLKD _dma_,_dma_
-
-BLKP _pma_,_ind_,_nextarp_      Block move from prog mem to data mem
-BLKP _pma_,_ind_
-BLKP _pma_,_dma_
-
-BLZ  _pma_,_ind_,_nextarp_      Branch if ACC < zero
-BLZ  _pma_,_ind_
-BLZ  _pma_
-
-BNC  _pma_,_ind_,_nextarp_      Branch on no carry
-BNC  _pma_,_ind_
-BNC  _pma_
-
-BNV  _pma_,_ind_,_nextarp_      Branch if no overflow
-BNV  _pma_,_ind_
-BNV  _pma_
-
-BNZ  _pma_,_ind_,_nextarp_      Branch if ACC 
-
 zero
-BNZ  _pma_,_ind_
-BNZ  _pma_
-
-BV   _pma_,_ind_,_nextarp_      Branch on overflow
-BV   _pma_,_ind_
-BV   _pma_
-
-BZ   _pma_,_ind_,_nextarp_      Branch if ACC = zero
-BZ   _pma_,_ind_
-BZ   _pma_
-
-CALA                            Call subroutine indirect
-
-CALL _pma_,_ind_,_nextarp_      Call subroutine
-CALL _pma_,_ind_
-CALL _pma_
-
-CMPL                            Complement ACC
-CMPR _const2_                   Compare Aux reg with Aux AR0
-CNFD                            Configure block as data memory
-CNFP                            Configure block as program memory
-CONF _const2_                   Configure block as data/prog memory
-DINT                            Disable interrupt
-
-DMOV _ind_,_nextarp_            Data move in data memory
-DMOV _ind_
-DMOV _dma_
-
-EINT                            Enable interrupt
-
-FORT _const1_                   Format serial port registers
-
-IDLE                            Idle until interrupt
-
-IN   _ind_,_port_,_nextarp_     Input data from port
-IN   _ind_,_port_
-IN   _dma_,_port_
-
-LAC  _ind_,_shift_,_nextarp_    Load ACC with shift
-LAC  _ind_,_shift_
-LAC  _ind_
-LAC  _dma_,_shift_
-LAC  _dma_
-
-LACK _const8_                   Load ACC immediate short
-
-LACT _ind_,_nextarp_            Load ACC with shift specified by T reg
-LACT _ind_
-LACT _dma_
-
-LALK _const16_,_shift_          Load ACC long immediate with shift
-LALK _const16_
-
-LAR  _ar_,_ind_,_nextarp_       Load auxilary register
-LAR  _ar_,_ind_
-LAR  _ar_,_dma_
-
-LARK _ar_,_const8_              Load auxilary register immediate short
-
-LARP _arp_                      Load auxilary register pointer
-
-LDP  _ind_,_nextarp_            Load data memory page pointer
-LDP  _ind_
-LDP  _dma_
-
-LDPK _const8_                   Load data memory page pointer immediate
-
-LPH  _ind_,_nextarp_            Load high P register
-LPH  _ind_
-LPH  _dma_
-
-LRLK _ar_,_const16_             Load auxilary register long immediate
-
-LST  _ind_,_nextarp_            Load status register ST0
-LST  _ind_
-LST  _dma_
-
-LST1 _ind_,_nextarp_            Load status register ST1
-LST1 _ind_
-LST1 _dma_
-
-LT   _ind_,_nextarp_            Load T register
-LT   _ind_
-LT   _dma_
-
-LTA  _ind_,_nextarp_            Load T reg and accumulate prev product
-LTA  _ind_
-LTA  _dma_
-
-LTD  _ind_,_nextarp_            Load T reg, accum prev product & move
-LTD  _ind_
-LTD  _dma_
-
-LTP  _ind_,_nextarp_            Load T reg and store P in ACC
-LTP  _ind_
-LTP  _dma_
-
-LTS  _ind_,_nextarp_            Load T reg, subract previous product
-LTS  _ind_
-LTS  _dma_
-
-MAC  _pma_,_ind_,_nextarp_      Multiply and accumulate
-MAC  _pma_,_ind_
-MAC  _pma_,_dma_
-
-MACD _pma_,_ind_,_nextarp_      Multiply and accumulate with data move
-MACD _pma_,_ind_
-MACD _pma_,_dma_
-
-MAR  _ind_,_nextarp_            Modify auxiliary register
-MAR  _ind_
-MAR  _dma_
-
-MPY  _ind_,_nextarp_            Multiply
-MPY  _ind_
-MPY  _dma_
-
-MPYA _ind_,_nextarp_            Multiply and accum previous product
-MPYA _ind_
-MPYA _dma_
-
-MPYK _const13_                  Multiply immediate
-
-MPYS _ind_,_nextarp_            Multiply and subtract previous product
-MPYS _ind_
-MPYS _dma_
-
-MPYU _ind_,_nextarp_            Multiply unsigned
-MPYU _ind_
-MPYU _dma_
-
-NEG                             Negate ACC
-
-NOP                             No operation
-
-NORM _ind_                      Normalize contents of ACC
-NORM
-
-OR   _ind_,_nextarp_            Or with ACC
-OR   _ind_
-OR   _dma_
-
-ORK  _dma_,_shift_              Or immediate with ACC with shift
-ORK  _dma_
-
-OUT  _ind_,_shift_,_nextarp_    Output data to port
-OUT  _ind_,_shift_
-OUT  _dma_,_shift_
-
-PAC                             Load ACC with P register
-
-POP                             Pop top of stack to low ACC
-
-POPD _ind_,_nextarp_            Pop top of stack to data memory
-POPD _ind_
-POPD _dma_
-
-PSHD _ind_,_nextarp_            Push data memory value onto stack
-PSHD _ind_
-PSHD _dma_
-
-PUSH                            Push low ACC onto stack
-RC                              Reset carry bit
-RET                             Return from subroutine
-RFSM                            Reset serial port frame syn mode
-RHM                             Reset hold mode
-ROL                             Rotate ACC left
-ROR                             Rotate ACC right
-ROVM                            Reset overflow mode
-
-RPT  _ind_,_nextarp_            Repeat instructions as per data mem
-RPT  _ind_
-RPT  _dma_
-
-RPTK _const8_                   Repeat instructions as per immediate
-
-RSXM                            Reset sign extension mode
-RTC                             Reset test control flag
-RTXM                            Reset serial port transmit mode
-RXF                             Reset external flag
-
-SACH _ind_,_shift_,_nextarp_    Store high ACC with shift
-SACH _ind_,_shift_
-SACH _ind_
-SACH _dma_,_shift_
-SACH _dma_
-
-SACL _ind_,_shift_,_nextarp_    Store low ACC with shift
-SACL _ind_,_shift_
-SACL _ind_
-SACL _dma_,_shift_
-SACL _dma_
-
-SAR  _ar_,_ind_,_nextarp_       Store AUX register
-SAR  _ar_,_ind_
-SAR  _ar_,_dma_
-
-SBLK _const16_,_shift_          Subtract from ACC long immediate with shift
-SBLK _const16_
-
-SBRK _const8_                   Subtract from AUX register short immediate
-
-SC                              Set carry bit
-SFL                             Shift ACC left
-SFR                             Shift ACC right
-SFSM                            Set serial port frame sync mode
-SHM                             Set hold mode
-SOVM                            Set overflow mode
-SPAC                            Subtract P register from ACC
-
-SPH  _ind_,_nextarp_            Store high P register
-SPH  _ind_
-SPH  _dma_
-
-SPL  _ind_,_nextarp_            Store low P register
-SPL  _ind_
-SPL  _dma_
-
-SPM  _dma_                      Set P register output shift mode
-
-SQRA _ind_,_nextarp_            Square and accumulate previous product
-SQRA _ind_
-SQRA _dma_
-
-SQRS _ind_,_nextarp_            Square and subtract previous product
-SQRS _ind_
-SQRS _dma_
-
-SST  _ind_,_nextarp_            Store status register ST0
-SST  _ind_
-SST  _dma_
-
-SST1 _ind_,_nextarp_            Store status register ST1
-SST1 _ind_
-SST1 _dma_
-
-SSXM                            Set sign extension mode
-STC                             Set test/control flag
-STXM                            Set serial port transmit mode
-
-
-SUB  _ind_,_shift_,_nextarp_    Subtract from ACC with shift
-SUB  _ind_,_shift_
-SUB  _ind_
-SUB  _dma_,_shift_
-SUB  _dma_
-
-SUBB _ind_,_nextarp_            Subtract from ACC with borrow
-SUBB _ind_
-SUBB _dma_
-SUBC _ind_,_nextarp_            Subtract conditional
-SUBC _ind_
-SUBC _dma_
-
-SUBH _ind_,_nextarp_            Subtract from high ACC
-SUBH _ind_
-SUBH _dma_
-
-SUBK _const8_                   Subtract from ACC short immediate
-
-SUBS _ind_,_nextarp_            Subtract from low ACC without sign-extension
-SUBS _ind_
-SUBS _dma_
-
-SUBT _ind_,_nextarp_            Subtract from ACC with shift as per T reg
-SUBT _ind_
-SUBT _dma_
-
-SXF                             Set external flag
-
-TBLR _ind_,_nextarp_            Table read
-TBLR _ind_
-TBLR _dma_
-
-TBLW _ind_,_nextarp_            Table write
-TBLW _ind_
-TBLW _dma_
-
-TRAP                            Software interrupt
-
-XOR  _ind_,_nextarp_            Exclusive OR with ACC
-XOR  _ind_
-XOR  _dma_
-
-XORK_dma_,_shift_               Exclusive OR immediate ACC with shift
-XORK _dma_
-
-ZAC                             Zero ACC
-
-ZALH _ind_,_nextarp_            Zero low ACC and load high ACC
-ZALH _ind_
-ZALH _dma_
-
-ZALR _ind_,_nextarp_            Zero low ACC, load high ACC with rounding
-ZALR _ind_
-ZALR _dma_
-
-ZALS _ind_,_nextarp_            Zero ACC, load low ACC without sign-extension
-ZALS _ind_
-ZALS _dma_
-
-
-
-

TMS7000 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the TMS7000 version of TASM. The following -symbolic fields used in the table: -

-
SYMBOLIC        DESCRIPTION
--------------------------------------------
-_iop_           Immediate data (8 bits)
-_Rn_            Register file (memory locations 0 to 127 or
-                   0 to 255 depending on on-chip RAM)
-_Pn_            Peripheral file (0-255)
-_rel_           Program address (relative)
-_addr_          Program address (16 bit)
-_trap_          Trap number (0-23)
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-

Note that TASM allows an alternate syntax for expressing indirection. -Parenthesis can be replaced with brackets (which are less ambiguous because they -do not occur in expressions). Thus, the following are equivalent: -

-
    BR      @addr1(B)
-    BR      @addr1[B]
-
-
OPCODE  OPERANDS
----------------------------------------
-ADC    B,A
-ADC    %_iop_,A
-ADC    %_iop_,B
-ADC    %_iop_,_Rn_
-ADC    _Rn_,A
-ADC    _Rn_,B
-ADC    _Rn_,_Rn_
-
-ADD    B,A
-ADD    %_iop_,A
-ADD    %_iop_,B
-ADD    %_iop_,_Rn_
-ADD    _Rn_,A
-ADD    _Rn_,B
-ADD    _Rn_,_Rn_
-
-AND    B,A
-AND    %_iop_,A
-AND    %_iop_,B
-AND    %_iop_,_Rn_
-AND    _Rn_,A
-AND    _Rn_,B
-AND    _Rn_,_Rn_
-
-ANDP   A,_Pn_
-ANDP   B,_Pn_
-ANDP   %_iop_,_Pn_
-
-BTJO   B,A,_rel_
-BTJO   %_iop_,A,_rel_
-BTJO   %_iop_,B,_rel_
-BTJO   %_iop_,_Rn_,_rel_
-BTJO   _Rn_,A,_rel_
-BTJO   _Rn_,B,_rel_
-BTJO   _Rn_,_Rn_,_rel_
-
-BTJOP  A,_Pn_,_rel_
-BTJOP  B,_Pn_,_rel_
-BTJOP  %_iop_,_Pn_,_rel_
-
-BTJZ   B,A,_rel_
-BTJZ   %_iop_,A,_rel_
-BTJZ   %_iop_,B,_rel_
-BTJZ   %_iop_,_Rn_,_rel_
-BTJZ   _Rn_,A,_rel_
-BTJZ   _Rn_,B,_rel_
-BTJZ   _Rn_,_Rn_,_rel_
-
-BTJZP  A,_Pn_,_rel_
-BTJZP  B,_Pn_,_rel_
-BTJZP  %_iop_,_Pn_,_rel_
-
-BR      @_addr_(B)
-BR      @_addr_[B]
-BR      @_addr_
-BR      *_Rn_
-
-CALL    @_addr_(B)
-CALL    @_addr_[B]
-CALL    @_addr_
-CALL    *_Rn_
-
-CLR     A
-CLR     B
-CLR     _Rn_
-CLRC
-
-CMP     B,A
-CMP     %_iop_,A
-CMP     %_iop_,B
-CMP     %_iop_,_Rn_
-CMP     _Rn_,A
-CMP     _Rn_,B
-CMP     _Rn_,_Rn_
-
-CMPA    @_addr_(B)
-CMPA    @_addr_[B]
-CMPA    @_addr_
-CMPA    *_Rn_
-
-DAC     B,A
-DAC     %_iop_,A
-DAC     %_iop_,B
-DAC     %_iop_,_Rn_
-DAC     _Rn_,A
-DAC     _Rn_,B
-DAC     _Rn_,_Rn_
-
-DEC     A
-DEC     B
-DEC     _Rn_
-
-DECD    A
-DECD    B
-DECD    _Rn_
-
-DINT
-
-DJNZ    A,_rel_
-DJNZ    B,_rel_
-DJNZ    _Rn_,_rel_
-
-DSB     B,A
-DSB     %_iop_,A
-DSB     %_iop_,B
-DSB     %_iop_,_Rn_
-DSB     _Rn_,A
-DSB     _Rn_,B
-DSB     _Rn_,_Rn_
-
-EINT
-IDLE
-
-INC     A
-INC     B
-INC     _Rn_
-
-INV     A
-INV     B
-INV     _Rn_
-
-JMP     _rel_
-
-JC      _rel_
-JEQ     _rel_
-JGE     _rel_
-JGT     _rel_
-JHS     _rel_
-JL      _rel_
-JN      _rel_
-JNC     _rel_
-JNE     _rel_
-JNZ     _rel_
-JP      _rel_
-JPZ     _rel_
-JZ      _rel_
-
-LDA     @_addr_(B)
-LDA     @_addr_[B]
-LDA     @_addr_
-LDA     *_Rn_
-
-LDSP
-
-MOV     A,B
-MOV     B,A
-MOV     A,_Rn_
-MOV     B,_Rn_
-MOV     %_iop_,A
-MOV     %_iop_,B
-MOV     %_iop_,_Rn_
-MOV     _Rn_,A
-MOV     _Rn_,B
-MOV     _Rn_,_Rn_
-
-MOVD    %_iop_[B],_Rn_
-MOVD    %_iop_,_Rn_
-MOVD    _Rn_,_Rn_
-
-MOVP    A,_Pn_
-MOVP    B,_Pn_
-MOVP    %_iop_,_Pn_
-MOVP    _Pn_,A
-MOVP    _Pn_,B
-
-MPY     B,A
-MPY     %_iop_,A
-MPY     %_iop_,B
-MPY     %_iop_,_Rn_
-MPY     _Rn_,A
-MPY     _Rn_,B
-MPY     _Rn_,_Rn_
-
-NOP
-
-OR      B,A
-OR      %_iop_,A
-OR      %_iop_,B
-OR      %_iop_,_Rn_
-OR      _Rn_,A
-OR      _Rn_,B
-OR      _Rn_,_Rn_
-
-ORP     A,_Pn_
-ORP     B,_Pn_
-ORP     %_iop_,_Pn_
-
-POP     A
-POP     B
-POP     ST
-POP     _Rn_
-POPST
-
-PUSH    A
-PUSH    B
-PUSH    ST
-PUSH    _Rn_
-PUSHST
-
-RETI
-
-RETS
-
-RL      A
-RL      B
-RL      _Rn_
-
-RLC     A
-RLC     B
-RLC     _Rn_
-
-RR      A
-RR      B
-RR      _Rn_
-
-RRC     A
-RRC     B
-RRC     _Rn_
-
-SBB     B,A
-SBB     %_iop_,A
-SBB     %_iop_,B
-SBB     %_iop_,_Rn_
-SBB     _Rn_,A
-SBB     _Rn_,B
-SBB     _Rn_,_Rn_
-
-SETC
-
-STA     @_addr_(B)
-STA     @_addr_[B]
-STA     @_addr_
-STA     *_Rn_
-
-STSP
-
-SUB     B,A
-SUB     %_iop_,A
-SUB     %_iop_,B
-SUB     %_iop_,_Rn_
-SUB     _Rn_,A
-SUB     _Rn_,B
-SUB     _Rn_,_Rn_
-
-SWAP    A
-SWAP    B
-SWAP    _Rn_
-
-TRAP    _trap_
-
-TST     A
-TSTA
-TST     B
-TSTB
-
-XCHB    A
-XCHB    _Rn_
-
-XOR     B,A
-XOR     %_iop_,A
-XOR     %_iop_,B
-XOR     %_iop_,_Rn_
-XOR     _Rn_,A
-XOR     _Rn_,B
-XOR     _Rn_,_Rn_
-
-XORP    A,_Pn_
-XORP    B,_Pn_
-XORP    %_iop_,_Pn_
-
-
diff --git a/branches/s100/Tools/tasm32/TEST05.ASM b/branches/s100/Tools/tasm32/TEST05.ASM deleted file mode 100644 index 858a575d..00000000 --- a/branches/s100/Tools/tasm32/TEST05.ASM +++ /dev/null @@ -1,251 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test05.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 6805 -; - - - .org 0 -bit3 .equ 3 -data .equ $12 - .block $46 -addz .equ $46 - - .org $1007 -addr: - ADC #data ;A9 2 NOP 1 - ADC ,X ;F9 1 NOP 1 - ADC addr,X ;D9 3 MZERO 1 - ADC addz,X ;D9 3 MZERO 1 - ADC addr ;C9 3 MZERO 1 - ADC addz ;C9 3 MZERO 1 - - ADD #data ;AB 2 NOP 1 - ADD ,X ;FB 1 NOP 1 - ADD addr,X ;DB 3 MZERO 1 - ADD addz,X ;DB 3 MZERO 1 - ADD addr ;CB 3 MZERO 1 - ADD addz ;CB 3 MZERO 1 - - AND #data ;A4 2 NOP 1 - AND ,X ;F4 1 NOP 1 - AND addr,X ;D4 3 MZERO 1 - AND addz,X ;D4 3 MZERO 1 - AND addr ;C4 3 MZERO 1 - AND addz ;C4 3 MZERO 1 - - ASLA ;48 1 NOP 1 - ASLX ;58 1 NOP 1 - ASL ,X ;78 1 NOP 1 - ASL addz,X ;68 2 NOP 1 - ASL addz ;38 2 NOP 1 - - ASRA ;47 1 NOP 1 - ASRX ;57 1 NOP 1 - ASR ,X ;77 1 NOP 1 - ASR addz,X ;37 2 NOP 1 - ASR addz ;37 2 NOP 1 - -loop1: - BCC loop1 ;24 2 R1 1 - BCS loop1 ;25 2 R1 1 - BEQ loop1 ;27 2 R1 1 - BHCC loop1 ;28 2 R1 1 - BHCS loop1 ;29 2 R1 1 - BHI loop1 ;22 2 R1 1 - BHS loop1 ;24 2 R1 1 - BIH loop1 ;2F 2 R1 1 - BIL loop1 ;2E 2 R1 1 - - BIT #data ;A5 2 NOP 1 - BIT ,X ;F5 1 NOP 1 - BIT addr,X ;D5 3 MZERO 1 - BIT addz,X ;C5 3 MZERO 1 - BIT addr ;C5 3 MZERO 1 - BIT addz ;C5 3 MZERO 1 - - BLO loop1 ;25 2 R1 1 - BLS loop1 ;23 2 R1 1 - BMC loop1 ;2C 2 R1 1 - BMI loop1 ;2B 2 R1 1 - BMS loop1 ;2D 2 R1 1 - BNE loop1 ;26 2 R1 1 - BPL loop1 ;2A 2 R1 1 - BRA loop1 ;20 2 R1 1 - BRN loop1 ;21 2 R1 1 - BSR loop1 ;AD 2 R1 1 - - BRCLR bit3,addz,loop1 ;01 3 MBIT 1 - BRSET bit3,addz,loop1 ;00 3 MBIT 1 - - BCLR bit3,addz ;11 2 MBIT 1 - BSET bit3,addz ;10 2 MBIT 1 - - CLC ;98 1 NOP 1 - CLI ;9A 1 NOP 1 - - CLRA ;4F 1 NOP 1 - CLRX ;5F 1 NOP 1 - CLR ,X ;7F 1 NOP 1 - CLR addz,X ;6F 2 NOP 1 - CLR addz ;3F 2 NOP 1 - - CMP #data ;A1 2 NOP 1 - CMP ,X ;F1 1 NOP 1 - CMP addr,X ;D1 3 MZERO 1 - CMP addz,X ;D1 3 MZERO 1 - CMP addr ;C1 3 MZERO 1 - CMP addz ;C1 3 MZERO 1 - - COMA ;43 1 NOP 1 - COMX ;53 1 NOP 1 - COM ,X ;73 1 NOP 1 - COM addz,X ;63 2 NOP 1 - COM addz ;33 2 NOP 1 - - CPX #data ;A3 2 NOP 1 - CPX ,X ;F3 1 NOP 1 - CPX addr,X ;D3 3 MZERO 1 - CPX addz,X ;D3 3 MZERO 1 - CPX addr ;C3 3 MZERO 1 - CPX addz ;C3 3 MZERO 1 - - DECA ;4A 1 NOP 1 - DECX ;5A 1 NOP 1 - DEX ;5A 1 NOP 1 - DEC ,X ;7A 1 NOP 1 - DEC addz,X ;6A 2 NOP 1 - DEC addz ;3A 2 NOP 1 - - EOR #data ;A8 2 NOP 1 - EOR ,X ;F8 1 NOP 1 - EOR addr,X ;D8 3 MZERO 1 - EOR addz,X ;D8 3 MZERO 1 - EOR addr ;C8 3 MZERO 1 - EOR addz ;C8 3 MZERO 1 - - INCA ;4C 1 NOP 1 - INCX ;5C 1 NOP 1 - INX ;5C 1 NOP 1 - INC ,X ;7C 1 NOP 1 - INC addz,X ;6C 2 NOP 1 - INC addz ;3C 2 NOP 1 - - JMP ,X ;FC 1 NOP 1 - JMP addr,X ;DC 3 MZERO 1 - JMP addz,X ;DC 3 MZERO 1 - JMP addr ;CC 3 MZERO 1 - JMP addz ;CC 3 MZERO 1 - - JSR ,X ;FD 1 NOP 1 - JSR addr,X ;DD 3 MZERO 1 - JSR addz,X ;DD 3 MZERO 1 - JSR addr ;CD 3 MZERO 1 - JSR addz ;CD 3 MZERO 1 - - LDA #data ;A6 2 NOP 1 - LDA ,X ;F6 1 NOP 1 - LDA addr,X ;D6 3 MZERO 1 - LDA addz,X ;D6 3 MZERO 1 - LDA addr ;C6 3 MZERO 1 - LDA addz ;C6 3 MZERO 1 - - LDX #data ;AE 2 NOP 1 - LDX ,X ;FE 1 NOP 1 - LDX addr,X ;DE 3 MZERO 1 - LDX addz,X ;DE 3 MZERO 1 - LDX addr ;CE 3 MZERO 1 - LDX addz ;CE 3 MZERO 1 - - LSLA ;48 1 NOP 1 - LSLX ;58 1 NOP 1 - LSL ,X ;78 1 NOP 1 - LSL addz,X ;68 2 NOP 1 - LSL addz ;38 2 NOP 1 - - LSRA ;44 1 NOP 1 - LSRX ;54 1 NOP 1 - LSR ,X ;74 1 NOP 1 - LSR addz,X ;64 2 NOP 1 - LSR addz ;34 2 NOP 1 - - NEGA ;40 1 NOP 1 - NEGX ;50 1 NOP 1 - NEG ,X ;70 1 NOP 1 - NEG addz,X ;60 2 NOP 1 - NEG addz ;30 2 NOP 1 - - NOP ;9D 1 NOP 1 - - ORA #data ;AA 2 NOP 1 - ORA ,X ;FA 1 NOP 1 - ORA addr,X ;DA 3 MZERO 1 - ORA addz,X ;DA 3 MZERO 1 - ORA addr ;CA 3 MZERO 1 - ORA addz ;CA 3 MZERO 1 - - ROLA ;49 1 NOP 1 - ROLX ;59 1 NOP 1 - ROL ,X ;79 1 NOP 1 - ROL addz,X ;69 2 NOP 1 - ROL addz ;39 2 NOP 1 - - RORA ;46 1 NOP 1 - RORX ;56 1 NOP 1 - ROR ,X ;76 1 NOP 1 - ROR addz,X ;66 2 NOP 1 - ROR addz ;36 2 NOP 1 - - RSP ;9C 1 NOP 1 - RTI ;80 1 NOP 1 - RTS ;81 1 NOP 1 - - SBC #data ;A2 2 NOP 1 - SBC ,X ;F2 1 NOP 1 - SBC addr,X ;D2 3 MZERO 1 - SBC addz,X ;D2 3 MZERO 1 - SBC addr ;C2 3 MZERO 1 - SBC addz ;C2 3 MZERO 1 - - SEC ;99 1 NOP 1 - SEI ;9B 1 NOP 1 - - STA ,X ;F7 1 NOP 1 - STA addr,X ;D7 3 MZERO 1 - STA addz,X ;D7 3 MZERO 1 - STA addr ;C7 3 MZERO 1 - STA addz ;C7 3 MZERO 1 - - STOP ;8E 1 NOP 1 - - STX ,X ;FF 1 NOP 1 - STX addr,X ;DF 3 MZERO 1 - STX addz,X ;DF 3 MZERO 1 - STX addr ;CF 3 MZERO 1 - STX addz ;CF 3 MZERO 1 - - SUB #data ;A0 2 NOP 1 - SUB ,X ;F0 1 NOP 1 - SUB addr,X ;D0 3 MZERO 1 - SUB addz,X ;D0 3 MZERO 1 - SUB addr ;C0 3 MZERO 1 - SUB addz ;C0 3 MZERO 1 - - SWI ;83 1 NOP 1 - - TAX ;97 1 NOP 1 - - TSTA ;4D 1 NOP 1 - TSTX ;5D 1 NOP 1 - TST ,X ;7D 1 NOP 1 - TST addz,X ;6D 2 NOP 1 - TST addz ;3D 2 NOP 1 - - TXA ;9F 1 NOP 1 - - WAIT ;8F 1 NOP 1 - .end diff --git a/branches/s100/Tools/tasm32/TEST3210.ASM b/branches/s100/Tools/tasm32/TEST3210.ASM deleted file mode 100644 index 80b4e98d..00000000 --- a/branches/s100/Tools/tasm32/TEST3210.ASM +++ /dev/null @@ -1,328 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test3210.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: TMS32010 -; - - - .org 100h -shift .equ 4 -shift0 .equ 0 -addr .equ 12h -port .equ 2 -arp .equ 1 -ar .equ 1 -const .equ 34h -const1 .equ 1h - - ABS ;7F88 2 NOP 1 - - ADD *+,shift,arp ;00A0 2 T1 1 8 0F00 - ADD *-,shift,arp ;0090 2 T1 1 8 0F00 - ADD *,shift,arp ;0080 2 T1 1 8 0F00 - ADD *+,shift ;00A8 2 T1 1 8 0F00 - ADD *-,shift ;0098 2 T1 1 8 0F00 - ADD *,shift ;0088 2 T1 1 8 0F00 - ADD *+ ;00A8 2 NOP 1 - ADD *- ;0098 2 NOP 1 - ADD * ;0088 2 NOP 1 - ADD addr,shift ;0000 2 TDMA 1 8 0F00 - ADD addr ;0000 2 T1 1 0 007F - - ADDH *+,arp ;60A0 2 T1 1 0 01 - ADDH *-,arp ;6090 2 T1 1 0 01 - ADDH *,arp ;6080 2 T1 1 0 01 - ADDH *+ ;60A8 2 NOP 1 - ADDH *- ;6098 2 NOP 1 - ADDH * ;6088 2 NOP 1 - ADDH addr ;6000 2 T1 1 0 007F - - ADDS *+,arp ;61A0 2 T1 1 0 01 - ADDS *-,arp ;6190 2 T1 1 0 01 - ADDS *,arp ;6180 2 T1 1 0 01 - ADDS *+ ;61A8 2 NOP 1 - ADDS *- ;6198 2 NOP 1 - ADDS * ;6188 2 NOP 1 - ADDS addr ;6100 2 T1 1 0 007F - - AND *+,arp ;79A0 2 T1 1 0 01 - AND *-,arp ;7990 2 T1 1 0 01 - AND *,arp ;7980 2 T1 1 0 01 - AND *+ ;79A8 2 NOP 1 - AND *- ;7998 2 NOP 1 - AND * ;7988 2 NOP 1 - AND addr ;7900 2 T1 1 0 7F - - APAC ;7F8F 2 NOP 1 - -loop1: - B loop1 ;F900 4 SWAP 1 - BANZ loop1 ;F400 4 SWAP 1 - BGEZ loop1 ;FD00 4 SWAP 1 - BGZ loop1 ;FC00 4 SWAP 1 - BIOZ loop1 ;F600 4 SWAP 1 - BLEZ loop1 ;FB00 4 SWAP 1 - BLZ loop1 ;FA00 4 SWAP 1 - BNZ loop1 ;FE00 4 SWAP 1 - BV loop1 ;F500 4 SWAP 1 - BZ loop1 ;FF00 4 SWAP 1 - - CALA ;7F8C 2 NOP 1 - CALL loop1 ;F800 4 SWAP 1 - DINT ;7F81 2 NOP 1 - - DMOV *+,arp ;69A0 2 T1 1 0 01 - DMOV *-,arp ;6990 2 T1 1 0 01 - DMOV *,arp ;6980 2 T1 1 0 01 - DMOV *+ ;69A8 2 NOP 1 - DMOV *- ;6998 2 NOP 1 - DMOV * ;6988 2 NOP 1 - DMOV addr ;6900 2 T1 1 0 007F - - EINT ;7F82 2 NOP 1 - - IN *+,port ,arp ;40A0 2 T1 1 8 0700 - IN *-,port ,arp ;4090 2 T1 1 8 0700 - IN * ,port ,arp ;4080 2 T1 1 8 0700 - IN *+,port ;40A8 2 T1 1 8 0700 - IN *-,port ;4098 2 T1 1 8 0700 - IN * ,port ;4088 2 T1 1 8 0700 - IN addr,port ;4000 2 TDMA 1 8 0700 - - LAC *+,shift,arp ;20A0 2 T1 1 8 0F00 - LAC *-,shift,arp ;2090 2 T1 1 8 0F00 - LAC *,shift,arp ;2080 2 T1 1 8 0F00 - LAC *+,shift ;20A8 2 T1 1 8 0F00 - LAC *-,shift ;2098 2 T1 1 8 0F00 - LAC *,shift ;2088 2 T1 1 8 0F00 - LAC *+ ;20A8 2 NOP 1 - LAC *- ;2098 2 NOP 1 - LAC * ;2088 2 NOP 1 - LAC addr,shift ;2000 2 TDMA 1 8 0F00 - LAC addr ;2000 2 T1 1 0 007F - - LACK const ;7E00 2 T1 1 0 00FF - - LAR ar,*+,arp ;38A0 2 TAR 1 0 0001 - LAR ar,*-,arp ;3890 2 TAR 1 0 0001 - LAR ar,*,arp ;3880 2 TAR 1 0 0001 - LAR ar,*+ ;38A8 2 TAR 1 0 0001 - LAR ar,*- ;3898 2 TAR 1 0 0001 - LAR ar,* ;3888 2 TAR 1 0 0001 - LAR ar, addr ;3800 2 TAR 1 0 007F - - LARK ar,const ;7000 2 TAR 1 0 00FF - LARP const1 ;6880 2 T1 1 0 0001 - - LDP *+,arp ;6FA0 2 T1 1 0 01 - LDP *-,arp ;6F90 2 T1 1 0 01 - LDP *,arp ;6F80 2 T1 1 0 01 - LDP *+ ;6FA8 2 NOP 1 - LDP *- ;6F98 2 NOP 1 - LDP * ;6F88 2 NOP 1 - LDP addr ;6F00 2 T1 1 0 007F - - LDPK const1 ;6E00 2 T1 1 0 01 - - LST *+,arp ;7BA0 2 T1 1 0 01 - LST *-,arp ;7B90 2 T1 1 0 01 - LST *,arp ;7B80 2 T1 1 0 01 - LST *+ ;7BA8 2 NOP 1 - LST *- ;7B98 2 NOP 1 - LST * ;7B88 2 NOP 1 - LST addr ;7B00 2 T1 1 0 007F - - LT *+,arp ;6AA0 2 T1 1 0 01 - LT *-,arp ;6A90 2 T1 1 0 01 - LT *,arp ;6A80 2 T1 1 0 01 - LT *+ ;6AA8 2 NOP 1 - LT *- ;6A98 2 NOP 1 - LT * ;6A88 2 NOP 1 - LT addr ;6A00 2 T1 1 0 007F - - LTA *+,arp ;6CA0 2 T1 1 0 01 - LTA *-,arp ;6C90 2 T1 1 0 01 - LTA *,arp ;6C80 2 T1 1 0 01 - LTA *+ ;6CA8 2 NOP 1 - LTA *- ;6C98 2 NOP 1 - LTA * ;6C88 2 NOP 1 - LTA addr ;6C00 2 T1 1 0 007F - - LTD *+,arp ;6BA0 2 T1 1 0 01 - LTD *-,arp ;6B90 2 T1 1 0 01 - LTD *,arp ;6B80 2 T1 1 0 01 - LTD *+ ;6BA8 2 NOP 1 - LTD *- ;6B98 2 NOP 1 - LTD * ;6B88 2 NOP 1 - LTD addr ;6B00 2 T1 1 0 007F - - MAR *+,arp ;68A0 2 T1 1 0 01 - MAR *-,arp ;6890 2 T1 1 0 01 - MAR *,arp ;6880 2 T1 1 0 01 - MAR *+ ;68A8 2 NOP 1 - MAR *- ;6898 2 NOP 1 - MAR * ;6888 2 NOP 1 - MAR addr ;6800 2 T1 1 0 007F - - MPY *+,arp ;6DA0 2 T1 1 0 01 - MPY *-,arp ;6D90 2 T1 1 0 01 - MPY *,arp ;6D80 2 T1 1 0 01 - MPY *+ ;6DA8 2 NOP 1 - MPY *- ;6D98 2 NOP 1 - MPY * ;6D88 2 NOP 1 - MPY addr ;6D00 2 T1 1 0 007F - - MPYK const ;8000 2 T1 1 0 1FFF - - NOP ;7F80 2 NOP 1 - - OR *+,arp ;7AA0 2 T1 1 0 01 - OR *-,arp ;7A90 2 T1 1 0 01 - OR *,arp ;7A80 2 T1 1 0 01 - OR *+ ;7AA8 2 NOP 1 - OR *- ;7A98 2 NOP 1 - OR * ;7A88 2 NOP 1 - OR addr ;7A00 2 T1 1 0 007F - - OUT *+,port,arp ;48A0 2 T1 1 8 0700 - OUT *-,port,arp ;4890 2 T1 1 8 0700 - OUT *, port,arp ;4880 2 T1 1 8 0700 - OUT *+,port ;48A8 2 T1 1 8 0700 - OUT *-,port ;4898 2 T1 1 8 0700 - OUT *, port ;4888 2 T1 1 8 0700 - OUT addr,port ;4800 2 TDMA 1 8 0700 - - PAC ;7F8E 2 NOP 1 - POP ;7F9D 2 NOP 1 - PUSH ;7F9C 2 NOP 1 - RET ;7F8D 2 NOP 1 - ROVM ;7F8A 2 NOP 1 - -;Note that shift count can only be 0,1, or 4. -;Mask also allows 5. Beware. - SACH *+,shift,arp ;58A0 2 T1 1 8 0500 - SACH *-,shift,arp ;5890 2 T1 1 8 0500 - SACH *, shift,arp ;5880 2 T1 1 8 0500 - SACH *+,shift ;58A8 2 T1 1 8 0500 - SACH *-,shift ;5898 2 T1 1 8 0500 - SACH *, shift ;5888 2 T1 1 8 0500 - SACH *+ ;58A8 2 NOP 1 - SACH *- ;5898 2 NOP 1 - SACH * ;5888 2 NOP 1 - SACH addr,shift ;5800 2 TDMA 1 8 0500 - SACH addr ;5800 2 T1 1 0 007F - -; Shift count must be zero for SACL - SACL *+,shift0,arp ;50A0 2 T1 1 8 0000 - SACL *-,shift0,arp ;5090 2 T1 1 8 0000 - SACL *, shift0,arp ;5080 2 T1 1 8 0000 - SACL *+,shift0 ;50A8 2 T1 1 8 0000 - SACL *-,shift0 ;5098 2 T1 1 8 0000 - SACL *, shift0 ;5088 2 T1 1 8 0000 - SACL *+ ;50A8 2 NOP 1 - SACL *- ;5098 2 NOP 1 - SACL * ;5088 2 NOP 1 - SACL addr,shift0 ;5000 2 TDMA 1 8 0000 - SACL addr ;5000 2 T1 1 0 007F - - SAR ar,*+,arp ;30A0 2 TAR 1 0 0001 - SAR ar,*-,arp ;3090 2 TAR 1 0 0001 - SAR ar,*,arp ;3080 2 TAR 1 0 0001 - SAR ar,*+ ;30A8 2 TAR 1 0 0001 - SAR ar,*- ;3098 2 TAR 1 0 0001 - SAR ar,* ;3088 2 TAR 1 0 0001 - SAR ar,addr ;3000 2 TAR 1 0 007F - - SOVM ;7F8B 2 NOP 1 - SPAC ;7F90 2 NOP 1 - - SST *+,arp ;7CA0 2 T1 1 0 0001 - SST *-,arp ;7C90 2 T1 1 0 0001 - SST *,arp ;7C80 2 T1 1 0 0001 - SST *+ ;7CA8 2 NOP 1 - SST *- ;7C98 2 NOP 1 - SST * ;7C88 2 NOP 1 - SST addr ;7C00 2 T1 1 0 007F - - SUB *+,shift,arp ;10A0 2 T1 1 8 0F00 - SUB *-,shift,arp ;1090 2 T1 1 8 0F00 - SUB *, shift,arp ;1080 2 T1 1 8 0F00 - SUB *+,shift ;10A8 2 T1 1 8 0F00 - SUB *-,shift ;1098 2 T1 1 8 0F00 - SUB *, shift ;1088 2 T1 1 8 0F00 - SUB *+ ;10A8 2 NOP 1 - SUB *- ;1098 2 NOP 1 - SUB * ;1088 2 NOP 1 - SUB addr,shift ;1000 2 TDMA 1 8 0F00 - SUB addr ;1000 2 T1 1 0 007F - - SUBC *+,arp ;64A0 2 T1 1 0 01 - SUBC *-,arp ;6490 2 T1 1 0 01 - SUBC *,arp ;6480 2 T1 1 0 01 - SUBC *+ ;64A8 2 NOP 1 - SUBC *- ;6498 2 NOP 1 - SUBC * ;6488 2 NOP 1 - SUBC addr ;6400 2 T1 1 0 007F - - SUBH *+,arp ;62A0 2 T1 1 0 01 - SUBH *-,arp ;6290 2 T1 1 0 01 - SUBH *,arp ;6280 2 T1 1 0 01 - SUBH *+ ;62A8 2 NOP 1 - SUBH *- ;6298 2 NOP 1 - SUBH * ;6288 2 NOP 1 - SUBH addr ;6200 2 T1 1 0 007F - - SUBS *+,arp ;63A0 2 T1 1 0 01 - SUBS *-,arp ;6390 2 T1 1 0 01 - SUBS *,arp ;6380 2 T1 1 0 01 - SUBS *+ ;63A8 2 NOP 1 - SUBS *- ;6398 2 NOP 1 - SUBS * ;6388 2 NOP 1 - SUBS addr ;6300 2 T1 1 0 007F - - TBLR *+,arp ;67A0 2 T1 1 0 01 - TBLR *-,arp ;6790 2 T1 1 0 01 - TBLR *,arp ;6780 2 T1 1 0 01 - TBLR *+ ;67A8 2 NOP 1 - TBLR *- ;6798 2 NOP 1 - TBLR * ;6788 2 NOP 1 - TBLR addr ;6700 2 T1 1 0 007F - - TBLW *+,arp ;7DA0 2 T1 1 0 01 - TBLW *-,arp ;7D90 2 T1 1 0 01 - TBLW *,arp ;7D80 2 T1 1 0 01 - TBLW *+ ;7DA8 2 NOP 1 - TBLW *- ;7D98 2 NOP 1 - TBLW * ;7D88 2 NOP 1 - TBLW addr ;7D00 2 T1 1 0 007F - - XOR *+,arp ;78A0 2 T1 1 0 01 - XOR *-,arp ;7890 2 T1 1 0 01 - XOR *,arp ;7880 2 T1 1 0 01 - XOR *+ ;78A8 2 NOP 1 - XOR *- ;7898 2 NOP 1 - XOR * ;7888 2 NOP 1 - XOR addr ;7800 2 T1 1 0 007F - - ZAC ;7F89 2 NOP 1 - - ZALH *+,arp ;65A0 2 T1 1 0 01 - ZALH *-,arp ;6590 2 T1 1 0 01 - ZALH *,arp ;6580 2 T1 1 0 01 - ZALH *+ ;65A8 2 NOP 1 - ZALH *- ;6598 2 NOP 1 - ZALH * ;6588 2 NOP 1 - ZALH addr ;6500 2 T1 1 0 007F - - ZALS *+,arp ;66A0 2 T1 1 0 01 - ZALS *-,arp ;6690 2 T1 1 0 01 - ZALS *,arp ;6680 2 T1 1 0 01 - ZALS *+ ;66A8 2 NOP 1 - ZALS *- ;6698 2 NOP 1 - ZALS * ;6688 2 NOP 1 - ZALS addr ;6600 2 T1 1 0 007F - .end diff --git a/branches/s100/Tools/tasm32/TEST3225.ASM b/branches/s100/Tools/tasm32/TEST3225.ASM deleted file mode 100644 index 16c885cd..00000000 --- a/branches/s100/Tools/tasm32/TEST3225.ASM +++ /dev/null @@ -1,1363 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test3225.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: TMS320C25 -; - - - .org 100h -shift: .equ 4 -shift0: .equ 0 -shiftmode: .equ 3 ;SPM instruction only -addr7: .equ 12h -addr9: .equ 123h -addr16: .equ 1234h -bit: .equ 05h -port: .equ 2 -arp: .equ 3 -nextarp: .equ 4 -ar: .equ 1 -const: .equ 34h -const1: .equ 1h -const8: .equ 0ffh -const13: .equ 0234h -const16: .equ 5678h -cmode: .equ 2 -format: .equ 1 - - ABS - - - ADD *BR0+,shift,nextarp - ADD *BR0-,shift,nextarp - ADD *0+, shift,nextarp - ADD *0-, shift,nextarp - ADD *+, shift,nextarp - ADD *-, shift,nextarp - ADD *, shift,nextarp - ADD *BR0+,shift - ADD *BR0-,shift - ADD *0+, shift - ADD *0-, shift - ADD *+, shift - ADD *-, shift - ADD *, shift - ADD *BR0+ - ADD *BR0- - ADD *0+ - ADD *0- - ADD *+ - ADD *- - ADD * - ADD addr7,shift - ADD addr7 - - ADDC *BR0+,nextarp - ADDC *BR0-,nextarp - ADDC *0+, nextarp - ADDC *0-, nextarp - ADDC *+, nextarp - ADDC *-, nextarp - ADDC *, nextarp - ADDC *BR0+ - ADDC *BR0- - ADDC *0+ - ADDC *0- - ADDC *+ - ADDC *- - ADDC * - ADDC addr7 - - ADDH *BR0+,nextarp - ADDH *BR0-,nextarp - ADDH *0+, nextarp - ADDH *0-, nextarp - ADDH *+, nextarp - ADDH *-, nextarp - ADDH *, nextarp - ADDH *BR0+ - ADDH *BR0- - ADDH *0+ - ADDH *0- - ADDH *+ - ADDH *- - ADDH * - ADDH addr7 - - - ADDK const8 - - ADDS *BR0+,nextarp - ADDS *BR0-,nextarp - ADDS *0+, nextarp - ADDS *0-, nextarp - ADDS *+, nextarp - ADDS *-, nextarp - ADDS *, nextarp - ADDS *BR0+ - ADDS *BR0- - ADDS *0+ - ADDS *0- - ADDS *+ - ADDS *- - ADDS * - ADDS addr7 - - ADDT *BR0+,nextarp - ADDT *BR0-,nextarp - ADDT *0+, nextarp - ADDT *0-, nextarp - ADDT *+, nextarp - ADDT *-, nextarp - ADDT *, nextarp - ADDT *BR0+ - ADDT *BR0- - ADDT *0+ - ADDT *0- - ADDT *+ - ADDT *- - ADDT * - ADDT addr7 - - ADLK const16,shift - ADLK const16 - ADLK 0 - ADLK 1 - ADLK 256 - ADLK 512 - ADLK $1234 - ADLK $1234,0 - - ADRK const8 - - AND *BR0+,nextarp - AND *BR0-,nextarp - AND *0+, nextarp - AND *0-, nextarp - AND *+, nextarp - AND *-, nextarp - AND *, nextarp - AND *BR0+ - AND *BR0- - AND *0+ - AND *0- - AND *+ - AND *- - AND * - AND addr7 - - ANDK const16,shift - ANDK const16 - - APAC - -loop1: - - B loop1,*BR0+,nextarp - B loop1,*BR0-,nextarp - B loop1,*0+, nextarp - B loop1,*0-, nextarp - B loop1,*+, nextarp - B loop1,*-, nextarp - B loop1,*, nextarp - B loop1,*BR0+ - B loop1,*BR0- - B loop1,*0+ - B loop1,*0- - B loop1,*+ - B loop1,*- - B loop1,* - B loop1 - - BACC - - BANZ loop1,*BR0+,nextarp - BANZ loop1,*BR0-,nextarp - BANZ loop1,*0+, nextarp - BANZ loop1,*0-, nextarp - BANZ loop1,*+, nextarp - BANZ loop1,*-, nextarp - BANZ loop1,*, nextarp - BANZ loop1,*BR0+ - BANZ loop1,*BR0- - BANZ loop1,*0+ - BANZ loop1,*0- - BANZ loop1,*+ - BANZ loop1,*- - BANZ loop1,* - BANZ loop1 - - BBNZ loop1,*BR0+,nextarp - BBNZ loop1,*BR0-,nextarp - BBNZ loop1,*0+, nextarp - BBNZ loop1,*0-, nextarp - BBNZ loop1,*+, nextarp - BBNZ loop1,*-, nextarp - BBNZ loop1,*, nextarp - BBNZ loop1,*BR0+ - BBNZ loop1,*BR0- - BBNZ loop1,*0+ - BBNZ loop1,*0- - BBNZ loop1,*+ - BBNZ loop1,*- - BBNZ loop1,* - BBNZ loop1 - - BBZ loop1,*BR0+,nextarp - BBZ loop1,*BR0-,nextarp - BBZ loop1,*0+, nextarp - BBZ loop1,*0-, nextarp - BBZ loop1,*+, nextarp - BBZ loop1,*-, nextarp - BBZ loop1,*, nextarp - BBZ loop1,*BR0+ - BBZ loop1,*BR0- - BBZ loop1,*0+ - BBZ loop1,*0- - BBZ loop1,*+ - BBZ loop1,*- - BBZ loop1,* - BBZ loop1 - - BC loop1,*BR0+,nextarp - BC loop1,*BR0-,nextarp - BC loop1,*0+, nextarp - BC loop1,*0-, nextarp - BC loop1,*+, nextarp - BC loop1,*-, nextarp - BC loop1,*, nextarp - BC loop1,*BR0+ - BC loop1,*BR0- - BC loop1,*0+ - BC loop1,*0- - BC loop1,*+ - BC loop1,*- - BC loop1,* - BC loop1 - - BGEZ loop1,*BR0+,nextarp - BGEZ loop1,*BR0-,nextarp - BGEZ loop1,*0+, nextarp - BGEZ loop1,*0-, nextarp - BGEZ loop1,*+, nextarp - BGEZ loop1,*-, nextarp - BGEZ loop1,*, nextarp - BGEZ loop1,*BR0+ - BGEZ loop1,*BR0- - BGEZ loop1,*0+ - BGEZ loop1,*0- - BGEZ loop1,*+ - BGEZ loop1,*- - BGEZ loop1,* - BGEZ loop1 - - BGZ loop1,*BR0+,nextarp - BGZ loop1,*BR0-,nextarp - BGZ loop1,*0+, nextarp - BGZ loop1,*0-, nextarp - BGZ loop1,*+, nextarp - BGZ loop1,*-, nextarp - BGZ loop1,*, nextarp - BGZ loop1,*BR0+ - BGZ loop1,*BR0- - BGZ loop1,*0+ - BGZ loop1,*0- - BGZ loop1,*+ - BGZ loop1,*- - BGZ loop1,* - BGZ loop1 - - BIOZ loop1,*BR0+,nextarp - BIOZ loop1,*BR0-,nextarp - BIOZ loop1,*0+, nextarp - BIOZ loop1,*0-, nextarp - BIOZ loop1,*+, nextarp - BIOZ loop1,*-, nextarp - BIOZ loop1,*, nextarp - BIOZ loop1,*BR0+ - BIOZ loop1,*BR0- - BIOZ loop1,*0+ - BIOZ loop1,*0- - BIOZ loop1,*+ - BIOZ loop1,*- - BIOZ loop1,* - BIOZ loop1 - - BLEZ loop1,*BR0+,nextarp - BLEZ loop1,*BR0-,nextarp - BLEZ loop1,*0+, nextarp - BLEZ loop1,*0-, nextarp - BLEZ loop1,*+, nextarp - BLEZ loop1,*-, nextarp - BLEZ loop1,*, nextarp - BLEZ loop1,*BR0+ - BLEZ loop1,*BR0- - BLEZ loop1,*0+ - BLEZ loop1,*0- - BLEZ loop1,*+ - BLEZ loop1,*- - BLEZ loop1,* - BLEZ loop1 - - BLZ loop1,*BR0+,nextarp - BLZ loop1,*BR0-,nextarp - BLZ loop1,*0+, nextarp - BLZ loop1,*0-, nextarp - BLZ loop1,*+, nextarp - BLZ loop1,*-, nextarp - BLZ loop1,*, nextarp - BLZ loop1,*BR0+ - BLZ loop1,*BR0- - BLZ loop1,*0+ - BLZ loop1,*0- - BLZ loop1,*+ - BLZ loop1,*- - BLZ loop1,* - BLZ loop1 - - BNC loop1,*BR0+,nextarp - BNC loop1,*BR0-,nextarp - BNC loop1,*0+, nextarp - BNC loop1,*0-, nextarp - BNC loop1,*+, nextarp - BNC loop1,*-, nextarp - BNC loop1,*, nextarp - BNC loop1,*BR0+ - BNC loop1,*BR0- - BNC loop1,*0+ - BNC loop1,*0- - BNC loop1,*+ - BNC loop1,*- - BNC loop1,* - BNC loop1 - - BNV loop1,*BR0+,nextarp - BNV loop1,*BR0-,nextarp - BNV loop1,*0+, nextarp - BNV loop1,*0-, nextarp - BNV loop1,*+, nextarp - BNV loop1,*-, nextarp - BNV loop1,*, nextarp - BNV loop1,*BR0+ - BNV loop1,*BR0- - BNV loop1,*0+ - BNV loop1,*0- - BNV loop1,*+ - BNV loop1,*- - BNV loop1,* - BNV loop1 - - BNZ loop1,*BR0+,nextarp - BNZ loop1,*BR0-,nextarp - BNZ loop1,*0+, nextarp - BNZ loop1,*0-, nextarp - BNZ loop1,*+, nextarp - BNZ loop1,*-, nextarp - BNZ loop1,*, nextarp - BNZ loop1,*BR0+ - BNZ loop1,*BR0- - BNZ loop1,*0+ - BNZ loop1,*0- - BNZ loop1,*+ - BNZ loop1,*- - BNZ loop1,* - BNZ loop1 - - BV loop1,*BR0+,nextarp - BV loop1,*BR0-,nextarp - BV loop1,*0+, nextarp - BV loop1,*0-, nextarp - BV loop1,*+, nextarp - BV loop1,*-, nextarp - BV loop1,*, nextarp - BV loop1,*BR0+ - BV loop1,*BR0- - BV loop1,*0+ - BV loop1,*0- - BV loop1,*+ - BV loop1,*- - BV loop1,* - BV loop1 - - BZ loop1,*BR0+,nextarp - BZ loop1,*BR0-,nextarp - BZ loop1,*0+, nextarp - BZ loop1,*0-, nextarp - BZ loop1,*+, nextarp - BZ loop1,*-, nextarp - BZ loop1,*, nextarp - BZ loop1,*BR0+ - BZ loop1,*BR0- - BZ loop1,*0+ - BZ loop1,*0- - BZ loop1,*+ - BZ loop1,*- - BZ loop1,* - BZ loop1 - - BIT *BR0+,bit ,nextarp - BIT *BR0-,bit ,nextarp - BIT *0+, bit ,nextarp - BIT *0-, bit ,nextarp - BIT *+, bit ,nextarp - BIT *-, bit ,nextarp - BIT *, bit ,nextarp - BIT *BR0+,bit - BIT *BR0-,bit - BIT *0+, bit - BIT *0-, bit - BIT *+, bit - BIT *-, bit - BIT *, bit - BIT addr7,bit - - BITT *BR0+,nextarp - BITT *BR0-,nextarp - BITT *0+, nextarp - BITT *0-, nextarp - BITT *+, nextarp - BITT *-, nextarp - BITT *, nextarp - BITT *BR0+ - BITT *BR0- - BITT *0+ - BITT *0- - BITT *+ - BITT *- - BITT * - BITT addr7 - - BLKD addr16,*BR0+,nextarp - BLKD addr16,*BR0-,nextarp - BLKD addr16,*0+, nextarp - BLKD addr16,*0-, nextarp - BLKD addr16,*+, nextarp - BLKD addr16,*-, nextarp - BLKD addr16,*, nextarp - BLKD addr16,*BR0+ - BLKD addr16,*BR0- - BLKD addr16,*0+ - BLKD addr16,*0- - BLKD addr16,*+ - BLKD addr16,*- - BLKD addr16,* - BLKD addr16,addr7 - - BLKP addr16,*BR0+,nextarp - BLKP addr16,*BR0-,nextarp - BLKP addr16,*0+, nextarp - BLKP addr16,*0-, nextarp - BLKP addr16,*+, nextarp - BLKP addr16,*-, nextarp - BLKP addr16,*, nextarp - BLKP addr16,*BR0+ - BLKP addr16,*BR0- - BLKP addr16,*0+ - BLKP addr16,*0- - BLKP addr16,*+ - BLKP addr16,*- - BLKP addr16,* - BLKP addr16,addr7 - - CALA - - CALL addr16,*BR0+,nextarp - CALL addr16,*BR0-,nextarp - CALL addr16,*0+, nextarp - CALL addr16,*0-, nextarp - CALL addr16,*+, nextarp - CALL addr16,*-, nextarp - CALL addr16,*, nextarp - CALL addr16,*BR0+ - CALL addr16,*BR0- - CALL addr16,*0+ - CALL addr16,*0- - CALL addr16,*+ - CALL addr16,*- - CALL addr16,* - CALL addr16 - - CMPL - - CMPR cmode - - CNFD - CNFP - - DINT - - DMOV *BR0+,nextarp - DMOV *BR0-,nextarp - DMOV *0+, nextarp - DMOV *0-, nextarp - DMOV *+, nextarp - DMOV *-, nextarp - DMOV *, nextarp - DMOV *BR0+ - DMOV *BR0- - DMOV *0+ - DMOV *0- - DMOV *+ - DMOV *- - DMOV * - DMOV addr7 - - EINT - - FORT format - - IDLE - - IN *BR0+,port,nextarp - IN *BR0-,port,nextarp - IN *0+, port,nextarp - IN *0-, port,nextarp - IN *+, port,nextarp - IN *-, port,nextarp - IN *, port,nextarp - IN *BR0+,port - IN *BR0-,port - IN *0+, port - IN *0-, port - IN *+, port - IN *-, port - IN *, port - IN addr7,port - - LAC *BR0+,shift,nextarp - LAC *BR0-,shift,nextarp - LAC *0+, shift,nextarp - LAC *0-, shift,nextarp - LAC *+, shift,nextarp - LAC *-, shift,nextarp - LAC *, shift,nextarp - LAC *BR0+,shift - LAC *BR0-,shift - LAC *0+, shift - LAC *0-, shift - LAC *+, shift - LAC *-, shift - LAC *, shift - LAC *BR0+ - LAC *BR0- - LAC *0+ - LAC *0- - LAC *+ - LAC *- - LAC * - LAC addr7,shift - LAC addr7 - - LACK const8 - - LACT *BR0+,nextarp - LACT *BR0-,nextarp - LACT *0+, nextarp - LACT *0-, nextarp - LACT *+, nextarp - LACT *-, nextarp - LACT *, nextarp - LACT *BR0+ - LACT *BR0- - LACT *0+ - LACT *0- - LACT *+ - LACT *- - LACT * - LACT addr7 - - LALK const16,shift - LALK const16 - - LAR arp,*BR0+,nextarp - LAR arp,*BR0-,nextarp - LAR arp,*0+, nextarp - LAR arp,*0-, nextarp - LAR arp,*+, nextarp - LAR arp,*-, nextarp - LAR arp,*, nextarp - LAR arp,*BR0+ - LAR arp,*BR0- - LAR arp,*0+ - LAR arp,*0- - LAR arp,*+ - LAR arp,*- - LAR arp,* - LAR arp,addr7 - - LARK arp, const8 - - LARP arp - - LDP *BR0+,nextarp - LDP *BR0-,nextarp - LDP *0+, nextarp - LDP *0-, nextarp - LDP *+, nextarp - LDP *-, nextarp - LDP *, nextarp - LDP *BR0+ - LDP *BR0- - LDP *0+ - LDP *0- - LDP *+ - LDP *- - LDP * - LDP addr7 - - LDPK addr9 - - LPH *BR0+,nextarp - LPH *BR0-,nextarp - LPH *0+, nextarp - LPH *0-, nextarp - LPH *+, nextarp - LPH *-, nextarp - LPH *, nextarp - LPH *BR0+ - LPH *BR0- - LPH *0+ - LPH *0- - LPH *+ - LPH *- - LPH * - LPH addr7 - - LRLK arp, const16 - - LST *BR0+,nextarp - LST *BR0-,nextarp - LST *0+, nextarp - LST *0-, nextarp - LST *+, nextarp - LST *-, nextarp - LST *, nextarp - LST *BR0+ - LST *BR0- - LST *0+ - LST *0- - LST *+ - LST *- - LST * - LST addr7 - - LST1 *BR0+,nextarp - LST1 *BR0-,nextarp - LST1 *0+, nextarp - LST1 *0-, nextarp - LST1 *+, nextarp - LST1 *-, nextarp - LST1 *, nextarp - LST1 *BR0+ - LST1 *BR0- - LST1 *0+ - LST1 *0- - LST1 *+ - LST1 *- - LST1 * - LST1 addr7 - - LT *BR0+,nextarp - LT *BR0-,nextarp - LT *0+, nextarp - LT *0-, nextarp - LT *+, nextarp - LT *-, nextarp - LT *, nextarp - LT *BR0+ - LT *BR0- - LT *0+ - LT *0- - LT *+ - LT *- - LT * - LT addr7 - - LTA *BR0+,nextarp - LTA *BR0-,nextarp - LTA *0+, nextarp - LTA *0-, nextarp - LTA *+, nextarp - LTA *-, nextarp - LTA *, nextarp - LTA *BR0+ - LTA *BR0- - LTA *0+ - LTA *0- - LTA *+ - LTA *- - LTA * - LTA addr7 - - LTD *BR0+,nextarp - LTD *BR0-,nextarp - LTD *0+, nextarp - LTD *0-, nextarp - LTD *+, nextarp - LTD *-, nextarp - LTD *, nextarp - LTD *BR0+ - LTD *BR0- - LTD *0+ - LTD *0- - LTD *+ - LTD *- - LTD * - LTD addr7 - - LTP *BR0+,nextarp - LTP *BR0-,nextarp - LTP *0+, nextarp - LTP *0-, nextarp - LTP *+, nextarp - LTP *-, nextarp - LTP *, nextarp - LTP *BR0+ - LTP *BR0- - LTP *0+ - LTP *0- - LTP *+ - LTP *- - LTP * - LTP addr7 - - LTS *BR0+,nextarp - LTS *BR0-,nextarp - LTS *0+, nextarp - LTS *0-, nextarp - LTS *+, nextarp - LTS *-, nextarp - LTS *, nextarp - LTS *BR0+ - LTS *BR0- - LTS *0+ - LTS *0- - LTS *+ - LTS *- - LTS * - LTS addr7 - - MAC addr16,*BR0+,nextarp - MAC addr16,*BR0-,nextarp - MAC addr16,*0+, nextarp - MAC addr16,*0-, nextarp - MAC addr16,*+, nextarp - MAC addr16,*-, nextarp - MAC addr16,*, nextarp - MAC addr16,*BR0+ - MAC addr16,*BR0- - MAC addr16,*0+ - MAC addr16,*0- - MAC addr16,*+ - MAC addr16,*- - MAC addr16,* - MAC addr16,addr7 - - MACD addr16,*BR0+,nextarp - MACD addr16,*BR0-,nextarp - MACD addr16,*0+, nextarp - MACD addr16,*0-, nextarp - MACD addr16,*+, nextarp - MACD addr16,*-, nextarp - MACD addr16,*, nextarp - MACD addr16,*BR0+ - MACD addr16,*BR0- - MACD addr16,*0+ - MACD addr16,*0- - MACD addr16,*+ - MACD addr16,*- - MACD addr16,* - MACD addr16,addr7 - - MAR *BR0+,nextarp - MAR *BR0-,nextarp - MAR *0+, nextarp - MAR *0-, nextarp - MAR *+, nextarp - MAR *-, nextarp - MAR *, nextarp - MAR *BR0+ - MAR *BR0- - MAR *0+ - MAR *0- - MAR *+ - MAR *- - MAR * - MAR addr7 - - MPY *BR0+,nextarp - MPY *BR0-,nextarp - MPY *0+, nextarp - MPY *0-, nextarp - MPY *+, nextarp - MPY *-, nextarp - MPY *, nextarp - MPY *BR0+ - MPY *BR0- - MPY *0+ - MPY *0- - MPY *+ - MPY *- - MPY * - MPY addr7 - - MPYA *BR0+,nextarp - MPYA *BR0-,nextarp - MPYA *0+, nextarp - MPYA *0-, nextarp - MPYA *+, nextarp - MPYA *-, nextarp - MPYA *, nextarp - MPYA *BR0+ - MPYA *BR0- - MPYA *0+ - MPYA *0- - MPYA *+ - MPYA *- - MPYA * - MPYA addr7 - - MPYK const13 - - MPYS *BR0+,nextarp - MPYS *BR0-,nextarp - MPYS *0+, nextarp - MPYS *0-, nextarp - MPYS *+, nextarp - MPYS *-, nextarp - MPYS *, nextarp - MPYS *BR0+ - MPYS *BR0- - MPYS *0+ - MPYS *0- - MPYS *+ - MPYS *- - MPYS * - MPYS addr7 - - MPYU *BR0+,nextarp - MPYU *BR0-,nextarp - MPYU *0+, nextarp - MPYU *0-, nextarp - MPYU *+, nextarp - MPYU *-, nextarp - MPYU *, nextarp - MPYU *BR0+ - MPYU *BR0- - MPYU *0+ - MPYU *0- - MPYU *+ - MPYU *- - MPYU * - MPYU addr7 - - NEG - - NOP - - NORM *BR0+ - NORM *BR0- - NORM *0+ - NORM *0- - NORM *+ - NORM *- - NORM * - NORM - - OR *BR0+,nextarp - OR *BR0-,nextarp - OR *0+, nextarp - OR *0-, nextarp - OR *+, nextarp - OR *-, nextarp - OR *, nextarp - OR *BR0+ - OR *BR0- - OR *0+ - OR *0- - OR *+ - OR *- - OR * - OR addr7 - - ORK const16, shift - ORK const16 - - OUT *BR0+,port,nextarp - OUT *BR0-,port,nextarp - OUT *0+, port,nextarp - OUT *0-, port,nextarp - OUT *+, port,nextarp - OUT *-, port,nextarp - OUT *, port,nextarp - OUT *BR0+,port - OUT *BR0-,port - OUT *0+, port - OUT *0-, port - OUT *+, port - OUT *-, port - OUT *, port - OUT addr7,port - - PAC - POP - - POPD *BR0+,nextarp - POPD *BR0-,nextarp - POPD *0+, nextarp - POPD *0-, nextarp - POPD *+, nextarp - POPD *-, nextarp - POPD *, nextarp - POPD *BR0+ - POPD *BR0- - POPD *0+ - POPD *0- - POPD *+ - POPD *- - POPD * - POPD addr7 - - PSHD *BR0+,nextarp - PSHD *BR0-,nextarp - PSHD *0+, nextarp - PSHD *0-, nextarp - PSHD *+, nextarp - PSHD *-, nextarp - PSHD *, nextarp - PSHD *BR0+ - PSHD *BR0- - PSHD *0+ - PSHD *0- - PSHD *+ - PSHD *- - PSHD * - PSHD addr7 - - PUSH - RC - RET - RFSM - RHM - ROL - ROR - ROVM - - RPT *BR0+,nextarp - RPT *BR0-,nextarp - RPT *0+, nextarp - RPT *0-, nextarp - RPT *+, nextarp - RPT *-, nextarp - RPT *, nextarp - RPT *BR0+ - RPT *BR0- - RPT *0+ - RPT *0- - RPT *+ - RPT *- - RPT * - RPT addr7 - - RPTK const8 - - RSXM - RTC - RTXM - RXF - - SACH *BR0+,shift,nextarp - SACH *BR0-,shift,nextarp - SACH *0+, shift,nextarp - SACH *0-, shift,nextarp - SACH *+, shift,nextarp - SACH *-, shift,nextarp - SACH *, shift,nextarp - SACH *BR0+,shift - SACH *BR0-,shift - SACH *0+, shift - SACH *0-, shift - SACH *+, shift - SACH *-, shift - SACH *, shift - SACH *BR0+ - SACH *BR0- - SACH *0+ - SACH *0- - SACH *+ - SACH *- - SACH * - SACH addr7,shift - SACH addr7 - - SACL *BR0+,shift,nextarp - SACL *BR0-,shift,nextarp - SACL *0+, shift,nextarp - SACL *0-, shift,nextarp - SACL *+, shift,nextarp - SACL *-, shift,nextarp - SACL *, shift,nextarp - SACL *BR0+,shift - SACL *BR0-,shift - SACL *0+, shift - SACL *0-, shift - SACL *+, shift - SACL *-, shift - SACL *, shift - SACL *BR0+ - SACL *BR0- - SACL *0+ - SACL *0- - SACL *+ - SACL *- - SACL * - SACL addr7,shift - SACL addr7 - - SAR arp,*BR0+,nextarp - SAR arp,*BR0-,nextarp - SAR arp,*0+, nextarp - SAR arp,*0-, nextarp - SAR arp,*+, nextarp - SAR arp,*-, nextarp - SAR arp,*, nextarp - SAR arp,*BR0+ - SAR arp,*BR0- - SAR arp,*0+ - SAR arp,*0- - SAR arp,*+ - SAR arp,*- - SAR arp,* - SAR arp,addr7 - - SBLK const16, shift - SBLK const16 - - SBRK const8 - - SC - SFL - SFR - SFSM - SHM - SOVM - SPAC - - SPH *BR0+,nextarp - SPH *BR0-,nextarp - SPH *0+, nextarp - SPH *0-, nextarp - SPH *+, nextarp - SPH *-, nextarp - SPH *, nextarp - SPH *BR0+ - SPH *BR0- - SPH *0+ - SPH *0- - SPH *+ - SPH *- - SPH * - SPH addr7 - - SPL *BR0+,nextarp - SPL *BR0-,nextarp - SPL *0+, nextarp - SPL *0-, nextarp - SPL *+, nextarp - SPL *-, nextarp - SPL *, nextarp - SPL *BR0+ - SPL *BR0- - SPL *0+ - SPL *0- - SPL *+ - SPL *- - SPL * - SPL addr7 - - SPM shiftmode - - SQRA *BR0+,nextarp - SQRA *BR0-,nextarp - SQRA *0+, nextarp - SQRA *0-, nextarp - SQRA *+, nextarp - SQRA *-, nextarp - SQRA *, nextarp - SQRA *BR0+ - SQRA *BR0- - SQRA *0+ - SQRA *0- - SQRA *+ - SQRA *- - SQRA * - SQRA addr7 - - SQRS *BR0+,nextarp - SQRS *BR0-,nextarp - SQRS *0+, nextarp - SQRS *0-, nextarp - SQRS *+, nextarp - SQRS *-, nextarp - SQRS *, nextarp - SQRS *BR0+ - SQRS *BR0- - SQRS *0+ - SQRS *0- - SQRS *+ - SQRS *- - SQRS * - SQRS addr7 - - SST *BR0+,nextarp - SST *BR0-,nextarp - SST *0+, nextarp - SST *0-, nextarp - SST *+, nextarp - SST *-, nextarp - SST *, nextarp - SST *BR0+ - SST *BR0- - SST *0+ - SST *0- - SST *+ - SST *- - SST * - SST addr7 - - SST1 *BR0+,nextarp - SST1 *BR0-,nextarp - SST1 *0+, nextarp - SST1 *0-, nextarp - SST1 *+, nextarp - SST1 *-, nextarp - SST1 *, nextarp - SST1 *BR0+ - SST1 *BR0- - SST1 *0+ - SST1 *0- - SST1 *+ - SST1 *- - SST1 * - SST1 addr7 - - SSXM - STC - STXM - - SUB *BR0+,shift,nextarp - SUB *BR0-,shift,nextarp - SUB *0+, shift,nextarp - SUB *0-, shift,nextarp - SUB *+, shift,nextarp - SUB *-, shift,nextarp - SUB *, shift,nextarp - SUB *BR0+,shift - SUB *BR0-,shift - SUB *0+, shift - SUB *0-, shift - SUB *+, shift - SUB *-, shift - SUB *, shift - SUB *BR0+ - SUB *BR0- - SUB *0+ - SUB *0- - SUB *+ - SUB *- - SUB * - SUB addr7,shift - SUB addr7 - - SUBB *BR0+,nextarp - SUBB *BR0-,nextarp - SUBB *0+, nextarp - SUBB *0-, nextarp - SUBB *+, nextarp - SUBB *-, nextarp - SUBB *, nextarp - SUBB *BR0+ - SUBB *BR0- - SUBB *0+ - SUBB *0- - SUBB *+ - SUBB *- - SUBB * - SUBB addr7 - - SUBC *BR0+,nextarp - SUBC *BR0-,nextarp - SUBC *0+, nextarp - SUBC *0-, nextarp - SUBC *+, nextarp - SUBC *-, nextarp - SUBC *, nextarp - SUBC *BR0+ - SUBC *BR0- - SUBC *0+ - SUBC *0- - SUBC *+ - SUBC *- - SUBC * - SUBC addr7 - - SUBH *BR0+,nextarp - SUBH *BR0-,nextarp - SUBH *0+, nextarp - SUBH *0-, nextarp - SUBH *+, nextarp - SUBH *-, nextarp - SUBH *, nextarp - SUBH *BR0+ - SUBH *BR0- - SUBH *0+ - SUBH *0- - SUBH *+ - SUBH *- - SUBH * - SUBH addr7 - - SUBK const8 - - SUBS *BR0+,nextarp - SUBS *BR0-,nextarp - SUBS *0+, nextarp - SUBS *0-, nextarp - SUBS *+, nextarp - SUBS *-, nextarp - SUBS *, nextarp - SUBS *BR0+ - SUBS *BR0- - SUBS *0+ - SUBS *0- - SUBS *+ - SUBS *- - SUBS * - SUBS addr7 - - SUBT *BR0+,nextarp - SUBT *BR0-,nextarp - SUBT *0+, nextarp - SUBT *0-, nextarp - SUBT *+, nextarp - SUBT *-, nextarp - SUBT *, nextarp - SUBT *BR0+ - SUBT *BR0- - SUBT *0+ - SUBT *0- - SUBT *+ - SUBT *- - SUBT * - SUBT addr7 - - SXF - - TBLR *BR0+,nextarp - TBLR *BR0-,nextarp - TBLR *0+, nextarp - TBLR *0-, nextarp - TBLR *+, nextarp - TBLR *-, nextarp - TBLR *, nextarp - TBLR *BR0+ - TBLR *BR0- - TBLR *0+ - TBLR *0- - TBLR *+ - TBLR *- - TBLR * - TBLR addr7 - - TBLW *BR0+,nextarp - TBLW *BR0-,nextarp - TBLW *0+, nextarp - TBLW *0-, nextarp - TBLW *+, nextarp - TBLW *-, nextarp - TBLW *, nextarp - TBLW *BR0+ - TBLW *BR0- - TBLW *0+ - TBLW *0- - TBLW *+ - TBLW *- - TBLW * - TBLW addr7 - - TRAP - - XOR *BR0+,nextarp - XOR *BR0-,nextarp - XOR *0+, nextarp - XOR *0-, nextarp - XOR *+, nextarp - XOR *-, nextarp - XOR *, nextarp - XOR *BR0+ - XOR *BR0- - XOR *0+ - XOR *0- - XOR *+ - XOR *- - XOR * - XOR addr7 - - XORK const16, shift - XORK const16 - - ZAC - - ZALH *BR0+,nextarp - ZALH *BR0-,nextarp - ZALH *0+, nextarp - ZALH *0-, nextarp - ZALH *+, nextarp - ZALH *-, nextarp - ZALH *, nextarp - ZALH *BR0+ - ZALH *BR0- - ZALH *0+ - ZALH *0- - ZALH *+ - ZALH *- - ZALH * - ZALH addr7 - - ZALR *BR0+,nextarp - ZALR *BR0-,nextarp - ZALR *0+, nextarp - ZALR *0-, nextarp - ZALR *+, nextarp - ZALR *-, nextarp - ZALR *, nextarp - ZALR *BR0+ - ZALR *BR0- - ZALR *0+ - ZALR *0- - ZALR *+ - ZALR *- - ZALR * - ZALR addr7 - - ZALS *BR0+,nextarp - ZALS *BR0-,nextarp - ZALS *0+, nextarp - ZALS *0-, nextarp - ZALS *+, nextarp - ZALS *-, nextarp - ZALS *, nextarp - ZALS *BR0+ - ZALS *BR0- - ZALS *0+ - ZALS *0- - ZALS *+ - ZALS *- - ZALS * - ZALS addr7 - .end - diff --git a/branches/s100/Tools/tasm32/TEST48.ASM b/branches/s100/Tools/tasm32/TEST48.ASM deleted file mode 100644 index 8cab0e93..00000000 --- a/branches/s100/Tools/tasm32/TEST48.ASM +++ /dev/null @@ -1,279 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test48.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8048 -; - - -label1 .equ 12H - - ADD A,R0 - ADD A,R1 - ADD A,R2 - ADD A,R3 - ADD A,R4 - ADD A,R5 - ADD A,R6 - ADD A,R7 - ADD A,@R0 - ADD A,@R1 - ADD A,#label1 - - ADDC A,R0 - ADDC A,R1 - ADDC A,R2 - ADDC A,R3 - ADDC A,R4 - ADDC A,R5 - ADDC A,R6 - ADDC A,R7 - ADDC A,@R0 - ADDC A,@R1 - ADDC A,#label1 - - ANL A,R0 - ANL A,R1 - ANL A,R2 - ANL A,R3 - ANL A,R4 - ANL A,R5 - ANL A,R6 - ANL A,R7 - ANL A,@R0 - ANL A,@R1 - ANL A,#label1 - ANL BUS,#label1 - ANL P1,#label1 - ANL P2,#label1 - - ANLD P4,A - ANLD P5,A - ANLD P6,A - ANLD P7,A - - CALL label1 - - CLR A - CLR C - CLR F0 - CLR F1 - - CPL A - CPL C - CPL F0 - CPL F1 - - DA A - - DEC A - DEC R0 - DEC R1 - DEC R2 - DEC R3 - DEC R4 - DEC R5 - DEC R6 - DEC R7 - - DIS I - DIS TCNTI - - DJNZ R0,label1 - DJNZ R1,label1 - DJNZ R2,label1 - DJNZ R3,label1 - DJNZ R4,label1 - DJNZ R5,label1 - DJNZ R6,label1 - DJNZ R7,label1 - - EN DMA - EN FLAGS - EN I - EN TCNTI - ENT0 CLK - - IN A,DBB - IN A,P0 - IN A,P1 - IN A,P2 - - INC A - INC R0 - INC R1 - INC R2 - INC R3 - INC R4 - INC R5 - INC R6 - INC R7 - INC @R0 - INC @R1 - - INS A,BUS - - JB0 label1 - JB1 label1 - JB2 label1 - JB3 label1 - JB4 label1 - JB5 label1 - JB6 label1 - JB7 label1 - - JMP label1 - - JC label1 - JF0 label1 - JF1 label1 - JNC label1 - JNI label1 - JNIBF label1 - JNT0 label1 - JNT1 label1 - JNZ label1 - JOBF label1 - JTF label1 - JT0 label1 - JT1 label1 - JZ label1 - - JMPP @A - - MOV A,PSW - MOV A,R0 - MOV A,R1 - MOV A,R2 - MOV A,R3 - MOV A,R4 - MOV A,R5 - MOV A,R6 - MOV A,R7 - MOV A,T - MOV A,@R0 - MOV A,@R1 - MOV A,#label1 - MOV PSW,A - MOV R0,A - MOV R1,A - MOV R2,A - MOV R3,A - MOV R4,A - MOV R5,A - MOV R6,A - MOV R7,A - MOV R0,#label1 - MOV R1,#label1 - MOV R2,#label1 - MOV R3,#label1 - MOV R4,#label1 - MOV R5,#label1 - MOV R6,#label1 - MOV R7,#label1 - MOV STS,A - MOV T,A - MOV @R0,A - MOV @R1,A - MOV @R0,#label1 - MOV @R1,#label1 - - MOVD A,P4 - MOVD A,P5 - MOVD A,P6 - MOVD A,P7 - MOVD P4,A - MOVD P5,A - MOVD P6,A - MOVD P7,A - - MOVP A,@A - MOVP3 A,@A - - - MOVX A,@R0 - MOVX A,@R1 - MOVX @R0,A - MOVX @R1,A - - NOP - - ORL A,R0 - ORL A,R1 - ORL A,R2 - ORL A,R3 - ORL A,R4 - ORL A,R5 - ORL A,R6 - ORL A,R7 - ORL A,@R0 - ORL A,@R1 - ORL A,#label1 - ORL BUS,#label1 - ORL P1,#label1 - ORL P2,#label1 - - ORLD P4,A - ORLD P5,A - ORLD P6,A - ORLD P7,A - - OUTL BUS,A - OUT DBB,A - OUTL P0,A - OUTL P1,A - OUTL P2,A - - RAD - - RET - RETI - RETR - - RL A - RLC A - RR A - RRC A - - SEL AN0 - SEL AN1 - SEL MB0 - SEL MB1 - SEL RB0 - SEL RB1 - - STOP TCNT - STRT CNT - STRT T - - SWAP A - - XCH A,R0 - XCH A,R1 - XCH A,R2 - XCH A,R3 - XCH A,R4 - XCH A,R5 - XCH A,R6 - XCH A,R7 - XCH A,@R0 - XCH A,@R1 - - XCHD A,@R0 - XCHD A,@R1 - - XRL A,R0 - XRL A,R1 - XRL A,R2 - XRL A,R3 - XRL A,R4 - XRL A,R5 - XRL A,R6 - XRL A,R7 - XRL A,@R0 - XRL A,@R1 - XRL A,#label1 - .end diff --git a/branches/s100/Tools/tasm32/TEST51.ASM b/branches/s100/Tools/tasm32/TEST51.ASM deleted file mode 100644 index 76c43c9f..00000000 --- a/branches/s100/Tools/tasm32/TEST51.ASM +++ /dev/null @@ -1,297 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test51.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8051 -; - - - .AVSYM - -labimm: .EQU 56h -lab2: .EQU 12h -lab3: .EQU 1234h -lab5: .EQU 0feh -labbt_1: .EQU 34h -bit .equ 81h - - - ACALL lab4 ;11 2 JMP 1 -lab4: - ADD A,R0 ;28 1 NOP 1 - ADD A,R1 ;29 1 NOP 1 - ADD A,R2 ;2A 1 NOP 1 - ADD A,R3 ;2B 1 NOP 1 - ADD A,R4 ;2C 1 NOP 1 - ADD A,R5 ;2D 1 NOP 1 - ADD A,R6 ;2E 1 NOP 1 - ADD A,R7 ;2F 1 NOP 1 - ADD A,@R0 ;26 1 NOP 1 - ADD A,@R1 ;27 1 NOP 1 - ADD A,#labimm ;24 2 NOP 1 - ADD A,lab2 ;25 2 NOP 1 - - ADDC A,R0 ;38 1 NOP 1 - ADDC A,R1 ;39 1 NOP 1 - ADDC A,R2 ;3A 1 NOP 1 - ADDC A,R3 ;3B 1 NOP 1 - ADDC A,R4 ;3C 1 NOP 1 - ADDC A,R5 ;3D 1 NOP 1 - ADDC A,R6 ;3E 1 NOP 1 - ADDC A,R7 ;3F 1 NOP 1 - ADDC A,@R0 ;36 1 NOP 1 - ADDC A,@R1 ;37 1 NOP 1 - ADDC A,#labimm ;34 2 NOP 1 - ADDC A,lab2 ;35 2 NOP 1 - - AJMP jlab ;01 2 JMP 1 - - ANL A,R0 ;58 1 NOP 1 - ANL A,R1 ;59 1 NOP 1 - ANL A,R2 ;5A 1 NOP 1 - ANL A,R3 ;5B 1 NOP 1 - ANL A,R4 ;5C 1 NOP 1 - ANL A,R5 ;5D 1 NOP 1 - ANL A,R6 ;5E 1 NOP 1 - ANL A,R7 ;5F 1 NOP 1 - ANL A,@R0 ;56 1 NOP 1 - ANL A,@R1 ;57 1 NOP 1 - ANL A,#labimm - ANL A,lab2 - ANL C,/bit - ANL C,bit - ANL lab2,A - ANL lab2,#labimm - - CJNE A,#labimm,jlab ;b4 3 CR 1 - CJNE A,lab2,jlab ;b5 3 CR 1 - CJNE R0,#labimm,jlab ;b8 3 CR 1 - CJNE R1,#labimm,jlab ;b9 3 CR 1 - CJNE R2,#labimm,jlab ;ba 3 CR 1 - CJNE R3,#labimm,jlab ;bb 3 CR 1 - CJNE R4,#labimm,jlab ;bc 3 CR 1 - CJNE R5,#labimm,jlab ;bd 3 CR 1 - CJNE R6,#labimm,jlab ;be 3 CR 1 - CJNE R7,#labimm,jlab ;bf 3 CR 1 - CJNE @R0,#labimm,jlab ;b6 3 CR 1 - CJNE @R1,#labimm,jlab ;b7 3 CR 1 - - CLR A ;e4 1 NOP 1 - CLR C ;c3 1 NOP 1 - CLR bit - - CPL A ;f4 1 NOP 1 - CPL C ;b3 1 NOP 1 - CPL bit - - DA A ;d4 1 NOP 1 - - DEC A ;14 1 NOP 1 - DEC R0 ;18 1 NOP 1 - DEC R1 ;19 1 NOP 1 - DEC R2 ;1A 1 NOP 1 - DEC R3 ;1B 1 NOP 1 - DEC R4 ;1C 1 NOP 1 - DEC R5 ;1D 1 NOP 1 - DEC R6 ;1E 1 NOP 1 - DEC R7 ;1F 1 NOP 1 - DEC @R0 ;16 1 NOP 1 - DEC @R1 ;17 1 NOP 1 - DEC lab2 ;15 2 NOP 1 - - DIV AB ;84 1 NOP 1 - - DJNZ R0,jlab ;d8 2 NOP 1 - DJNZ R1,jlab ;d9 2 NOP 1 - DJNZ R2,jlab ;dA 2 NOP 1 - DJNZ R3,jlab ;dB 2 NOP 1 - DJNZ R4,jlab ;dC 2 NOP 1 - DJNZ R5,jlab ;dD 2 NOP 1 - DJNZ R6,jlab ;dE 2 NOP 1 - DJNZ R7,jlab ;dF 2 NOP 1 - DJNZ lab2,jlab ;d5 3 CR 1 - - INC A ;04 1 NOP 1 - INC R0 ;08 1 NOP 1 - INC R1 ;09 1 NOP 1 - INC R2 ;0A 1 NOP 1 - INC R3 ;0B 1 NOP 1 - INC R4 ;0C 1 NOP 1 - INC R5 ;0D 1 NOP 1 - INC R6 ;0E 1 NOP 1 - INC R7 ;0F 1 NOP 1 - INC @R0 ;06 1 NOP 1 - INC @R1 ;07 1 NOP 1 - INC DPTR ;a3 1 NOP 1 - INC lab2 ;05 2 NOP 1 - -jlab: - JB labbt_1,jlab ;20 3 CR 1 - JBC labbt_1,jlab ;10 3 CR 1 - JC jlab ;40 2 R1 1 - JMP @A+DPTR ;73 1 NOP 1 - JNB labbt_1,jlab ;30 3 CR 1 - JNC jlab ;50 2 R1 1 - JNZ jlab ;70 2 R1 1 - JZ jlab ;60 2 R1 1 - - LCALL lab3 ;12 3 SWAP 1 - - LJMP lab3 ;02 3 SWAP 1 - - MOV A,R0 ;e8 1 NOP 1 - MOV A,R1 ;e9 1 NOP 1 - MOV A,R2 ;eA 1 NOP 1 - MOV A,R3 ;eB 1 NOP 1 - MOV A,R4 ;eC 1 NOP 1 - MOV A,R5 ;eD 1 NOP 1 - MOV A,R6 ;eE 1 NOP 1 - MOV A,R7 ;eF 1 NOP 1 - MOV A,@R0 ;e6 1 NOP 1 - MOV A,@R1 ;e7 1 NOP 1 - MOV A,#labimm ;74 2 NOP 1 - MOV A,lab2 ;e5 2 NOP 1 - MOV C,bit ;a2 2 NOP 1 - MOV DPTR,#labimm ;90 3 SWAP 1 - MOV R0,A ;f8 1 NOP 1 - MOV R1,A ;f9 1 NOP 1 - MOV R2,A ;fA 1 NOP 1 - MOV R3,A ;fB 1 NOP 1 - MOV R4,A ;fC 1 NOP 1 - MOV R5,A ;fD 1 NOP 1 - MOV R6,A ;fE 1 NOP 1 - MOV R7,A ;fF 1 NOP 1 - MOV R0,#labimm ;78 2 NOP 1 - MOV R1,#labimm ;79 2 NOP 1 - MOV R2,#labimm ;7A 2 NOP 1 - MOV R3,#labimm ;7B 2 NOP 1 - MOV R4,#labimm ;7C 2 NOP 1 - MOV R5,#labimm ;7D 2 NOP 1 - MOV R6,#labimm ;7E 2 NOP 1 - MOV R7,#labimm ;7F 2 NOP 1 - MOV R0,lab2 ;a8 2 NOP 1 - MOV R1,lab2 ;a9 2 NOP 1 - MOV R2,lab2 ;aA 2 NOP 1 - MOV R3,lab2 ;aB 2 NOP 1 - MOV R4,lab2 ;aC 2 NOP 1 - MOV R5,lab2 ;aD 2 NOP 1 - MOV R6,lab2 ;aE 2 NOP 1 - MOV R7,lab2 ;aF 2 NOP 1 - MOV @R0,A ;f6 1 NOP 1 - MOV @R1,A ;f7 1 NOP 1 - MOV @R0,#labimm ;76 2 NOP 1 - MOV @R1,#labimm ;77 2 NOP 1 - MOV @R0,lab2 ;a6 2 NOP 1 - MOV @R1,lab2 ;a7 2 NOP 1 - MOV lab2,A ;f5 2 NOP 1 - MOV bit,C ;92 2 NOP 1 - MOV lab2,R0 ;88 2 NOP 1 - MOV lab2,R1 ;89 2 NOP 1 - MOV lab2,R2 ;8A 2 NOP 1 - MOV lab2,R3 ;8B 2 NOP 1 - MOV lab2,R4 ;8C 2 NOP 1 - MOV lab2,R5 ;8D 2 NOP 1 - MOV lab2,R6 ;8E 2 NOP 1 - MOV lab2,R7 ;8F 2 NOP 1 - MOV lab2,@R0 ;86 2 NOP 1 - MOV lab2,@R1 ;87 2 NOP 1 - MOV lab2,#labimm ;75 3 COMBINE 1 - MOV lab5,lab2 ;85 3 COMBINE 1 - - MOVC A,@A+DPTR ;93 1 NOP 1 - MOVC A,@A+PC ;83 1 NOP 1 - - MOVX A,@R0 ;e2 1 NOP 1 - MOVX A,@R1 ;e3 1 NOP 1 - MOVX A,@DPTR ;e0 1 NOP 1 - MOVX @R0,A ;f2 1 NOP 1 - MOVX @R1,A ;f3 1 NOP 1 - MOVX @DPTR,A ;f0 1 NOP 1 - - MUL AB ;a4 1 NOP 1 - - NOP ;00 1 NOP 1 - - ORL A,R0 ;48 1 NOP 1 - ORL A,R1 ;49 1 NOP 1 - ORL A,R2 ;4A 1 NOP 1 - ORL A,R3 ;4B 1 NOP 1 - ORL A,R4 ;4C 1 NOP 1 - ORL A,R5 ;4D 1 NOP 1 - ORL A,R6 ;4E 1 NOP 1 - ORL A,R7 ;4F 1 NOP 1 - ORL A,@R0 ;46 1 NOP 1 - ORL A,@R1 ;47 1 NOP 1 - ORL A,#labimm ;44 2 NOP 1 - ORL A,lab2 ;45 2 NOP 1 - ORL C,/bit ;a0 2 NOP 1 - ORL C,bit ;72 2 NOP 1 - ORL lab2,A ;42 2 NOP 1 - ORL lab2,#labimm ;43 3 COMBINE 1 - - POP lab2 ;d0 2 NOP 1 - PUSH lab2 ;c0 2 NOP 1 - - RET ;22 1 NOP 1 - RETI ;32 1 NOP 1 - - RL A ;23 1 NOP 1 - RLC A ;33 1 NOP 1 - RR A ;03 1 NOP 1 - RRC A ;13 1 NOP 1 - -jlab5: - SETB C ;d3 1 NOP 1 - SETB bit ;d2 2 NOP 1 - - SJMP jlab5 ;80 2 NOP 1 - - SUBB A,R0 ;98 1 NOP 1 - SUBB A,R1 ;99 1 NOP 1 - SUBB A,R2 ;9A 1 NOP 1 - SUBB A,R3 ;9B 1 NOP 1 - SUBB A,R4 ;9C 1 NOP 1 - SUBB A,R5 ;9D 1 NOP 1 - SUBB A,R6 ;9E 1 NOP 1 - SUBB A,R7 ;9F 1 NOP 1 - SUBB A,@R0 ;96 1 NOP 1 - SUBB A,@R1 ;97 1 NOP 1 - SUBB A,#labimm ;94 2 NOP 1 - SUBB A,lab2 ;95 2 NOP 1 - - SWAP A ;c4 1 NOP 1 - - XCH A,R0 ;c8 1 NOP 1 - XCH A,R1 ;c9 1 NOP 1 - XCH A,R2 ;cA 1 NOP 1 - XCH A,R3 ;cB 1 NOP 1 - XCH A,R4 ;cC 1 NOP 1 - XCH A,R5 ;cD 1 NOP 1 - XCH A,R6 ;cE 1 NOP 1 - XCH A,R7 ;cF 1 NOP 1 - XCH A,@R0 ;c6 1 NOP 1 - XCH A,@R1 ;c7 1 NOP 1 - XCH A,lab2 ;c5 2 NOP 1 - - XCHD A,@R0 ;d6 1 NOP 1 - XCHD A,@R1 ;d7 1 NOP 1 - - XRL A,R0 ;68 1 NOP 1 - XRL A,R1 ;69 1 NOP 1 - XRL A,R2 ;6A 1 NOP 1 - XRL A,R3 ;6B 1 NOP 1 - XRL A,R4 ;6C 1 NOP 1 - XRL A,R5 ;6D 1 NOP 1 - XRL A,R6 ;6E 1 NOP 1 - XRL A,R7 ;6F 1 NOP 1 - XRL A,@R0 ;66 1 NOP 1 - XRL A,@R1 ;67 1 NOP 1 - XRL A,#labimm ;64 2 NOP 1 - XRL A,lab2 ;65 2 NOP 1 - XRL lab2,A ;62 2 NOP 1 - XRL lab2,#labimm ;63 3 COMBINE 1 - - .end diff --git a/branches/s100/Tools/tasm32/TEST65.ASM b/branches/s100/Tools/tasm32/TEST65.ASM deleted file mode 100644 index 7f5f8f2f..00000000 --- a/branches/s100/Tools/tasm32/TEST65.ASM +++ /dev/null @@ -1,298 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test65.asm 1.2 1997/11/29 13:07:53 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 6502 -; - - - -#define FLAG1 -#define TORG $1234 - .org $56 -zlabel .byte $12 - .word $1234 - .word $1234/3 - .word 1234h - .word %0101010 - .word 0101010b - .word @1234 - .word 1234o - .word 1234 - .word 1234d - .word 0d - .word 1d - .word 2d - .word 3d - .word 4d - .word 10d - .word 20d - .word 100d - .word * - .word $ - .word 3 * 7 - .word 3 + 7 - .word 3 - 7 - .word 73 % 7 - .word $1234 >> 4 - .word $1234 << 4 - .word 1 = 1 - .word 1 = 0 - .word 1 >= 1 - .word 1 >= 2 - .word 1 >= 0 - .word 1 <= 1 - .word 1 <= 2 - .word 1 <= 0 - .word 1 <= -1 - .word TORG - - .org $0234 -alabel - ADC #zlabel - ADC (zlabel,X) - ADC (zlabel),Y - ADC (zlabel) - ADC (alabel & $ff) ; suppress UNUSED DATA error - ADC zlabel,X - ADC zlabel,Y - ADC zlabel - ADC alabel - - AND #zlabel - AND (zlabel,X) - AND (zlabel),Y - AND (zlabel) - AND zlabel,X - AND zlabel,Y - AND zlabel - AND alabel - - ASL A - ASL zlabel,X - ASL zlabel -loop - BCC loop - BCS loop - BEQ loop - BNE loop - BMI loop - BPL loop - BVC loop - BVS loop - - BIT #zlabel - BIT zlabel,X - BIT zlabel - BIT alabel - - BRK - - CLC - CLD - CLI - CLV - - CMP #zlabel - CMP (zlabel,X) - CMP (zlabel),Y - CMP (zlabel) - CMP zlabel,X - CMP zlabel,Y - CMP zlabel - CMP alabel - - CPX #zlabel - CPX zlabel - CPX alabel - - CPY #zlabel - CPY zlabel - CPY alabel - - DEC A - DEC zlabel,X - DEC alabel,X - DEC zlabel - DEC alabel - - DEX - DEY - - EOR #zlabel - EOR (zlabel,X) - EOR (zlabel),Y - EOR (zlabel) - EOR zlabel,X - EOR zlabel,Y - EOR zlabel - EOR alabel - - INC A - INC zlabel,X - INC alabel,X - INC zlabel - INC alabel - - INX - INY - - JMP (zlabel,X) - JMP (zlabel) - JMP zlabel - - JSR zlabel - JSR alabel - - LDA #zlabel - LDA (zlabel,X) - LDA (zlabel),Y - LDA (zlabel) - LDA zlabel,X - LDA zlabel,Y - LDA zlabel - LDA alabel - - LDX #zlabel - LDX zlabel,Y - LDX zlabel - LDX alabel - - LDY #zlabel - LDY zlabel,X - LDY zlabel - LDY alabel - - LSR A - LSR zlabel,X - LSR zlabel - LSR alabel - - NOP - - ORA #zlabel - ORA (zlabel,X) - ORA (zlabel),Y - ORA (zlabel) - ORA zlabel,X - ORA zlabel,Y - ORA zlabel - ORA alabel - - PHA - PHP - PLA - PLP - - ROL A - ROL zlabel,X - ROL zlabel - ROL alabel - - ROR A - ROR zlabel,X - ROR alabel,X - ROR zlabel - ROR alabel - - RTI - RTS - - SBC #zlabel - SBC (zlabel,X) - SBC (zlabel),Y - SBC (zlabel) - SBC zlabel,X - SBC zlabel,Y - SBC zlabel - SBC alabel - - SEC - SED - SEI - - STA (zlabel,X) - STA (zlabel),Y - STA (zlabel) - STA zlabel,X - STA zlabel,Y - STA zlabel - STA alabel - - STX zlabel,Y - STX zlabel - STX alabel - - STY zlabel,X - STY zlabel - STY alabel - - TAX - TAY - TSX - TXA - TXS - TYA - - BRA loop2 -loop2 - BBR0 zlabel,loop2 - BBR1 zlabel,loop2 - BBR2 zlabel,loop2 - BBR3 zlabel,loop2 - BBR4 zlabel,loop2 - BBR5 zlabel,loop2 - BBR6 zlabel,loop2 - BBR7 zlabel,loop2 - - BBS0 zlabel,loop2 - BBS1 zlabel,loop2 - BBS2 zlabel,loop2 - BBS3 zlabel,loop2 - BBS4 zlabel,loop2 - BBS5 zlabel,loop2 - BBS6 zlabel,loop2 - BBS7 zlabel,loop2 - - MUL - - PHX - PHY - PLX - PLY - - RMB0 zlabel - RMB1 zlabel - RMB2 zlabel - RMB3 zlabel - RMB4 zlabel - RMB5 zlabel - RMB6 zlabel - RMB7 zlabel - - SMB0 zlabel - SMB1 zlabel - SMB2 zlabel - SMB3 zlabel - SMB4 zlabel - SMB5 zlabel - SMB6 zlabel - SMB7 zlabel - - - STZ zlabel,X - STZ zlabel - STZ alabel - - TRB zlabel - TSB zlabel - .end - - - - - - diff --git a/branches/s100/Tools/tasm32/TEST68.ASM b/branches/s100/Tools/tasm32/TEST68.ASM deleted file mode 100644 index bd80b02b..00000000 --- a/branches/s100/Tools/tasm32/TEST68.ASM +++ /dev/null @@ -1,422 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test68.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 6801/6803/68HC11 -; - - -data1 .equ $12 -data2 .equ $1234 - - ABA - ABX - - ADDA #data1 ;8B - ADDA data1,X ;AB - ADDA data1 ;9B - ADDA data2 ;BB - - ADDB #data1 ;CB - ADDB data1,X ;EB - ADDB data1 ;DB - ADDB data2 ;FB - - ADCA #data1 ;89 - ADCA data1,X ;A9 - ADCA data1 ;99 - ADCA data2 ;B9 - - ADCB #data1 ;C9 - ADCB data1,X ;E9 - ADCB data1 ;D9 - ADCB data2 ;F9 - - ADDD #data1 ;C3 - ADDD data1,X ;E3 - ADDD data1 ;D3 - ADDD data2 ;F3 - - ANDA #data1 ;84 - ANDA data1,X ;A4 - ANDA data1 ;94 - ANDA data2 ;B4 - - ANDB #data1 ;C4 - ANDB data1,X ;E4 - ANDB data1 ;D4 - ANDB data2 ;F4 - - ASL data1,X ;68 - ASL data1 ;78 - ASL data2 ;78 - ASLA ;48 - ASLB ;58 - ASLD ;05 - - ASR data1,X ; - ASR data1 ; - ASR data2 ; - ASRA ; - ASRB ; - -loop1: - BRA loop1 ;20 - BRN loop1 ;21 - BCC loop1 ;24 - BCS loop1 ;25 - BEQ loop1 ;27 - BGE loop1 ;2C - BGT loop1 ;2E - BHI loop1 ;22 - BHS loop1 ;24 - - BITA #data1 ;85 - BITA data1,X ;A5 - BITA data1 ;B5 - BITA data2 ;B5 - - BITB #data1 ;C5 - BITB data1,X ;E5 - BITB data1 ;F5 - BITB data2 ;F5 - - BLE loop1 ;2F - BLO loop1 ;25 - BLS loop1 ;23 - BLT loop1 ;2D - BMI loop1 ;2B - BNE loop1 ;26 - BVC loop1 ;28 - BVS loop1 ;29 - BPL loop1 ;2A - BSR loop1 ;8D - - CBA - CLC ;0C - CLI ;0E - CLR data1,X ;6F - CLR data1 ;7F - CLR data2 ;7F - CLRA ;4F - CLRB ;5F - CLV ;0A - - COM data1,X ;63 - COM data1 ;73 - COM data2 ;73 - COMA ;43 - COMB ;53 - - CPX #data1 ;8C - CPX data1,X ;AC - CPX data1 ;9C - CPX data2 ;BC - - CMPA #data1 ; - CMPA data1,X ; - CMPA data1 ; - CMPA data2 ; - - CMPB #data1 ; - CMPB data1,X ; - CMPB data1 ; - CMPB data2 ; - - DAA ;19 - - DEC data1,X - DEC data1 - DEC data2 - - DECA ;4A - DECB ;5A - DES ;34 - DEX ;09 - - EORA #data1 ; - EORA data1,X ; - EORA data1 ; - EORA data2 ; - - EORB #data1 ; - EORB data1,X ; - EORB data1 ; - EORB data2 ; - - INC data1,X - INC data1 - INC data2 - - INCA ;4C - INCB ;5C - INS ;31 - INX ;08 - - JMP data1,X ;63 - JMP data1 ;7E - JMP data2 ;7E - - JSR data1,X ;AD - JSR data1 ;9D - JSR data2 ;BD - - LDAA #data1 ;86 - LDAA data1,X ;A6 - LDAA data1 ;96 - LDAA data2 ;B6 - - LDAB #data1 ;C6 - LDAB data1,X ;E6 - LDAB data1 ;D6 - LDAB data2 ;F6 - - LDD #data1 ;CC - LDD data1,X ;EC - LDD data1 ;DC - LDD data2 ;FC - - LDS #data1 ;8E - LDS data1,X ;AE - LDS data1 ;9E - LDS data2 ;BE - - LDX #data1 ;CE - LDX data1,X ;EE - LDX data1 ;DE - LDX data2 ;FE - - LSLA ;48 - LSLB ;58 - LSLD ;05 - - LSRA ;44 - LSRB ;54 - LSRD ;04 - LSR data1,X ;64 - LSR data1 ;74 - LSR data2 ;74 - - MUL ;3D - - NEG data1,X ;60 - NEG data1 ;70 - NEG data2 ;70 - NEGA ;40 - NEGB ;50 - - NOP ;01 - - ORAA #data1 ;8A - ORAA data1,X ;AA - ORAA data1 ;BA - ORAA data2 ;9A - - ORAB #data1 ;CA - ORAB data1,X ;EA - ORAB data1 ;DA - ORAB data2 ;FA - - PSHA ;36 - PSHB ;37 - PSHX ;3C - - PULA ;32 - PULB ;33 - PULX ;38 - - ROL data1,X ;69 - ROL data1 ;79 - ROLA ;49 - ROLB ;59 - - ROR data1,X ;66 - ROR data1 ;76 - RORA ;46 - RORB ;56 - - RTI ;3B - RTS ;39 - - SBA ;10 - - SBCA #data1 ;82 - SBCA data1,X ;A2 - SBCA data1 ;92 - SBCA data2 ;B2 - - SBCB #data1 ;C2 - SBCB data1,X ;E2 - SBCB data1 ;D2 - SBCB data2 ;F2 - - SEI ;0F - SEV ;0B - SEC - - STS data1,X - STS data1 - STS data2 - - STAA data1,X ;A7 - STAA data1 ;97 - STAA data2 ;B7 - - STAB data1,X ;E7 - STAB data1 ;D7 - STAB data2 ;F7 - - STD data1,X ;ED - STD data1 ;DD - STD data2 ;FD - - STX data1,X ;EF - STX data1 ;FF - - SUBA #data1 ;80 - SUBA data1,X ;A0 - SUBA data1 ;90 - SUBA data2 ;B0 - - SUBB #data1 ;C0 - SUBB data1,X ;E0 - SUBB data1 ;D0 - SUBB data2 ;F0 - - SUBD #data1 ;83 - SUBD data1,X ;A3 - SUBD data1 ;93 - SUBD data2 ;B3 - - SWI ;3F - - TAB ;16 - TAP ;06 - TPA ;07 - TBA ;17 - - TST data1,X - TST data1 - TST data2 - - TSTA ;4D - TSTB ;5D - - TXS ;35 - TSX ;30 - - WAI ;3E - -; -; Test all the new 68HC11 instructions -; -bmsk .equ 12h -addr1 .equ 34h -addr2 .equ 5678h -imm .equ 55h - - ABY ;183A - ADCA addr1,Y ;18A9 - ADCB addr1,Y ;18E9 - ADDA addr1,Y ;18AB - ADDB addr1,Y ;18EB - ADDD addr1,Y ;18E3 - ANDA addr1,Y ;18A4 - ANDB addr1,Y ;18E4 - ASL addr1,Y ;1868 - ASR addr1,Y ;1867 -lab1 - BCLR addr1,Y,bmsk - BCLR addr1,X,bmsk - BCLR addr1,bmsk - - BITA addr1,Y ;18A5 - BITB addr1,Y ;18E5 - - BRCLR addr1,Y,bmsk,lab1 - BRCLR addr1,X,bmsk,lab1 - BRCLR addr1,bmsk,lab1 - BRCLR addr2,bmsk,lab1 - - BRSET addr1,Y,bmsk,lab1 - BRSET addr1,X,bmsk,lab1 - BRSET addr1,bmsk,lab1 - BRSET addr2,bmsk,lab1 - - BSET addr1,Y,bmsk - BSET addr1,X,bmsk - BSET addr1,bmsk - - CLR addr1,Y ;186F - CMPA addr1,Y ;18A1 - CMPB addr1,Y ;18E1 - COM addr1,Y ;1863 - CPD #imm ;1A83 - CPD addr1,X ;1AA3 - CPD addr1,Y ;CDA3 - CPD addr1 ;1AB3 - CPD addr2 ;1AB3 - CPX addr1,Y ;CDAC - CPY #imm ;188C - CPY addr1,Y ;18AC - CPY addr1,X ;1AAC - CPY addr1 ;18BC - CPY addr2 ;18BC - DEC addr1,Y ;186A - DEY ;1809 - EORA addr1,Y ;18A8 - EORB addr1,Y ;18E8 - FDIV ;03 - IDIV ;02 - INC addr1,Y ;186C - INY ;1808 - JMP addr1,Y ;186E - JSR addr1,Y ;18AD - LDAA addr1,Y ;18A6 - LDAB addr1,Y ;18E6 - LDD addr1,Y ;18EC - LDS addr1,Y ;18AE - LDX addr1,Y ;CDEE - LDY #imm ;18CE - LDY addr1,Y ;18EE - LDY addr1,X ;1AEE - LDY addr1 ;18FE - LDY addr2 ;18FE - LSL addr1,Y ;1868 - LSR addr1,Y ;1864 - NEG addr1,Y ;1860 - ORAA addr1,Y ;18AA - ORAB addr1,Y ;18EA - PSHY ;183C - PULY ;1838 - ROL addr1,Y ;1869 - ROR addr1,Y ;1866 - SBCA addr1,Y ;18A2 - SBCB addr1,Y ;18E2 - STAA addr1,Y ;18A7 - STAB addr1,Y ;18E7 - STD addr1,Y ;18ED - STS addr1,Y ;CDAF - STX addr1,Y ;CDEF - STY addr1,Y ;18EF - STY addr1,X ;1AEF - STY addr1 ;18FF - STY addr2 ;18FF - SUBA addr1,Y ;18A0 - SUBB addr1,Y ;18E0 - SUBD addr1,Y ;18A3 - TST addr1,Y ;186D -; TEST ; - TSY ;1830 2 NOP 4 - TYS ;1835 2 NOP 4 - XGDX ;8F 1 NOP 4 - XGDY ;188F 2 NOP 4 - - .end - - - - diff --git a/branches/s100/Tools/tasm32/TEST70.ASM b/branches/s100/Tools/tasm32/TEST70.ASM deleted file mode 100644 index 8c9afba5..00000000 --- a/branches/s100/Tools/tasm32/TEST70.ASM +++ /dev/null @@ -1,305 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test70.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: TMS7000 -; - - - -R0 .equ 0 -R1 .equ 1 -R2 .equ 2 -R3 .equ 3 -R12 .equ 12 -R13 .equ 13 -R7 .equ 7 -data1 .equ $34 -data2 .equ $1287 -table .equ $1234 -P7 .equ 7 - - .org $f000 -start: - ADC B,A - ADC %data1,A - ADC %data1,B - ADC %data1,R7 - ADC R12,A - ADC R13,B - ADC R12,R7 - - ADD B,A - ADD %data1,A - ADD %data1,B - ADD %data1,R7 - ADD R12,A - ADD R13,B - ADD R12,R7 - - AND B,A - AND %data1,A - AND %data1,B - AND %data1,R7 - AND R12,A - AND R13,B - AND R12,R7 - - ANDP A,R7 - ANDP B,R7 - ANDP %data1,R7 - - BTJO B,A,start - BTJO %data1,A,start - BTJO %data1,B,start - BTJO %data1,R7,start - BTJO R12,A,start - BTJO R13,B,start - BTJO R12,R7,start - -loop1 - BTJOP A,P7,loop1 - BTJOP B,P7,loop1 - BTJOP %data1,P7,loop1 - - BTJZ B,A,loop1 - BTJZ %data1,A,loop1 - BTJZ %data1,B,loop1 - BTJZ %data1,R7,loop1 - BTJZ R12,A,loop1 - BTJZ R12,B,loop1 - BTJZ R12,R7,loop1 - - BTJZP A,P7,loop1 - BTJZP B,P7,loop1 - BTJZP %data1,P7,loop1 - - BR @start(B) - BR @start[B] - BR @start - BR *R7 - - CALL @sub1(B) - CALL @sub1 - CALL *R7 - -sub1: CLR A - CLR B - CLR R12 - - CLRC - - CMP B,A - CMP %data1,A - CMP %data1,B - CMP %data1,R7 - CMP R12,A - CMP R12,B - CMP R12,R7 - - CMPA @R7(B) - CMPA @R7[B] - CMPA @R7 - CMPA *R7 - - DAC B,A - DAC %data1,A - DAC %data1,B - DAC %data1,R7 - DAC R12,A - DAC R12,B - DAC R12,R7 - - DEC A - DEC B - DEC R7 - - DECD A - DECD B - DECD R7 - - DINT - - DJNZ A,loop2 - DJNZ B,loop2 - DJNZ R12,loop2 - - DSB B,A - DSB %data1,A - DSB %data1,B - DSB %data1,R7 - DSB R12,A - DSB R12,B - DSB R12,R7 - - EINT - - IDLE - - INC A - INC B - INC R7 - - INV A - INV B - INV R7 -loop2: - JMP loop2 - - JC loop2 - JEQ loop2 - JGE loop2 - JGT loop2 - JHS loop2 - JL loop2 - JN loop2 - JNC loop2 - JNE loop2 - JNZ loop2 - JP loop2 - JPZ loop2 - JZ loop2 - - LDA @table(B) - LDA @table - LDA *R7 - - LDSP - - MOV A,B - MOV B,A - MOV A,R7 - MOV B,R7 - MOV %data1,A - MOV %data1,B - MOV %data1,R7 - MOV R12,A - MOV R12,B - MOV R12,R7 - - MOVD %data2,R7 - MOVD %data2[B],R7 - MOVD R12,R7 - - MOVP A,P7 - MOVP B,P7 - MOVP %data1,P7 - MOVP P7,A - MOVP P7,B - - MPY B,A - MPY %data1,A - MPY %data1,B - MPY %data1,R7 - MPY R12,A - MPY R12,B - MPY R12,R7 - - NOP - - OR B,A - OR %data1,A - OR %data1,B - OR %data1,R7 - OR R12,A - OR R12,B - OR R12,R7 - - ORP A,P7 - ORP B,P7 - ORP %data1,P7 - - POP A - POP B - POP R7 - - POPST - POP ST - - PUSH A - PUSH B - PUSH R7 - - PUSHST - PUSH ST - - RETI - - RETS - - RL A - RL B - RL R7 - - RLC A - RLC B - RLC R7 - - RR A - RR B - RR R7 - - RRC A - RRC B - RRC R7 - - SBB B,A - SBB %data1,A - SBB %data1,B - SBB %data1,R7 - SBB R12,A - SBB R12,B - SBB R12,R7 - - SETC - - STA @table(B) - STA @table - STA *R7 - - STSP - - SUB B,A - SUB %data1,A - SUB %data1,B - SUB %data1,R7 - SUB R12,A - SUB R12,B - SUB R12,R7 - - SWAP A - SWAP B - SWAP R7 - - TRAP 0 - TRAP 1 - TRAP 6 - TRAP 12 - TRAP 23 - - TST A - TSTA - TST B - TSTB - - XCHB A - XCHB R7 - - XOR B,A - XOR %data1,A - XOR %data1,B - XOR %data1,R7 - XOR R12,A - XOR R12,B - XOR R12,R7 - - XORP A,P7 - XORP B,P7 - XORP %data1,P7 - - - .end - diff --git a/branches/s100/Tools/tasm32/TEST85.ASM b/branches/s100/Tools/tasm32/TEST85.ASM deleted file mode 100644 index 7120d68e..00000000 --- a/branches/s100/Tools/tasm32/TEST85.ASM +++ /dev/null @@ -1,294 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test85.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8080/8085 -; - - - -idata16 .equ 1234h -idata8 .equ 12h -port .equ 34h -addr16 .equ 5678h - - .org 1000h - -start: - nop - lxi b,idata16 - stax b - inx b - inr b - dcr b - mvi b,idata8 - rlc - - dad b - ldax b - dcx b - inr c - dcr c - mvi c,idata8 - rrc - -; --- ; 10 - lxi d,idata16 - stax d - inx d - inr d - dcr d - mvi d,idata8 - ral -; --- - dad d - ldax d - dcx d - inr e - dcr e - mvi e,idata8 - rar - - rim ; 20 - lxi h,idata16 - shld addr16 - inx h - inr h - dcr h - mvi h,idata8 - daa -; --- - dad h - lhld addr16 - dcx h - inr l - dcr l - mvi l,idata8 - cma - - sim ; 30 - lxi sp,idata16 - sta addr16 - inx sp - inr m - dcr m - mvi m,idata8 - stc -; --- - dad sp - lda addr16 - dcx sp - inr a - dcr a - mvi a,idata8 - cmc - - mov b,b ; 40 - mov b,c - mov b,d - mov b,e - mov b,h - mov b,l - mov b,m - mov b,a - mov c,b - mov c,c - mov c,d - mov c,e - mov c,h - mov c,l - mov c,m - mov c,a - - mov d,b ; 50 - mov d,c - mov d,d - mov d,e - mov d,h - mov d,l - mov d,m - mov d,a - mov e,b - mov e,c - mov e,d - mov e,e - mov e,h - mov e,l - mov e,m - mov e,a - - mov h,b ; 60 - mov h,c - mov h,d - mov h,e - mov h,h - mov h,l - mov h,m - mov h,a - mov l,b - mov l,c - mov l,d - mov l,e - mov l,h - mov l,l - mov l,m - mov l,a - - mov m,b ; 70 - mov m,c - mov m,d - mov m,e - mov m,h - mov m,l - hlt - mov m,a - mov a,b - mov a,c - mov a,d - mov a,e - mov a,h - mov a,l - mov a,m - mov a,a - - add b ; 80 - add c - add d - add e - add h - add l - add m - add a - adc b ; 88 - adc c - adc d - adc e - adc h - adc l - adc m - adc a - - sub b ; 90 - sub c - sub d - sub e - sub h - sub l - sub m - sub a - sbb b ; 98 - sbb c - sbb d - sbb e - sbb h - sbb l - sbb m - sbb a - - ana b ; a0 - ana c - ana d - ana e - ana h - ana l - ana m - ana a - xra b ; a8 - xra c - xra d - xra e - xra h - xra l - xra m - xra a - - ora b ; b0 - ora c - ora d - ora e - ora h - ora l - ora m - ora a - cmp b ; b8 - cmp c - cmp d - cmp e - cmp h - cmp l - cmp m - cmp a - - rnz ; c0 - pop b - jnz start - jmp start - cnz start - push b - adi idata8 - rst 0 - rz - ret - jz start -; --- - cz start - call start - aci idata8 - rst 1 - - rnc ; d0 - pop d - jnc start - out port - cnc start - push d - sui idata8 - rst 2 - rc -; --- - jc start - in port - cc start -; --- - sbi idata8 - rst 3 - - rpo ; e0 - pop h - jpo start - xthl - cpo start - push h - ani idata8 - rst 4 - rpe - pchl - jpe start - xchg - cpe start -; --- - xri idata8 - rst 5 - - rp ; f0 - pop psw - jp start - di - cp start - push psw - ori idata8 - rst 6 - rm - sphl - jm start - ei - cm start -; --- - cpi idata8 - rst 7 - - .END - diff --git a/branches/s100/Tools/tasm32/TEST96.ASM b/branches/s100/Tools/tasm32/TEST96.ASM deleted file mode 100644 index 1ed5351a..00000000 --- a/branches/s100/Tools/tasm32/TEST96.ASM +++ /dev/null @@ -1,887 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test96.asm 1.1 1997/11/23 15:51:20 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8096/8XC196KC -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; - -; CPU "8096.TBL" ; CPU TABLE -; HOF "INT8" ; HEX FORMAT - -#define EQU .equ -#define END .end -#define ORG .org -#define DWL .dw -#define IF #if -#define ENDI #endif - -wreg: EQU 12h ; word register even address -wreg1: EQU 22h ; word register even address -wreg2: EQU 32h ; word register even address -wreg3: EQU 42h ; word register even address -lreg1: EQU 44h ; long register (32 bit) -lreg2: EQU 48h ; long register (32 bit) -breg: EQU wreg+1 ; low byte of reg. where odd is allowed -breg1: EQU wreg+3 ; low byte of reg. where odd is allowed -breg2: EQU wreg+5 ; low byte of reg. where odd is allowed -breg3: EQU wreg+7 ; low byte of reg. where odd is allowed - -imm8: EQU 88H -imm16: EQU 4321H - -addr8: EQU 12H -addr16: EQU 3456H - -ishort: EQU 12H -ishrt: EQU 12H -ilong: EQU 4567H - -count: EQU 7H - - ORG 7418h - -dtable: DWL $1234 - DWL $5678 - DWL $1234 - - -;------------------------------------- -; ADD - add wreg1,#imm8 - add wreg1,#imm16 - add wreg1,wreg2 - add wreg1,addr16 - add wreg1,[wreg2] - add wreg1,[wreg2]+ - add wreg1,addr8[wreg2] - add wreg1,addr16[wreg2] - - add wreg1,wreg2,#imm8 - add wreg1,wreg2,#imm16 - add wreg1,wreg2,wreg3 - add wreg1,wreg2,addr16 - add wreg1,wreg2,[wreg3] - add wreg1,wreg2,[wreg3]+ - add wreg1,wreg2,addr8[wreg3] - add wreg1,wreg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; ADDB - addb breg1,#imm8 - addb breg1,breg2 - addb breg1,addr16 - addb breg1,[wreg2] - addb breg1,[wreg2]+ - addb breg1,addr8[wreg2] - addb breg1,addr16[wreg2] - - addb breg1,breg2,#imm8 - addb breg1,breg2,breg3 - addb breg1,breg2,addr16 - addb breg1,breg2,[wreg3] - addb breg1,breg2,[wreg3]+ - addb breg1,breg2,addr8[wreg3] - addb breg1,breg2,addr16[wreg3] -;------------------------------------- - - -;------------------------------------- -; ADDB - addc wreg1,#imm8 - addc wreg1,#imm16 - addc wreg1,wreg2 - addc wreg1,addr16 - addc wreg1,[wreg2] - addc wreg1,[wreg2]+ - addc wreg1,addr8[wreg2] - addc wreg1,addr16[wreg2] - - ; No three arg form for addc -;------------------------------------- - -;------------------------------------- -; ADDCB - addcb breg1,#imm8 - addcb breg1,breg2 - addcb breg1,addr16 - addcb breg1,[wreg2] - addcb breg1,[wreg2]+ - addcb breg1,addr8[wreg2] - addcb breg1,addr16[wreg2] - - ; No three arg form for addcb -;------------------------------------- - -;------------------------------------- -; AND - and wreg1,#imm8 - and wreg1,#imm16 - and wreg1,wreg2 - and wreg1,addr16 - and wreg1,[wreg2] - and wreg1,[wreg2]+ - and wreg1,addr8[wreg2] - and wreg1,addr16[wreg2] - - and wreg1,wreg2,#imm8 - and wreg1,wreg2,#imm16 - and wreg1,wreg2,wreg3 - and wreg1,wreg2,addr16 - and wreg1,wreg2,[wreg3] - and wreg1,wreg2,[wreg3]+ - and wreg1,wreg2,addr8[wreg3] - and wreg1,wreg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; ANDB - andb breg1,#imm8 - andb breg1,breg2 - andb breg1,addr16 - andb breg1,[wreg2] - andb breg1,[wreg2]+ - andb breg1,addr8[wreg2] - andb breg1,addr16[wreg2] - - andb breg1,breg2,#imm8 - andb breg1,breg2,breg3 - andb breg1,breg2,addr16 - andb breg1,breg2,[wreg3] - andb breg1,breg2,[wreg3]+ - andb breg1,breg2,addr8[wreg3] - andb breg1,breg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; BMOV - bmov lreg1,wreg1 - bmov lreg1,wreg2 -;------------------------------------- - -;------------------------------------- -; BR - br [wreg1] -;------------------------------------- - -;------------------------------------- -; MISC CLR - clr wreg1 - clrb breg1 - clrc - clrvt -;------------------------------------- - - - -;------------------------------------- -; CMP - cmp wreg1,#imm8 - cmp wreg1,#imm16 - cmp wreg1,wreg2 - cmp wreg1,addr16 - cmp wreg1,[wreg2] - cmp wreg1,[wreg2]+ - cmp wreg1,addr8[wreg2] - cmp wreg1,addr16[wreg2] - - ; No three arg form for cmp -;------------------------------------- - -;------------------------------------- -; CMPB - cmpb breg1,#imm8 - cmpb breg1,breg2 - cmpb breg1,addr16 - cmpb breg1,[wreg2] - cmpb breg1,[wreg2]+ - cmpb breg1,addr8[wreg2] - cmpb breg1,addr16[wreg2] - - ; No three arg form for cmpb -;------------------------------------- - -;------------------------------------- -; CMPL - cmpl lreg1,lreg2 -;------------------------------------- - -;------------------------------------- -; DEC - dec wreg1 - decb breg1 -;------------------------------------- - -;------------------------------------- -; DEC - di -;------------------------------------- - - -;------------------------------------- -; DIV - div lreg1,#imm8 - div lreg1,#imm16 - div lreg1,wreg2 - div lreg1,addr16 - div lreg1,[wreg2] - div lreg1,[wreg2]+ - div lreg1,addr8[wreg2] - div lreg1,addr16[wreg2] - - ; No three arg form for div -;------------------------------------- - -;------------------------------------- -; DIVB - divb wreg1,#imm8 - divb wreg1,breg2 - divb wreg1,addr16 - divb wreg1,[wreg2] - divb wreg1,[wreg2]+ - divb wreg1,addr8[wreg2] - divb wreg1,addr16[wreg2] - - ; No three arg form for divb -;------------------------------------- - - -;------------------------------------- -; DIVU - divu lreg1,#imm8 - divu lreg1,#imm16 - divu lreg1,wreg2 - divu lreg1,addr16 - divu lreg1,[wreg2] - divu lreg1,[wreg2]+ - divu lreg1,addr8[wreg2] - divu lreg1,addr16[wreg2] - - ; No three arg form for divu -;------------------------------------- - -;------------------------------------- -; DIVUB - divub wreg1,#imm8 - divub wreg1,breg2 - divub wreg1,addr16 - divub wreg1,[wreg2] - divub wreg1,[wreg2]+ - divub wreg1,addr8[wreg2] - divub wreg1,addr16[wreg2] - - ; No three arg form for divub -;------------------------------------- - - -;------------------------------------- -; DJNZ -rtest1: ;backward reference - djnz breg1,rtest1 - djnz breg1,rtest1 - djnz breg1,rtest2 - djnz breg1,rtest2 -rtest2: ;forward reference -;------------------------------------- - -;------------------------------------- -; DJNZW - djnzw wreg1,rtest1 - djnzw wreg1,rtest1 - djnzw wreg1,rtest3 - djnzw wreg1,rtest3 -rtest3: ;forward reference -;------------------------------------- - -;------------------------------------- -; DPTS - dpts -;------------------------------------- - -;------------------------------------- -; EI - ei -;------------------------------------- - -;------------------------------------- -; EPTS - epts -;------------------------------------- - -;------------------------------------- -; EXT & EXTB - ext lreg1 - ext lreg2 - extb wreg1 - extb wreg2 -;------------------------------------- - -;------------------------------------- -; IDLPD - idlpd #1 - idlpd #2 -;------------------------------------- - -;------------------------------------- -; INC & INCB - inc wreg1 - inc wreg2 - incb breg1 - incb breg2 -;------------------------------------- - - -FLAG: EQU 3 -;------------------------------------- -; JBC - jbc breg1,0,rtest1 - jbc breg1,1,rtest1 - jbc breg1,2,rtest1 - jbc breg1,3,rtest1 - jbc breg1,4,rtest1 - jbc breg1,5,rtest1 - jbc breg1,6,rtest1 - jbc breg1,7,rtest1 -;------------------------------------- - -;------------------------------------- -; JBS - jbs breg1,0,rtest1 - jbs breg1,1,rtest1 - jbs breg1,2,rtest1 - jbs breg1,3,rtest1 - jbs breg1,4,rtest1 - jbs breg1,5,rtest1 - jbs breg1,6,rtest1 - jbs breg1,7,rtest1 -;------------------------------------- - -;------------------------------------- -; MISC Jump backward - jc rtest1 - je rtest1 - jge rtest1 - jgt rtest1 - jh rtest1 - jle rtest1 - jlt rtest1 - jnc rtest1 - jne rtest1 - jnh rtest1 - jnst rtest1 - jnv rtest1 - jnvt rtest1 - jst rtest1 - jv rtest1 - jvt rtest1 -;------------------------------------- - -;------------------------------------- -; MISC Jump forward - jc rtest4 - je rtest4 - jge rtest4 - jgt rtest4 - jh rtest4 - jle rtest4 - jlt rtest4 - jnc rtest4 - jne rtest4 - jnh rtest4 - jnst rtest4 - jnv rtest4 - jnvt rtest4 - jst rtest4 - jv rtest4 -rtest4: jvt rtest4 -;------------------------------------- - -;------------------------------------- -; LCALL - lcall rtest1 - lcall rtest2 - lcall rtest4 - lcall addr8 - lcall addr16 -;------------------------------------- - - -;------------------------------------- -; LD - ld wreg1,#imm8 - ld wreg1,#imm16 - ld wreg1,wreg2 - ld wreg1,addr16 - ld wreg1,[wreg2] - ld wreg1,[wreg2]+ - ld wreg1,addr8[wreg2] - ld wreg1,addr16[wreg2] - - ; No three arg form for ld -;------------------------------------- - -;------------------------------------- -; LDB - ldb breg1,#imm8 - ldb breg1,breg2 - ldb breg1,addr16 - ldb breg1,[wreg2] - ldb breg1,[wreg2]+ - ldb breg1,addr8[wreg2] - ldb breg1,addr16[wreg2] - - ; No three arg form for ldb -;------------------------------------- - -;------------------------------------- -; LDBSE - ldbse wreg1,#imm8 - ldbse wreg1,breg2 - ldbse wreg1,addr16 - ldbse wreg1,[wreg2] - ldbse wreg1,[wreg2]+ - ldbse wreg1,addr8[wreg2] - ldbse wreg1,addr16[wreg2] - - ; No three arg form for ldbse -;------------------------------------- - -;------------------------------------- -; LDBZE - ldbze wreg1,#imm8 - ldbze wreg1,breg2 - ldbze wreg1,addr16 - ldbze wreg1,[wreg2] - ldbze wreg1,[wreg2]+ - ldbze wreg1,addr8[wreg2] - ldbze wreg1,addr16[wreg2] - - ; No three arg form for ldbze -;------------------------------------- - -;------------------------------------- -; LJMP - ljmp addr8 - ljmp addr16 -;------------------------------------- - - -;------------------------------------- -; MUL - mul lreg1,#imm8 - mul lreg1,#imm16 - mul lreg1,wreg2 - mul lreg1,addr16 - mul lreg1,[wreg2] - mul lreg1,[wreg2]+ - mul lreg1,addr8[wreg2] - mul lreg1,addr16[wreg2] - - mul lreg1,wreg2,#imm8 - mul lreg1,wreg2,#imm16 - mul lreg1,wreg2,wreg3 - mul lreg1,wreg2,addr16 - mul lreg1,wreg2,[wreg3] - mul lreg1,wreg2,[wreg3]+ - mul lreg1,wreg2,addr8[wreg3] - mul lreg1,wreg2,addr16[wreg3] - -;------------------------------------- - - -;------------------------------------- -; MULB - mulb wreg1,#imm8 - mulb wreg1,breg2 - mulb wreg1,addr16 - mulb wreg1,[wreg2] - mulb wreg1,[wreg2]+ - mulb wreg1,addr8[wreg2] - mulb wreg1,addr16[wreg2] - - mulb wreg1,breg2,#imm8 - mulb wreg1,breg2,breg3 - mulb wreg1,breg2,addr16 - mulb wreg1,breg2,[wreg3] - mulb wreg1,breg2,[wreg3]+ - mulb wreg1,breg2,addr8[wreg3] - mulb wreg1,breg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; MULU - mulu lreg1,#imm8 - mulu lreg1,#imm16 - mulu lreg1,wreg2 - mulu lreg1,addr16 - mulu lreg1,[wreg2] - mulu lreg1,[wreg2]+ - mulu lreg1,addr8[wreg2] - mulu lreg1,addr16[wreg2] - - mulu lreg1,wreg2,#imm8 - mulu lreg1,wreg2,#imm16 - mulu lreg1,wreg2,wreg3 - mulu lreg1,wreg2,addr16 - mulu lreg1,wreg2,[wreg3] - mulu lreg1,wreg2,[wreg3]+ - mulu lreg1,wreg2,addr8[wreg3] - mulu lreg1,wreg2,addr16[wreg3] - -;------------------------------------- - - -;------------------------------------- -; MULUB - mulub wreg1,#imm8 - mulub wreg1,breg2 - mulub wreg1,addr16 - mulub wreg1,[wreg2] - mulub wreg1,[wreg2]+ - mulub wreg1,addr8[wreg2] - mulub wreg1,addr16[wreg2] - - mulub wreg1,breg2,#imm8 - mulub wreg1,breg2,breg3 - mulub wreg1,breg2,addr16 - mulub wreg1,breg2,[wreg3] - mulub wreg1,breg2,[wreg3]+ - mulub wreg1,breg2,addr8[wreg3] - mulub wreg1,breg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; NEG & NEGB - neg wreg1 - negb breg1 -;------------------------------------- - -;------------------------------------- -; NOP - nop -;------------------------------------- - -;------------------------------------- -; NORML - norml lreg1,breg1 -;------------------------------------- - -;------------------------------------- -; NOT & NOTB - not wreg1 - notb breg1 -;------------------------------------- - - -;------------------------------------- -; OR - or wreg1,#imm8 - or wreg1,#imm16 - or wreg1,wreg2 - or wreg1,addr16 - or wreg1,[wreg2] - or wreg1,[wreg2]+ - or wreg1,addr8[wreg2] - or wreg1,addr16[wreg2] - - ; No three arg form for or -;------------------------------------- - -;------------------------------------- -; ORB - orb breg1,#imm8 - orb breg1,breg2 - orb breg1,addr16 - orb breg1,[wreg2] - orb breg1,[wreg2]+ - orb breg1,addr8[wreg2] - orb breg1,addr16[wreg2] - - ; No three arg form for orb -;------------------------------------- - - -;------------------------------------- -; POP - pop wreg1 - pop [wreg1] - pop [wreg1]+ - pop addr8[wreg1] - pop addr16[wreg1] - - popa - popf -;------------------------------------- - -;------------------------------------- -; PUSH - push wreg1 - push [wreg1] - push [wreg1]+ - push addr8[wreg1] - push addr16[wreg1] - - pusha - pushf -;------------------------------------- - - -;------------------------------------- -; RET - return - ret -;------------------------------------- - -;------------------------------------- -; RST - reset - rst -;------------------------------------- - -;------------------------------------- -; SCALL - short call -scall1: -scall2: EQU scall1-1015 - scall scall1 - scall scall1 - scall scall2 - scall scall2 - scall scall3 - scall scall4 -scall3: -scall4: EQU scall3+1020 -;------------------------------------- - -;------------------------------------- -; SETC - set carry - setc -;------------------------------------- - -;------------------------------------- -; shl - shift word left - shl wreg1,#count - shl wreg2,breg1 -;------------------------------------- - -;------------------------------------- -; shlb - shift byte left - shlb breg1,#count - shlb breg2,breg1 -;------------------------------------- - -;------------------------------------- -; shll - shift long word left - shll lreg1,#count - shll lreg1,breg1 -;------------------------------------- - -;------------------------------------- -; shr - logical shift word right - shr wreg1,#count - shr wreg2,breg1 -;------------------------------------- - -;------------------------------------- -; shra - arithmetic shift word right - shra wreg1,#count - shra wreg2,breg1 -;------------------------------------- - -;------------------------------------- -; shrab - arithmetic shift byte right - shrab breg1,#count - shrab breg2,breg1 -;------------------------------------- - -;------------------------------------- -; shral - arithmetic shift long word right - shral lreg1,#count - shral lreg1,breg1 -;------------------------------------- - -;------------------------------------- -; shrb - logical shift byte right - shrb breg1,#count - shrb breg2,breg1 -;------------------------------------- - -;------------------------------------- -; shrl - logical shift long word right - shrl lreg1,#count - shrl lreg1,breg1 -;------------------------------------- - - -;------------------------------------- -; SJMP - short jump -sjump1: -sjump2: EQU sjump1-1015 - sjmp sjump1 - sjmp sjump1 - sjmp sjump2 - sjmp sjump2 - sjmp sjump3 - sjmp sjump4 -sjump3: -sjump4: EQU sjump3+1020 -;------------------------------------- - -;------------------------------------- -; skip - two byte nop - skip breg1 -;------------------------------------- - - -;------------------------------------- -; ST - store word - st wreg1,wreg2 - st wreg1,addr16 - st wreg1,[wreg2] - st wreg1,[wreg2]+ - st wreg1,addr8[wreg2] - st wreg1,addr16[wreg2] - - ; No three arg form for st; No immediate -;------------------------------------- - -;------------------------------------- -; STB - store byte - stb breg1,breg2 - stb breg1,addr16 - stb breg1,[wreg2] - stb breg1,[wreg2]+ - stb breg1,addr8[wreg2] - stb breg1,addr16[wreg2] - - ; No three arg form for stb; No immediate -;------------------------------------- - - -;------------------------------------- -; SUB - subtract word - sub wreg1,#imm8 - sub wreg1,#imm16 - sub wreg1,wreg2 - sub wreg1,addr16 - sub wreg1,[wreg2] - sub wreg1,[wreg2]+ - sub wreg1,addr8[wreg2] - sub wreg1,addr16[wreg2] - - sub wreg1,wreg2,#imm8 - sub wreg1,wreg2,#imm16 - sub wreg1,wreg2,wreg3 - sub wreg1,wreg2,addr16 - sub wreg1,wreg2,[wreg3] - sub wreg1,wreg2,[wreg3]+ - sub wreg1,wreg2,addr8[wreg3] - sub wreg1,wreg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; SUBB - subtract byte - subb breg1,#imm8 - subb breg1,breg2 - subb breg1,addr16 - subb breg1,[wreg2] - subb breg1,[wreg2]+ - subb breg1,addr8[wreg2] - subb breg1,addr16[wreg2] - - subb breg1,breg2,#imm8 - subb breg1,breg2,breg3 - subb breg1,breg2,addr16 - subb breg1,breg2,[wreg3] - subb breg1,breg2,[wreg3]+ - subb breg1,breg2,addr8[wreg3] - subb breg1,breg2,addr16[wreg3] -;------------------------------------- - - -;------------------------------------- -; SUBC - subtract word with carry - subc wreg1,#imm8 - subc wreg1,#imm16 - subc wreg1,wreg2 - subc wreg1,addr16 - subc wreg1,[wreg2] - subc wreg1,[wreg2]+ - subc wreg1,addr8[wreg2] - subc wreg1,addr16[wreg2] - - ; No three arg form for subc -;------------------------------------- - -;------------------------------------- -; SUBCB - subtract byte with carry - subcb breg1,#imm8 - subcb breg1,breg2 - subcb breg1,addr16 - subcb breg1,[wreg2] - subcb breg1,[wreg2]+ - subcb breg1,addr8[wreg2] - subcb breg1,addr16[wreg2] - - ; No three arg form for subcb -;------------------------------------- - - -;------------------------------------- -; tijmp - table indirect jump - tijmp wreg1,[wreg2],#imm8 - tijmp wreg2,[wreg1],#imm8 - tijmp wreg3,[wreg2],#13 -;------------------------------------- - -;------------------------------------- -; TRAP - software trap - trap -;------------------------------------- - -;------------------------------------- -; XCH - exchange word - xch wreg1,wreg2 - xch wreg1,addr16 - xch wreg1,addr8[wreg2] - xch wreg1,addr16[wreg2] -;------------------------------------- - -;------------------------------------- -; XCHB - exchange byte - xchb breg1,breg2 - xchb breg1,addr16 - xchb breg1,addr8[wreg2] - xchb breg1,addr16[wreg2] -;------------------------------------- - - -;------------------------------------- -; XOR - xor wreg1,#imm8 - xor wreg1,#imm16 - xor wreg1,wreg2 - xor wreg1,addr16 - xor wreg1,[wreg2] - xor wreg1,[wreg2]+ - xor wreg1,addr8[wreg2] - xor wreg1,addr16[wreg2] - - ; No three arg form for xor -;------------------------------------- - -;------------------------------------- -; XORB - xorb breg1,#imm8 - xorb breg1,breg2 - xorb breg1,addr16 - xorb breg1,[wreg2] - xorb breg1,[wreg2]+ - xorb breg1,addr8[wreg2] - xorb breg1,addr16[wreg2] - - ; No three arg form for xorb -;------------------------------------- - - END diff --git a/branches/s100/Tools/tasm32/TESTTABS.BAT b/branches/s100/Tools/tasm32/TESTTABS.BAT deleted file mode 100644 index 36bbba4c..00000000 --- a/branches/s100/Tools/tasm32/TESTTABS.BAT +++ /dev/null @@ -1,18 +0,0 @@ -rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -rem $Id: testtabs.bat 1.3 1998/02/25 12:27:04 toma Exp $ -rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -rem Run TASM on all the table test files. Those that have -rem extended instuctions use the -x option. - -tasm -48 -x test48.asm -tasm -65 -x test65.asm -tasm -51 test51.asm -tasm -85 test85.asm -tasm -80 -x testz80.asm -tasm -05 -x test05.asm -tasm -3210 test3210.asm -tasm -3225 test3225.asm -tasm -68 -x test68.asm -tasm -70 test70.asm -tasm -96 -x test96.asm - diff --git a/branches/s100/Tools/tasm32/TESTZ80.ASM b/branches/s100/Tools/tasm32/TESTZ80.ASM deleted file mode 100644 index 4f4eb843..00000000 --- a/branches/s100/Tools/tasm32/TESTZ80.ASM +++ /dev/null @@ -1,831 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: testz80.asm 1.4 1998/02/25 12:18:20 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: Z80 -; -; SEPT. 16,1987 -; CARL A. WALL -; VE3APY -; -; - -#define equ .equ -#define end .end - -n: equ 20h -nn: equ 0584h -dddd: equ 07h -addr16: equ $1234 -port: equ 3 -imm8: equ 56h ;immediate data (8 bits) -offset: equ 7 -offset_neg: equ -7 - -; try a few cases that have two expressions in the args and -; one is inside (). - LD (IX+offset),n+1+4+8-9 - LD (IX+offset+5),n-1 - LD (IX+dddd),n - LD (IX+offset),n - LD (IX+offset),n - -; Try all possible instructions - - ADC A,(HL) - ADC A,(IX+offset) - ADC A,(IX+offset_neg) - ADC A,(IY+offset) - ADC A,(IY+offset_neg) - ADC A,A - ADC A,B - ADC A,C - ADC A,D - ADC A,E - ADC A,H - ADC A,L - ADC A,n - ADC HL,BC - ADC HL,DE - ADC HL,HL - ADC HL,SP - - ADD A,(HL) - ADD A,(IX+offset) - ADD A,(IY+offset) - ADD A,A - ADD A,B - ADD A,C - ADD A,D - ADD A,E - ADD A,H - ADD A,L - ADD A,n - ADD HL,BC - ADD HL,DE - ADD HL,HL - ADD HL,SP - ADD IX,BC - ADD IX,DE - ADD IX,IX - ADD IX,SP - ADD IY,BC - ADD IY,DE - ADD IY,IY - ADD IY,SP - - AND (HL) - AND (IX+offset) - AND (IY+offset) - AND A - AND B - AND C - AND D - AND E - AND H - AND L - AND n - - BIT 0,(HL) - BIT 0,(IX+offset) - BIT 0,(IY+offset) - BIT 0,A - BIT 0,B - BIT 0,C - BIT 0,D - BIT 0,E - BIT 0,H - BIT 0,L - - BIT 1,(HL) - BIT 1,(IX+offset) - BIT 1,(IY+offset) - BIT 1,A - BIT 1,B - BIT 1,C - BIT 1,D - BIT 1,E - BIT 1,H - BIT 1,L - - BIT 2,(HL) - BIT 2,(IX+offset) - BIT 2,(IY+offset) - BIT 2,A - BIT 2,B - BIT 2,C - BIT 2,D - BIT 2,E - BIT 2,H - BIT 2,L - - BIT 3,(HL) - BIT 3,(IX+offset) - BIT 3,(IY+offset) - BIT 3,A - BIT 3,B - BIT 3,C - BIT 3,D - BIT 3,E - BIT 3,H - BIT 3,L - - BIT 4,(HL) - BIT 4,(IX+offset) - BIT 4,(IY+offset) - BIT 4,A - BIT 4,B - BIT 4,C - BIT 4,D - BIT 4,E - BIT 4,H - BIT 4,L - - BIT 5,(HL) - BIT 5,(IX+offset) - BIT 5,(IY+offset) - BIT 5,A - BIT 5,B - BIT 5,C - BIT 5,D - BIT 5,E - BIT 5,H - BIT 5,L - - BIT 6,(HL) - BIT 6,(IX+offset) - BIT 6,(IY+offset) - BIT 6,A - BIT 6,B - BIT 6,C - BIT 6,D - BIT 6,E - BIT 6,H - BIT 6,L - - BIT 7,(HL) - BIT 7,(IX+offset) - BIT 7,(IY+offset) - BIT 7,A - BIT 7,B - BIT 7,C - BIT 7,D - BIT 7,E - BIT 7,H - BIT 7,L - - CALL C,addr16 - CALL M,addr16 - CALL NC,addr16 - CALL NZ,addr16 - CALL P,addr16 - CALL PE,addr16 - CALL PO,addr16 - CALL Z,addr16 - CALL addr16 - - CCF - - CP (HL) - CP (IX+offset) - CP (IY+offset) - CP A - CP B - CP C - CP D - CP E - CP H - CP L - CP imm8 - CPD - CPDR - CPIR - CPI - CPL - - DAA - - DEC (HL) - DEC (IX+offset) - DEC (IY+offset) - DEC A - DEC B - DEC BC - DEC C - DEC D - DEC DE - DEC E - DEC H - DEC HL - DEC IX - DEC IY - DEC L - DEC SP - DI -loop1: - DJNZ loop1 - - EI - EX (SP),HL - EX (SP),IX - EX (SP),IY - EX AF,AF' - EX DE,HL - EXX - HALT - - IM 0 - IM 1 - IM 2 - - IN A,(C) - IN B,(C) - IN C,(C) - IN D,(C) - IN E,(C) - IN H,(C) - IN L,(C) - IN A,(port) - - IN0 B,(n) - IN0 C,(n) - IN0 D,(n) - IN0 E,(n) - IN0 H,(n) - IN0 L,(n) - - INC (HL) - INC (IX+offset) - INC (IY+offset) - INC A - INC B - INC BC - INC C - INC D - INC DE - INC E - INC H - INC HL - INC IX - INC IY - INC L - INC SP - - IND - INDR - INI - INIR - - JP addr16 - JP (HL) - JP (IX) - JP (IY) - JP C,addr16 - JP M,addr16 - JP NC,addr16 - JP NZ,addr16 - JP P,addr16 - JP PE,addr16 - JP PO,addr16 - JP Z,addr16 - -loop2: - JR C,loop2 - JR NC,loop2 - JR NZ,loop2 - JR Z,loop2 - JR loop2 - - LD (BC),A - LD (DE),A - LD (HL),A - LD (HL),B - LD (HL),C - LD (HL),D - LD (HL),E - LD (HL),H - LD (HL),L - LD (HL),n - LD (IX+offset),A - LD (IX+offset),B - LD (IX+offset),C - LD (IX+offset),D - LD (IX+offset),E - LD (IX+offset),H - LD (IX+offset),L - LD (IX+offset),n - LD (IY+offset),A - LD (IY+offset),B - LD (IY+offset),C - LD (IY+offset),D - LD (IY+offset),E - LD (IY+offset),H - LD (IY+offset),L - LD (IY+offset),n - LD (nn),A - LD (nn),BC - LD (nn),DE - LD (nn),HL - LD (nn),IX - LD (nn),IY - LD (nn),SP - LD A,(BC) - LD A,(DE) - LD A,(HL) - LD A,(IX+offset) - LD A,(IY+offset) - LD A,(nn) - LD A,A - LD A,B - LD A,C - LD A,D - LD A,E - LD A,H - LD A,I - LD A,L - LD A,n - LD A,R - LD B,(HL) - LD B,(IX+offset) - LD B,(IY+offset) - LD B,A - LD B,B - LD B,C - LD B,D - LD B,E - LD B,H - LD B,L - LD B,n - LD BC,(nn) - LD BC,nn - LD C,(HL) - LD C,(IX+offset) - LD C,(IY+offset) - LD C,A - LD C,B - LD C,C - LD C,D - LD C,E - LD C,H - LD C,L - LD C,n - LD D,(HL) - LD D,(IX+offset) - LD D,(IY+offset) - LD D,A - LD D,B - LD D,C - LD D,D - LD D,E - LD D,H - LD D,L - LD D,n - LD DE,(nn) - LD DE,nn - LD E,(HL) - LD E,(IX+offset) - LD E,(IY+offset) - LD E,A - LD E,B - LD E,C - LD E,D - LD E,E - LD E,H - LD E,L - LD E,n - LD H,(HL) - LD H,(IX+offset) - LD H,(IY+offset) - LD H,A - LD H,B - LD H,C - LD H,D - LD H,E - LD H,H - LD H,L - LD H,n - LD HL,(nn) - LD HL,nn - LD I,A - LD IX,(nn) - LD IX,nn - LD IY,(nn) - LD IY,nn - LD L,(HL) - LD L,(IX+offset) - LD L,(IY+offset) - LD L,A - LD L,B - LD L,C - LD L,D - LD L,E - LD L,H - LD L,L - LD L,n - LD R,A - LD SP,(nn) - LD SP,HL - LD SP,IX - LD SP,IY - LD SP,nn - - LDD - LDDR - LDI - LDIR - - MLT BC - MLT DE - MLT HL - MLT SP - - NEG - NOP - - OR (HL) - OR (IX+offset) - OR (IY+offset) - OR A - OR B - OR C - OR D - OR E - OR H - OR L - OR imm8 - - OTDR - OTIR - - OUT (C),A - OUT (C),B - OUT (C),C - OUT (C),D - OUT (C),E - OUT (C),H - OUT (C),L - OUT (port),A - - OUT0 (imm8),A - OUT0 (imm8),B - OUT0 (imm8),C - OUT0 (imm8),D - OUT0 (imm8),E - OUT0 (imm8),H - OUT0 (imm8),L - - OUTD - OUTI - OTIM - OTDM - OTIMR - OTDMR - - POP AF - POP BC - POP DE - POP HL - POP IX - POP IY - - PUSH AF - PUSH BC - PUSH DE - PUSH HL - PUSH IX - PUSH IY - - RES 0,(HL) - RES 0,(IX+offset) - RES 0,(IY+offset) - RES 0,A - RES 0,B - RES 0,C - RES 0,D - RES 0,E - RES 0,H - RES 0,L - - RES 1,(HL) - RES 1,(IX+offset) - RES 1,(IY+offset) - RES 1,A - RES 1,B - RES 1,C - RES 1,D - RES 1,E - RES 1,H - RES 1,L - - RES 2,(HL) - RES 2,(IX+offset) - RES 2,(IY+offset) - RES 2,A - RES 2,B - RES 2,C - RES 2,D - RES 2,E - RES 2,H - RES 2,L - - RES 3,(HL) - RES 3,(IX+offset) - RES 3,(IY+offset) - RES 3,A - RES 3,B - RES 3,C - RES 3,D - RES 3,E - RES 3,H - RES 3,L - - RES 4,(HL) - RES 4,(IX+offset) - RES 4,(IY+offset) - RES 4,A - RES 4,B - RES 4,C - RES 4,D - RES 4,E - RES 4,H - RES 4,L - - RES 5,(HL) - RES 5,(IX+offset) - RES 5,(IY+offset) - RES 5,A - RES 5,B - RES 5,C - RES 5,D - RES 5,E - RES 5,H - RES 5,L - - RES 6,(HL) - RES 6,(IX+offset) - RES 6,(IY+offset) - RES 6,A - RES 6,B - RES 6,C - RES 6,D - RES 6,E - RES 6,H - RES 6,L - - RES 7,(HL) - RES 7,(IX+offset) - RES 7,(IY+offset) - RES 7,A - RES 7,B - RES 7,C - RES 7,D - RES 7,E - RES 7,H - RES 7,L - - RET - RET C - RET M - RET NC - RET NZ - RET P - RET PE - RET PO - RET Z - RETI - RETN - - RL (HL) - RL (IX+offset) - RL (IY+offset) - RL A - RL B - RL C - RL D - RL E - RL H - RL L - RLA - - RLC (HL) - RLC (IX+offset) - RLC (IY+offset) - RLC A - RLC B - RLC C - RLC D - RLC E - RLC H - RLC L - RLCA - RLD - - RR (HL) - RR (IX+offset) - RR (IY+offset) - RR A - RR B - RR C - RR D - RR E - RR H - RR L - RRA - - RRC (HL) - RRC (IX+offset) - RRC (IY+offset) - RRC A - RRC B - RRC C - RRC D - RRC E - RRC H - RRC L - RRCA - RRD - - RST 00H - RST 08H - RST 10H - RST 18H - RST 20H - RST 28H - RST 30H - RST 38H - - SBC A,n - SBC A,(HL) - SBC A,(IX+offset) - SBC A,(IY+offset) - SBC A,A - SBC A,B - SBC A,C - SBC A,D - SBC A,E - SBC A,H - SBC A,L - SBC HL,BC - SBC HL,DE - SBC HL,HL - SBC HL,SP - SCF - - SET 0,(HL) - SET 0,(IX+offset) - SET 0,(IY+offset) - SET 0,A - SET 0,B - SET 0,C - SET 0,D - SET 0,E - SET 0,H - SET 0,L - - SET 1,(HL) - SET 1,(IX+offset) - SET 1,(IY+offset) - SET 1,A - SET 1,B - SET 1,C - SET 1,D - SET 1,E - SET 1,H - SET 1,L - - SET 2,(HL) - SET 2,(IX+offset) - SET 2,(IY+offset) - SET 2,A - SET 2,B - SET 2,C - SET 2,D - SET 2,E - SET 2,H - SET 2,L - - SET 3,(HL) - SET 3,(IX+offset) - SET 3,(IY+offset) - SET 3,A - SET 3,B - SET 3,C - SET 3,D - SET 3,E - SET 3,H - SET 3,L - - SET 4,(HL) - SET 4,(IX+offset) - SET 4,(IY+offset) - SET 4,A - SET 4,B - SET 4,C - SET 4,D - SET 4,E - SET 4,H - SET 4,L - - SET 5,(HL) - SET 5,(IX+offset) - SET 5,(IY+offset) - SET 5,A - SET 5,B - SET 5,C - SET 5,D - SET 5,E - SET 5,H - SET 5,L - - SET 6,(HL) - SET 6,(IX+offset) - SET 6,(IY+offset) - SET 6,A - SET 6,B - SET 6,C - SET 6,D - SET 6,E - SET 6,H - SET 6,L - - SET 7,(HL) - SET 7,(IX+offset) - SET 7,(IY+offset) - SET 7,A - SET 7,B - SET 7,C - SET 7,D - SET 7,E - SET 7,H - SET 7,L - - SLA (HL) - SLA (IX+offset) - SLA (IY+offset) - SLA A - SLA B - SLA C - SLA D - SLA E - SLA H - SLA L - - SLP - - SRA (HL) - SRA (IX+offset) - SRA (IY+offset) - SRA A - SRA B - SRA C - SRA D - SRA E - SRA H - SRA L - - SRL (HL) - SRL (IX+offset) - SRL (IY+offset) - SRL A - SRL B - SRL C - SRL D - SRL E - SRL H - SRL L - - SUB (HL) - SUB (IX+offset) - SUB (IY+offset) - SUB A - SUB B - SUB C - SUB D - SUB E - SUB H - SUB L - SUB n - - TST A - TST B - TST C - TST D - TST E - TST (HL) - TST n - - XOR (HL) - XOR (IX+offset) - XOR (IY+offset) - XOR A - XOR B - XOR C - XOR D - XOR E - XOR H - XOR L - XOR n - end diff --git a/branches/s100/XSource/Makefile b/branches/s100/XSource/Makefile deleted file mode 100644 index f42e7352..00000000 --- a/branches/s100/XSource/Makefile +++ /dev/null @@ -1,467 +0,0 @@ -# Makefile 1/31/2013 dwg - - -# RomWBW/branches/s100/XSource/Makefile 1/19/2013 dgw - -# This makefile is a preliminary build script for the new std.asm schema. -# It currently builds the zeta and n8_2312 platforms and work on the -# n8vem platform is in progress but not working yet. - -# RomWBW/branches/dwg/XSource/Makefile 1/16/2013 dwg - validate build on Linux -# RomWBW/branches/dwg/XSource/Makefile 11/09/2012 dwg - add copy rule for n8chars.inc -# RomWBW/branches/dwg/XSource/Makefile 10/24/2012 dwg - -# -# GCC based makefile -# -# 09/28/2012 2.2 dwg - updated for Mac OS X 10.8.2 Mountain Lion -# -# 06/18/2012 2.0 dgg - updated for v2.0 -# -# 02/22/2012 1.5 dgg - modified for assembly under Linux -# -# 01/11/2011 1.4 wbw - added support for ZSDOS/ZDDOS/ZCPR -# -# 12/22/2011 1.3 wbw - removed all built-in config stuff, operation is now entirely -# dependent on variables CONFIG, ROMSIZE, and CPU -# -# 12/02/2011 1.3 wbw - replaced makever functionality with built-in makefile stuff -# -# 11/29/2011 1.3 dwg - uses makever to generate stdincl.inc from the version.hpp file -# -# 11/19/2011 1.3 dwg - added n8vem_vdu to "usage" and "all" rules -# enhanced clean to get files in $(OUTDIR) -# added custom to "all" rule - -# -# The operation of this makefile is entirely dependent on the setting -# of three variables: CONFIG, ROMSIZE, and CPU: -# -# CONFIG determines which configuration to build which means that -# it will determine the config_xxx.asm config settings file to -# include as well as the output file names. So, for example, -# if CONFIG is "n8vem", the config_n8vem.asm file will be used -# for BIOS configuration settings and the output files will be -# n8vem.rom, n8vem.sys, and n8vem.com. -# -# ROMSIZE specifies the size of the ROM image to be produced and -# currently must be either "1024" for a 1MB ROM or "512" for a -# 512KB ROM. -# -# CPU specifies the instruction set to be used in assembly and -# must be either "80" for Z80 or "180" for Z180. Currently, -# you should use 180 for N8 ROMs and 80 for everything else. -# -# SYS specifies the system variant to build in. CPM will -# build traditional CP/M. ZSYS will build ZSystem which -# currently means ZSDOS 1.2 & ZCPR 1.0 -# -# ROMNAME names the output file. It defaults to -# CONFIG. The output of the build will be: -# .rom, .sys, and .com. -# -# These variables can be passed into the makefile by the command -# line, hardcoded in this file, or set as environment variables -# in the OS. To use a command line, use the following format: -# -# make CONFIG= ROMSIZE= CPU= SYS= ROMNAME= -# -# An example of this is: -# -# make CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# Alternatively, you can specify the variables by hardcoding them -# in this file. To do so, uncomment the five lines after these -# comments and change the values as desired. -# If the variables are specified this way, you would then invoke -# the make by simply using "make" -# -# If you want to set them as environment variables, you can -# do this with commands like the following at an OS command -# prompt or in a batch file: -# -# SET CONFIG=zeta -# SET ROMSIZE=512 -# SET CPU=80 -# SET SYS=CPM -# SET ROMNAME=zeta -# -# Note: use "make clean" to delete temporary and output files -# -# A good idea is to do a clean with every build and this can be -# accomplished on one command line doing something like this: -# -# make clean all CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# or, if you are using hard coded variables above: -# -# make clean all -# -# Uncomment and update values below to hardcode settings: -# - -#CONFIG := zeta -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := zeta - -#CONFIG := n8_2312 -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := n8_2312 - -#CONFIG := n8vem -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := n8vem - -CONFIG := s100_std -ROMSIZE := 512 -CPU := 80 -SYS := CPM -ROMNAME := s100 -CPUROM := master-luke - -ifndef ROMNAME -ROMNAME := $(CONFIG) -endif - -CPMCP := bin/cpmcp -CVT := bin/CVT2MAC -SRC := ../Source/ - -ROMDSKFILES := ../RomDsk/$(SYS)_$(ROMSIZE)KB/*.* ../RomDsk/cfg_$(CONFIG)/*.* ../Apps/core/*.* - -ifeq "$(SYS)" "CPM" -DOSBIN := bdosb01.bin -CPBIN := ccpb03.bin -else -DOSBIN := zsdos.bin -CPBIN := zcprw.bin -endif - -OUTDIR := ../Output - -TASM := bin/TASM -TASMTABS := bin -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -NULL := -SPACE := ${NULL} ${NULL} - - -%.bin: %.asm - $(ASM80) $< $@ - -%.com: %.asm - $(ASM80) $< $@ - -%.img: %.asm - $(ASMIMG) $< $@ - -%.exe: %.cpp - $(CC) $< -o $@ - -ifneq ($(MAKECMDGOALS),clean) -ifeq "$(and $(CONFIG), $(ROMSIZE), $(CPU), $(SYS), $(ROMNAME))" "" -$(error Usage: make CONFIG= ROMSIZE=[512|1024] CPU=[80|180] SYS=[CPM|ZSYS] ROMNAME=) -endif -endif - -# The STDS macro names all the sub-includes so they all can be copied -# in from the Source folder. $(STDS) is the first dependency of the "all" -# target, therefore assuring that these files are here in time for their -# use in any assembly that includes the top level file, "std.asm". -# STDS = std-n8.inc std-n8vem.inc std-s100.inc std-s2i.inc std-zeta.inc -STDS = std-s100.inc std-n8vem.inc -CONDIT = $(OUTDIR)/$(CPUROM).rom - -all: $(STDS) tasm80.tab tasm85.tab $(OUTDIR)/$(ROMNAME).rom $(OUTDIR)/$(ROMNAME).sys $(OUTDIR)/$(ROMNAME).com $(CONDIT) - rm -f *.asm - rm -f *.bin - rm -f *.inc *.tab *.tmp - rm -f diskdefs *.exp - -tasm80.tab: bin/TASM80.TAB - cp bin/TASM80.TAB tasm80.tab - -tasm85.tab: bin/TASM85.TAB - cp bin/TASM85.TAB tasm85.tab - - -build.inc: - /bin/echo ';' >$@ - /bin/echo -n '; RomWBW Configured for '$(CONFIG)' ' >>$@ - date >> $@ - /bin/echo ; >>$@ - /bin/echo -n '#DEFINE TIMESTAMP "' >>$@ - date '+%Y %m %d %H%M"' >>$@ - /bin/echo ; >>$@ - /bin/echo '#DEFINE VARIANT "WBW-$(USERNAME)"' >>$@ - /bin/echo ; >>$@ - /bin/echo ROMSIZE .EQU $(ROMSIZE) >>$@ - /bin/echo ; >>$@ - /bin/echo '#INCLUDE "config_'$(CONFIG)'.asm"' >>$@ - /bin/echo ; >>$@ - -# 12/31/2012 dwg - added xio.asm as dependency -bootrom.bin : bootrom.asm std.asm build.inc ver.inc memmgr.asm config_$(CONFIG).asm xio.asm - $(TASM) $(ASMOPT80) $< $@ - -bootapp.bin: bootapp.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -#$(OUTDIR)/$(CPUROM).rom: $(CPUROM).asm std.asm build.inc config_$(CONFIG).asm -# cp config_$(CONFIG).asm config.asm -# $(ASMIMG) $(CPUROM).asm $(OUTDIR)/$(CPUROM).rom - -$(OUTDIR)/$(CPUROM).rom: $(CPUROM).asm - $(ASMIMG) $< $@ - -pgzero.bin: pgzero.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -zcprw.bin: zcprw.asm zcpr.asm - $(TASM) $(ASMOPT85) $< $@ - -zsdos.bin: zsdos.asm zsdos.lib zsdos-gp.z80 - $(TASM) $(ASMOPT80) $< $@ - -cbios.bin: cbios.asm fd_data.asm ide_data.asm ppide_data.asm sd_data.asm prp_data.asm ppp_data.asm uart.asm vdu.asm std.asm ver.inc build.inc infolist.inc - $(TASM) $(ASMOPT80) -dBLD_SYS=SYS_$(SYS) $< $@ - -dbgmon.bin: dbgmon.asm std.asm ver.inc build.inc - -syscfg.bin: syscfg.asm std.asm build.inc ver.inc - -os.bin: $(CPBIN) $(DOSBIN) cbios.bin - cat $(CPBIN) $(DOSBIN) cbios.bin >>$@ - -rom0.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin >>$@ - -# fixed 1/16/20113 dwg - added hbios.bin to end of cat list -rom1.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin >>$@ - -$(OUTDIR)/$(ROMNAME).rom: rom0.bin rom1.bin $(ROMDISKFILES) $(OUTDIR)/$(ROMNAME).sys diskdefs - cp $(SRC)blank$(ROMSIZE)KB.dat RomDisk.tmp - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp $(ROMDSKFILES) 0: - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp ../Output/$(ROMNAME).sys 0:$(SYS).sys - cat rom0.bin rom1.bin RomDisk.tmp >>$@ - -$(OUTDIR)/$(ROMNAME).com: bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin - cat bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin >>$@ - -$(OUTDIR)/$(ROMNAME).sys: prefix.bin os.bin - cat prefix.bin os.bin >>$@ - -$(OUTDIR)/$(CPUROM).bin: $(CPUROM).asm std.asm btromwbw.inc - $(ASMIMG) $(CPUROM).asm $@ - -std.asm: $(SRC)std.asm - cp $< $@ - $(CVT) $@ - -ansi.asm: $(SRC)ansi.asm - cp $< $@ - $(CVT) $@ - -bdosb01.asm: $(SRC)bdosb01.asm - cp $< $@ - $(CVT) $@ - -hbios.asm: $(SRC)hbios.asm kbd.asm fd.asm ppide.asm n8v.asm n8chars.inc ppk.asm sd.asm tty.asm ansi.asm - cp $(SRC)hbios.asm $@ - $(CVT) $@ - -bootapp.asm: $(SRC)bootapp.asm - cp $< $@ - $(CVT) $@ - -bootrom.asm: $(SRC)bootrom.asm - cp $< $@ - $(CVT) $@ - -cbios.asm: $(SRC)cbios.asm - cp $< $@ - $(CVT) $@ - -ccpb03.asm: $(SRC)ccpb03.asm - cp $< $@ - $(CVT) $@ - -cnfgdata.inc: $(SRC)cnfgdata.inc - cp $< $@ - $(CVT) $@ - -config_$(CONFIG).asm: $(SRC)config_$(CONFIG).asm - cp $< $@ - $(CVT) $@ - -dbgmon.asm: $(SRC)dbgmon.asm - cp $< $@ - $(CVT) $@ - -diskdefs: $(SRC)diskdefs - cp $< $@ - $(CVT) $@ - -fd.asm: $(SRC)fd.asm - cp $< $@ - $(CVT) $@ - -fd_data.asm: $(SRC)fd_data.asm - cp $< $@ - $(CVT) $@ - -hbfill.asm: $(SRC)hbfill.asm - cp $< $@ - $(CVT) $@ - -ide_data.asm: $(SRC)ide_data.asm - cp $< $@ - $(CVT) $@ - -infolist.inc: $(SRC)infolist.inc - cp $< $@ - $(CVT) $@ - -kbd.asm: $(SRC)kbd.asm - cp $< $@ - $(CVT) $@ - -loader.asm: $(SRC)loader.asm util.asm - cp $(SRC)loader.asm $@ - $(CVT) $@ - -$(CPUROM).asm: $(SRC)/$(CPUROM).asm - cp $< $@ - $(CVT) $@ - -btromwbw.inc: $(SRC)/btromwbw.inc - cp $< $@ - $(CVT) $@ - -memmgr.asm: $(SRC)memmgr.asm - cp $< $@ - $(CVT) $@ - -n8chars.inc: $(SRC)n8chars.inc - cp $< $@ - $(CVT) $@ - -n8v.asm: $(SRC)n8v.asm - cp $< $@ - $(CVT) $@ - -pgzero.asm: $(SRC)pgzero.asm - cp $< $@ - $(CVT) $@ - -ppide.asm: $(SRC)ppide.asm - cp $< $@ - $(CVT) $@ - -ppide_data.asm: $(SRC)ppide_data.asm - cp $< $@ - $(CVT) $@ - -ppk.asm: $(SRC)ppk.asm - cp $< $@ - $(CVT) $@ - -ppp_data.asm: $(SRC)ppp_data.asm - cp $< $@ - $(CVT) $@ - -prefix.asm: $(SRC)prefix.asm - cp $< $@ - $(CVT) $@ - -prp_data.asm: $(SRC)prp_data.asm - cp $< $@ - $(CVT) $@ - -romfill.asm: $(SRC)romfill.asm - cp $< $@ - $(CVT) $@ - -s100-i3.asm: $(SRC)s100-i3.asm - cp $< $@ - $(CVT) $@ - -sd.asm: $(SRC)sd.asm - cp $< $@ - $(CVT) $@ - -sd_data.asm: $(SRC)sd_data.asm - cp $< $@ - $(CVT) $@ - -# By adding all the sub-includes as dependencies for std.asm, this assures that -# whichever one we are using will be present during the assembly of any modules -# that include std.asm. -std.asm: $(SRC)std.asm $(STDS) - cp $(SRC)std.asm $@ - $(CVT) $@ - -std-n8.inc: $(SRC)std-n8.inc - cp $< $@ - $(CVT) $@ - -std-n8vem.inc: $(SRC)std-n8vem.inc - cp $< $@ - $(CVT) $@ - -std-s100.inc: $(SRC)std-s100.inc - cp $< $@ - $(CVT) $@ - -std-s2i.inc: $(SRC)std-s2i.inc - cp $< $@ - $(CVT) $@ - -std-zeta.inc: $(SRC)std-zeta.inc - cp $< $@ - $(CVT) $@ - -syscfg.asm: $(SRC)syscfg.asm config_$(CONFIG).asm cnfgdata.inc - cp $< $@ - $(CVT) $@ - -tty.asm: $(SRC)tty.asm - cp $< $@ - $(CVT) $@ - -uart.asm: $(SRC)uart.asm - cp $< $@ - $(CVT) $@ - -util.asm: $(SRC)util.asm - cp $< $@ - $(CVT) $@ - -vdu.asm: $(SRC)vdu.asm - cp $< $@ - $(CVT) $@ - -ver.inc: $(SRC)ver.inc - cp $< $@ - $(CVT) $@ - -xio.asm: $(SRC)xio.asm - cp $< $@ - $(CVT) $@ - -clean: - rm -f *.tab *.TAB *.inc *.asm *.bin *.com *.img *.rom *.lst *.exp *.tmp - rm -f build.inc diskdefs *.inc - rm -f $(OUTDIR)/*.* diff --git a/branches/s100/XSource/Makefile_n8_2312 b/branches/s100/XSource/Makefile_n8_2312 deleted file mode 100644 index e29423a0..00000000 --- a/branches/s100/XSource/Makefile_n8_2312 +++ /dev/null @@ -1,431 +0,0 @@ -# RomWBW/branches/s100/XSource/Makefile 1/19/2013 dgw - -# This makefile is a preliminary build script for the new std.asm schema. -# It currently builds the zeta and n8_2312 platforms and work on the -# n8vem platform is in progress but not working yet. - -# RomWBW/branches/dwg/XSource/Makefile 1/16/2013 dwg - validate build on Linux -# RomWBW/branches/dwg/XSource/Makefile 11/09/2012 dwg - add copy rule for n8chars.inc -# RomWBW/branches/dwg/XSource/Makefile 10/24/2012 dwg - -# -# GCC based makefile -# -# 09/28/2012 2.2 dwg - updated for Mac OS X 10.8.2 Mountain Lion -# -# 06/18/2012 2.0 dgg - updated for v2.0 -# -# 02/22/2012 1.5 dgg - modified for assembly under Linux -# -# 01/11/2011 1.4 wbw - added support for ZSDOS/ZDDOS/ZCPR -# -# 12/22/2011 1.3 wbw - removed all built-in config stuff, operation is now entirely -# dependent on variables CONFIG, ROMSIZE, and CPU -# -# 12/02/2011 1.3 wbw - replaced makever functionality with built-in makefile stuff -# -# 11/29/2011 1.3 dwg - uses makever to generate stdincl.inc from the version.hpp file -# -# 11/19/2011 1.3 dwg - added n8vem_vdu to "usage" and "all" rules -# enhanced clean to get files in $(OUTDIR) -# added custom to "all" rule - -# -# The operation of this makefile is entirely dependent on the setting -# of three variables: CONFIG, ROMSIZE, and CPU: -# -# CONFIG determines which configuration to build which means that -# it will determine the config_xxx.asm config settings file to -# include as well as the output file names. So, for example, -# if CONFIG is "n8vem", the config_n8vem.asm file will be used -# for BIOS configuration settings and the output files will be -# n8vem.rom, n8vem.sys, and n8vem.com. -# -# ROMSIZE specifies the size of the ROM image to be produced and -# currently must be either "1024" for a 1MB ROM or "512" for a -# 512KB ROM. -# -# CPU specifies the instruction set to be used in assembly and -# must be either "80" for Z80 or "180" for Z180. Currently, -# you should use 180 for N8 ROMs and 80 for everything else. -# -# SYS specifies the system variant to build in. CPM will -# build traditional CP/M. ZSYS will build ZSystem which -# currently means ZSDOS 1.2 & ZCPR 1.0 -# -# ROMNAME names the output file. It defaults to -# CONFIG. The output of the build will be: -# .rom, .sys, and .com. -# -# These variables can be passed into the makefile by the command -# line, hardcoded in this file, or set as environment variables -# in the OS. To use a command line, use the following format: -# -# make CONFIG= ROMSIZE= CPU= SYS= ROMNAME= -# -# An example of this is: -# -# make CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# Alternatively, you can specify the variables by hardcoding them -# in this file. To do so, uncomment the five lines after these -# comments and change the values as desired. -# If the variables are specified this way, you would then invoke -# the make by simply using "make" -# -# If you want to set them as environment variables, you can -# do this with commands like the following at an OS command -# prompt or in a batch file: -# -# SET CONFIG=zeta -# SET ROMSIZE=512 -# SET CPU=80 -# SET SYS=CPM -# SET ROMNAME=zeta -# -# Note: use "make clean" to delete temporary and output files -# -# A good idea is to do a clean with every build and this can be -# accomplished on one command line doing something like this: -# -# make clean all CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# or, if you are using hard coded variables above: -# -# make clean all -# -# Uncomment and update values below to hardcode settings: -# - - -# 1/19/2013 dwg - tested zeta, - -#CONFIG := zeta -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := zeta - -CONFIG := n8_2312 -ROMSIZE := 512 -CPU := 180 -SYS := CPM -ROMNAME := n8_2312 - -#CONFIG := N8VEM -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := N8VEM - - - -ifndef ROMNAME -ROMNAME := $(CONFIG) -endif - -CPMCP := bin/cpmcp -CVT := bin/CVT2MAC -SRC := ../Source/ - -ROMDSKFILES := ../RomDsk/$(SYS)_$(ROMSIZE)KB/*.* ../RomDsk/cfg_$(CONFIG)/*.* ../Apps/core/*.* - -ifeq "$(SYS)" "CPM" -DOSBIN := bdosb01.bin -CPBIN := ccpb03.bin -else -DOSBIN := zsdos.bin -CPBIN := zcprw.bin -endif - -OUTDIR := ../Output - -TASM := bin/TASM -TASMTABS := bin -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -NULL := -SPACE := ${NULL} ${NULL} - -%.bin: %.asm - $(ASM80) $< $@ - -%.com: %.asm - $(ASM80) $< $@ - -%.img: %.asm - $(ASMIMG) $< $@ - -%.exe: %.cpp - $(CC) $< -o $@ - -ifneq ($(MAKECMDGOALS),clean) -ifeq "$(and $(CONFIG), $(ROMSIZE), $(CPU), $(SYS), $(ROMNAME))" "" -$(error Usage: make CONFIG= ROMSIZE=[512|1024] CPU=[80|180] SYS=[CPM|ZSYS] ROMNAME=) -endif -endif - -STDS = std-n8.inc std-n8vem.inc std-s100.inc std-s2i.inc std-zeta.inc - -all: $(STDS) tasm80.tab tasm85.tab $(OUTDIR)/$(ROMNAME).rom $(OUTDIR)/$(ROMNAME).sys $(OUTDIR)/$(ROMNAME).com - rm -f *.asm - rm -f *.bin - rm -f *.inc *.tab *.tmp - rm -f diskdefs *.exp - -tasm80.tab: bin/TASM80.TAB - cp bin/TASM80.TAB tasm80.tab - -tasm85.tab: bin/TASM85.TAB - cp bin/TASM85.TAB tasm85.tab - - -build.inc: - /bin/echo ';' >$@ - /bin/echo -n '; RomWBW Configured for '$(CONFIG)' ' >>$@ - date >> $@ - /bin/echo ; >>$@ - /bin/echo -n '#DEFINE TIMESTAMP "' >>$@ - date '+%Y %m %d %H%M"' >>$@ - /bin/echo ; >>$@ - /bin/echo '#DEFINE VARIANT "WBW-$(USERNAME)"' >>$@ - /bin/echo ; >>$@ - /bin/echo ROMSIZE .EQU $(ROMSIZE) >>$@ - /bin/echo ; >>$@ - /bin/echo '#INCLUDE "config_'$(CONFIG)'.asm"' >>$@ - /bin/echo ; >>$@ - -# 12/31/2012 dwg - added xio.asm as dependency -bootrom.bin : bootrom.asm std.asm build.inc ver.inc memmgr.asm config_$(CONFIG).asm xio.asm - $(TASM) $(ASMOPT80) $< $@ - -bootapp.bin: bootapp.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -pgzero.bin: pgzero.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -zcprw.bin: zcprw.asm zcpr.asm - $(TASM) $(ASMOPT85) $< $@ - -zsdos.bin: zsdos.asm zsdos.lib zsdos-gp.z80 - $(TASM) $(ASMOPT80) $< $@ - -cbios.bin: cbios.asm fd_data.asm ide_data.asm ppide_data.asm sd_data.asm prp_data.asm ppp_data.asm uart.asm vdu.asm std.asm ver.inc build.inc infolist.inc - $(TASM) $(ASMOPT80) -dBLD_SYS=SYS_$(SYS) $< $@ - -dbgmon.bin: dbgmon.asm std.asm ver.inc build.inc - -syscfg.bin: syscfg.asm std.asm build.inc ver.inc - -os.bin: $(CPBIN) $(DOSBIN) cbios.bin - cat $(CPBIN) $(DOSBIN) cbios.bin >>$@ - -rom0.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin >>$@ - -# fixed 1/16/20113 dwg - added hbios.bin to end of cat list -rom1.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin >>$@ - -$(OUTDIR)/$(ROMNAME).rom: rom0.bin rom1.bin $(ROMDISKFILES) $(OUTDIR)/$(ROMNAME).sys diskdefs - cp $(SRC)blank$(ROMSIZE)KB.dat RomDisk.tmp - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp $(ROMDSKFILES) 0: - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp ../Output/$(ROMNAME).sys 0:$(SYS).sys - cat rom0.bin rom1.bin RomDisk.tmp >>$@ - -$(OUTDIR)/$(ROMNAME).com: bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin - cat bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin >>$@ - -$(OUTDIR)/$(ROMNAME).sys: prefix.bin os.bin - cat prefix.bin os.bin >>$@ - -ansi.asm: $(SRC)ansi.asm - cp $< $@ - $(CVT) $@ - -bdosb01.asm: $(SRC)bdosb01.asm - cp $< $@ - $(CVT) $@ - -hbios.asm: $(SRC)hbios.asm kbd.asm fd.asm ppide.asm n8v.asm n8chars.inc ppk.asm sd.asm tty.asm ansi.asm - cp $(SRC)hbios.asm $@ - $(CVT) $@ - -bootapp.asm: $(SRC)bootapp.asm - cp $< $@ - $(CVT) $@ - -bootrom.asm: $(SRC)bootrom.asm - cp $< $@ - $(CVT) $@ - -cbios.asm: $(SRC)cbios.asm - cp $< $@ - $(CVT) $@ - -ccpb03.asm: $(SRC)ccpb03.asm - cp $< $@ - $(CVT) $@ - -cnfgdata.inc: $(SRC)cnfgdata.inc - cp $< $@ - $(CVT) $@ - -##config_zeta.asm: $(SRC)config_zeta.asm -## cp $< $@ -## $(CVT) $@ - -config_$(CONFIG).asm: $(SRC)config_$(CONFIG).asm - cp $< $@ - $(CVT) $@ - -dbgmon.asm: $(SRC)dbgmon.asm - cp $< $@ - $(CVT) $@ - -diskdefs: $(SRC)diskdefs - cp $< $@ - $(CVT) $@ - -fd.asm: $(SRC)fd.asm - cp $< $@ - $(CVT) $@ - -fd_data.asm: $(SRC)fd_data.asm - cp $< $@ - $(CVT) $@ - -hbfill.asm: $(SRC)hbfill.asm - cp $< $@ - $(CVT) $@ - -ide_data.asm: $(SRC)ide_data.asm - cp $< $@ - $(CVT) $@ - -infolist.inc: $(SRC)infolist.inc - cp $< $@ - $(CVT) $@ - -kbd.asm: $(SRC)kbd.asm - cp $< $@ - $(CVT) $@ - -loader.asm: $(SRC)loader.asm util.asm - cp $(SRC)loader.asm $@ - $(CVT) $@ - -memmgr.asm: $(SRC)memmgr.asm - cp $< $@ - $(CVT) $@ - -n8chars.inc: $(SRC)n8chars.inc - cp $< $@ - $(CVT) $@ - -n8v.asm: $(SRC)n8v.asm - cp $< $@ - $(CVT) $@ - -pgzero.asm: $(SRC)pgzero.asm - cp $< $@ - $(CVT) $@ - -ppide.asm: $(SRC)ppide.asm - cp $< $@ - $(CVT) $@ - -ppide_data.asm: $(SRC)ppide_data.asm - cp $< $@ - $(CVT) $@ - -ppk.asm: $(SRC)ppk.asm - cp $< $@ - $(CVT) $@ - -ppp_data.asm: $(SRC)ppp_data.asm - cp $< $@ - $(CVT) $@ - -prefix.asm: $(SRC)prefix.asm - cp $< $@ - $(CVT) $@ - -prp_data.asm: $(SRC)prp_data.asm - cp $< $@ - $(CVT) $@ - -romfill.asm: $(SRC)romfill.asm - cp $< $@ - $(CVT) $@ - -sd.asm: $(SRC)sd.asm - cp $< $@ - $(CVT) $@ - -sd_data.asm: $(SRC)sd_data.asm - cp $< $@ - $(CVT) $@ - -std.asm: $(SRC)std.asm - cp $< $@ - $(CVT) $@ - -std-n8.inc: $(SRC)std-n8.inc - cp $< $@ - $(CVT) $@ - -std-n8vem.inc: $(SRC)std-n8vem.inc - cp $< $@ - $(CVT) $@ - -std-s100.inc: $(SRC)std-s100.inc - cp $< $@ - $(CVT) $@ - -std-s2i.inc: $(SRC)std-s2i.inc - cp $< $@ - $(CVT) $@ - -std-zeta.inc: $(SRC)std-zeta.inc - cp $< $@ - $(CVT) $@ - -syscfg.asm: $(SRC)syscfg.asm config_$(CONFIG).asm cnfgdata.inc - cp $< $@ - $(CVT) $@ - -tty.asm: $(SRC)tty.asm - cp $< $@ - $(CVT) $@ - -uart.asm: $(SRC)uart.asm - cp $< $@ - $(CVT) $@ - -util.asm: $(SRC)util.asm - cp $< $@ - $(CVT) $@ - -vdu.asm: $(SRC)vdu.asm - cp $< $@ - $(CVT) $@ - -ver.inc: $(SRC)ver.inc - cp $< $@ - $(CVT) $@ - -xio.asm: $(SRC)xio.asm - cp $< $@ - $(CVT) $@ - -clean: - rm -f *.tab *.TAB *.inc *.asm *.bin *.com *.img *.rom *.lst *.exp *.tmp - rm -f build.inc diskdefs *.inc - rm -f $(OUTDIR)/*.* diff --git a/branches/s100/XSource/Makefile_n8vem b/branches/s100/XSource/Makefile_n8vem deleted file mode 100644 index 12632ba3..00000000 --- a/branches/s100/XSource/Makefile_n8vem +++ /dev/null @@ -1,431 +0,0 @@ -# RomWBW/branches/s100/XSource/Makefile 1/19/2013 dgw - -# This makefile is a preliminary build script for the new std.asm schema. -# It currently builds the zeta and n8_2312 platforms and work on the -# n8vem platform is in progress but not working yet. - -# RomWBW/branches/dwg/XSource/Makefile 1/16/2013 dwg - validate build on Linux -# RomWBW/branches/dwg/XSource/Makefile 11/09/2012 dwg - add copy rule for n8chars.inc -# RomWBW/branches/dwg/XSource/Makefile 10/24/2012 dwg - -# -# GCC based makefile -# -# 09/28/2012 2.2 dwg - updated for Mac OS X 10.8.2 Mountain Lion -# -# 06/18/2012 2.0 dgg - updated for v2.0 -# -# 02/22/2012 1.5 dgg - modified for assembly under Linux -# -# 01/11/2011 1.4 wbw - added support for ZSDOS/ZDDOS/ZCPR -# -# 12/22/2011 1.3 wbw - removed all built-in config stuff, operation is now entirely -# dependent on variables CONFIG, ROMSIZE, and CPU -# -# 12/02/2011 1.3 wbw - replaced makever functionality with built-in makefile stuff -# -# 11/29/2011 1.3 dwg - uses makever to generate stdincl.inc from the version.hpp file -# -# 11/19/2011 1.3 dwg - added n8vem_vdu to "usage" and "all" rules -# enhanced clean to get files in $(OUTDIR) -# added custom to "all" rule - -# -# The operation of this makefile is entirely dependent on the setting -# of three variables: CONFIG, ROMSIZE, and CPU: -# -# CONFIG determines which configuration to build which means that -# it will determine the config_xxx.asm config settings file to -# include as well as the output file names. So, for example, -# if CONFIG is "n8vem", the config_n8vem.asm file will be used -# for BIOS configuration settings and the output files will be -# n8vem.rom, n8vem.sys, and n8vem.com. -# -# ROMSIZE specifies the size of the ROM image to be produced and -# currently must be either "1024" for a 1MB ROM or "512" for a -# 512KB ROM. -# -# CPU specifies the instruction set to be used in assembly and -# must be either "80" for Z80 or "180" for Z180. Currently, -# you should use 180 for N8 ROMs and 80 for everything else. -# -# SYS specifies the system variant to build in. CPM will -# build traditional CP/M. ZSYS will build ZSystem which -# currently means ZSDOS 1.2 & ZCPR 1.0 -# -# ROMNAME names the output file. It defaults to -# CONFIG. The output of the build will be: -# .rom, .sys, and .com. -# -# These variables can be passed into the makefile by the command -# line, hardcoded in this file, or set as environment variables -# in the OS. To use a command line, use the following format: -# -# make CONFIG= ROMSIZE= CPU= SYS= ROMNAME= -# -# An example of this is: -# -# make CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# Alternatively, you can specify the variables by hardcoding them -# in this file. To do so, uncomment the five lines after these -# comments and change the values as desired. -# If the variables are specified this way, you would then invoke -# the make by simply using "make" -# -# If you want to set them as environment variables, you can -# do this with commands like the following at an OS command -# prompt or in a batch file: -# -# SET CONFIG=zeta -# SET ROMSIZE=512 -# SET CPU=80 -# SET SYS=CPM -# SET ROMNAME=zeta -# -# Note: use "make clean" to delete temporary and output files -# -# A good idea is to do a clean with every build and this can be -# accomplished on one command line doing something like this: -# -# make clean all CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# or, if you are using hard coded variables above: -# -# make clean all -# -# Uncomment and update values below to hardcode settings: -# - - -# 1/19/2013 dwg - tested zeta, - -#CONFIG := zeta -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := zeta - -#CONFIG := n8_2312 -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := n8_2312 - -CONFIG := n8vem -ROMSIZE := 512 -CPU := 180 -SYS := CPM -ROMNAME := n8vem - - - -ifndef ROMNAME -ROMNAME := $(CONFIG) -endif - -CPMCP := bin/cpmcp -CVT := bin/CVT2MAC -SRC := ../Source/ - -ROMDSKFILES := ../RomDsk/$(SYS)_$(ROMSIZE)KB/*.* ../RomDsk/cfg_$(CONFIG)/*.* ../Apps/core/*.* - -ifeq "$(SYS)" "CPM" -DOSBIN := bdosb01.bin -CPBIN := ccpb03.bin -else -DOSBIN := zsdos.bin -CPBIN := zcprw.bin -endif - -OUTDIR := ../Output - -TASM := bin/TASM -TASMTABS := bin -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -NULL := -SPACE := ${NULL} ${NULL} - -%.bin: %.asm - $(ASM80) $< $@ - -%.com: %.asm - $(ASM80) $< $@ - -%.img: %.asm - $(ASMIMG) $< $@ - -%.exe: %.cpp - $(CC) $< -o $@ - -ifneq ($(MAKECMDGOALS),clean) -ifeq "$(and $(CONFIG), $(ROMSIZE), $(CPU), $(SYS), $(ROMNAME))" "" -$(error Usage: make CONFIG= ROMSIZE=[512|1024] CPU=[80|180] SYS=[CPM|ZSYS] ROMNAME=) -endif -endif - -STDS = std-n8.inc std-n8vem.inc std-s100.inc std-s2i.inc std-zeta.inc - -all: $(STDS) tasm80.tab tasm85.tab $(OUTDIR)/$(ROMNAME).rom $(OUTDIR)/$(ROMNAME).sys $(OUTDIR)/$(ROMNAME).com - rm -f *.asm - rm -f *.bin - rm -f *.inc *.tab *.tmp - rm -f diskdefs *.exp - -tasm80.tab: bin/TASM80.TAB - cp bin/TASM80.TAB tasm80.tab - -tasm85.tab: bin/TASM85.TAB - cp bin/TASM85.TAB tasm85.tab - - -build.inc: - /bin/echo ';' >$@ - /bin/echo -n '; RomWBW Configured for '$(CONFIG)' ' >>$@ - date >> $@ - /bin/echo ; >>$@ - /bin/echo -n '#DEFINE TIMESTAMP "' >>$@ - date '+%Y %m %d %H%M"' >>$@ - /bin/echo ; >>$@ - /bin/echo '#DEFINE VARIANT "WBW-$(USERNAME)"' >>$@ - /bin/echo ; >>$@ - /bin/echo ROMSIZE .EQU $(ROMSIZE) >>$@ - /bin/echo ; >>$@ - /bin/echo '#INCLUDE "config_'$(CONFIG)'.asm"' >>$@ - /bin/echo ; >>$@ - -# 12/31/2012 dwg - added xio.asm as dependency -bootrom.bin : bootrom.asm std.asm build.inc ver.inc memmgr.asm config_$(CONFIG).asm xio.asm - $(TASM) $(ASMOPT80) $< $@ - -bootapp.bin: bootapp.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -pgzero.bin: pgzero.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -zcprw.bin: zcprw.asm zcpr.asm - $(TASM) $(ASMOPT85) $< $@ - -zsdos.bin: zsdos.asm zsdos.lib zsdos-gp.z80 - $(TASM) $(ASMOPT80) $< $@ - -cbios.bin: cbios.asm fd_data.asm ide_data.asm ppide_data.asm sd_data.asm prp_data.asm ppp_data.asm uart.asm vdu.asm std.asm ver.inc build.inc infolist.inc - $(TASM) $(ASMOPT80) -dBLD_SYS=SYS_$(SYS) $< $@ - -dbgmon.bin: dbgmon.asm std.asm ver.inc build.inc - -syscfg.bin: syscfg.asm std.asm build.inc ver.inc - -os.bin: $(CPBIN) $(DOSBIN) cbios.bin - cat $(CPBIN) $(DOSBIN) cbios.bin >>$@ - -rom0.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin >>$@ - -# fixed 1/16/20113 dwg - added hbios.bin to end of cat list -rom1.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin >>$@ - -$(OUTDIR)/$(ROMNAME).rom: rom0.bin rom1.bin $(ROMDISKFILES) $(OUTDIR)/$(ROMNAME).sys diskdefs - cp $(SRC)blank$(ROMSIZE)KB.dat RomDisk.tmp - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp $(ROMDSKFILES) 0: - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp ../Output/$(ROMNAME).sys 0:$(SYS).sys - cat rom0.bin rom1.bin RomDisk.tmp >>$@ - -$(OUTDIR)/$(ROMNAME).com: bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin - cat bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin >>$@ - -$(OUTDIR)/$(ROMNAME).sys: prefix.bin os.bin - cat prefix.bin os.bin >>$@ - -ansi.asm: $(SRC)ansi.asm - cp $< $@ - $(CVT) $@ - -bdosb01.asm: $(SRC)bdosb01.asm - cp $< $@ - $(CVT) $@ - -hbios.asm: $(SRC)hbios.asm kbd.asm fd.asm ppide.asm n8v.asm n8chars.inc ppk.asm sd.asm tty.asm ansi.asm - cp $(SRC)hbios.asm $@ - $(CVT) $@ - -bootapp.asm: $(SRC)bootapp.asm - cp $< $@ - $(CVT) $@ - -bootrom.asm: $(SRC)bootrom.asm - cp $< $@ - $(CVT) $@ - -cbios.asm: $(SRC)cbios.asm - cp $< $@ - $(CVT) $@ - -ccpb03.asm: $(SRC)ccpb03.asm - cp $< $@ - $(CVT) $@ - -cnfgdata.inc: $(SRC)cnfgdata.inc - cp $< $@ - $(CVT) $@ - -##config_zeta.asm: $(SRC)config_zeta.asm -## cp $< $@ -## $(CVT) $@ - -config_$(CONFIG).asm: $(SRC)config_$(CONFIG).asm - cp $< $@ - $(CVT) $@ - -dbgmon.asm: $(SRC)dbgmon.asm - cp $< $@ - $(CVT) $@ - -diskdefs: $(SRC)diskdefs - cp $< $@ - $(CVT) $@ - -fd.asm: $(SRC)fd.asm - cp $< $@ - $(CVT) $@ - -fd_data.asm: $(SRC)fd_data.asm - cp $< $@ - $(CVT) $@ - -hbfill.asm: $(SRC)hbfill.asm - cp $< $@ - $(CVT) $@ - -ide_data.asm: $(SRC)ide_data.asm - cp $< $@ - $(CVT) $@ - -infolist.inc: $(SRC)infolist.inc - cp $< $@ - $(CVT) $@ - -kbd.asm: $(SRC)kbd.asm - cp $< $@ - $(CVT) $@ - -loader.asm: $(SRC)loader.asm util.asm - cp $(SRC)loader.asm $@ - $(CVT) $@ - -memmgr.asm: $(SRC)memmgr.asm - cp $< $@ - $(CVT) $@ - -n8chars.inc: $(SRC)n8chars.inc - cp $< $@ - $(CVT) $@ - -n8v.asm: $(SRC)n8v.asm - cp $< $@ - $(CVT) $@ - -pgzero.asm: $(SRC)pgzero.asm - cp $< $@ - $(CVT) $@ - -ppide.asm: $(SRC)ppide.asm - cp $< $@ - $(CVT) $@ - -ppide_data.asm: $(SRC)ppide_data.asm - cp $< $@ - $(CVT) $@ - -ppk.asm: $(SRC)ppk.asm - cp $< $@ - $(CVT) $@ - -ppp_data.asm: $(SRC)ppp_data.asm - cp $< $@ - $(CVT) $@ - -prefix.asm: $(SRC)prefix.asm - cp $< $@ - $(CVT) $@ - -prp_data.asm: $(SRC)prp_data.asm - cp $< $@ - $(CVT) $@ - -romfill.asm: $(SRC)romfill.asm - cp $< $@ - $(CVT) $@ - -sd.asm: $(SRC)sd.asm - cp $< $@ - $(CVT) $@ - -sd_data.asm: $(SRC)sd_data.asm - cp $< $@ - $(CVT) $@ - -std.asm: $(SRC)std.asm - cp $< $@ - $(CVT) $@ - -std-n8.inc: $(SRC)std-n8.inc - cp $< $@ - $(CVT) $@ - -std-n8vem.inc: $(SRC)std-n8vem.inc - cp $< $@ - $(CVT) $@ - -std-s100.inc: $(SRC)std-s100.inc - cp $< $@ - $(CVT) $@ - -std-s2i.inc: $(SRC)std-s2i.inc - cp $< $@ - $(CVT) $@ - -std-zeta.inc: $(SRC)std-zeta.inc - cp $< $@ - $(CVT) $@ - -syscfg.asm: $(SRC)syscfg.asm config_$(CONFIG).asm cnfgdata.inc - cp $< $@ - $(CVT) $@ - -tty.asm: $(SRC)tty.asm - cp $< $@ - $(CVT) $@ - -uart.asm: $(SRC)uart.asm - cp $< $@ - $(CVT) $@ - -util.asm: $(SRC)util.asm - cp $< $@ - $(CVT) $@ - -vdu.asm: $(SRC)vdu.asm - cp $< $@ - $(CVT) $@ - -ver.inc: $(SRC)ver.inc - cp $< $@ - $(CVT) $@ - -xio.asm: $(SRC)xio.asm - cp $< $@ - $(CVT) $@ - -clean: - rm -f *.tab *.TAB *.inc *.asm *.bin *.com *.img *.rom *.lst *.exp *.tmp - rm -f build.inc diskdefs *.inc - rm -f $(OUTDIR)/*.* diff --git a/branches/s100/XSource/Makefile_zeta b/branches/s100/XSource/Makefile_zeta deleted file mode 100644 index a629aef8..00000000 --- a/branches/s100/XSource/Makefile_zeta +++ /dev/null @@ -1,431 +0,0 @@ -# RomWBW/branches/s100/XSource/Makefile 1/19/2013 dgw - -# This makefile is a preliminary build script for the new std.asm schema. -# It currently builds the zeta and n8_2312 platforms and work on the -# n8vem platform is in progress but not working yet. - -# RomWBW/branches/dwg/XSource/Makefile 1/16/2013 dwg - validate build on Linux -# RomWBW/branches/dwg/XSource/Makefile 11/09/2012 dwg - add copy rule for n8chars.inc -# RomWBW/branches/dwg/XSource/Makefile 10/24/2012 dwg - -# -# GCC based makefile -# -# 09/28/2012 2.2 dwg - updated for Mac OS X 10.8.2 Mountain Lion -# -# 06/18/2012 2.0 dgg - updated for v2.0 -# -# 02/22/2012 1.5 dgg - modified for assembly under Linux -# -# 01/11/2011 1.4 wbw - added support for ZSDOS/ZDDOS/ZCPR -# -# 12/22/2011 1.3 wbw - removed all built-in config stuff, operation is now entirely -# dependent on variables CONFIG, ROMSIZE, and CPU -# -# 12/02/2011 1.3 wbw - replaced makever functionality with built-in makefile stuff -# -# 11/29/2011 1.3 dwg - uses makever to generate stdincl.inc from the version.hpp file -# -# 11/19/2011 1.3 dwg - added n8vem_vdu to "usage" and "all" rules -# enhanced clean to get files in $(OUTDIR) -# added custom to "all" rule - -# -# The operation of this makefile is entirely dependent on the setting -# of three variables: CONFIG, ROMSIZE, and CPU: -# -# CONFIG determines which configuration to build which means that -# it will determine the config_xxx.asm config settings file to -# include as well as the output file names. So, for example, -# if CONFIG is "n8vem", the config_n8vem.asm file will be used -# for BIOS configuration settings and the output files will be -# n8vem.rom, n8vem.sys, and n8vem.com. -# -# ROMSIZE specifies the size of the ROM image to be produced and -# currently must be either "1024" for a 1MB ROM or "512" for a -# 512KB ROM. -# -# CPU specifies the instruction set to be used in assembly and -# must be either "80" for Z80 or "180" for Z180. Currently, -# you should use 180 for N8 ROMs and 80 for everything else. -# -# SYS specifies the system variant to build in. CPM will -# build traditional CP/M. ZSYS will build ZSystem which -# currently means ZSDOS 1.2 & ZCPR 1.0 -# -# ROMNAME names the output file. It defaults to -# CONFIG. The output of the build will be: -# .rom, .sys, and .com. -# -# These variables can be passed into the makefile by the command -# line, hardcoded in this file, or set as environment variables -# in the OS. To use a command line, use the following format: -# -# make CONFIG= ROMSIZE= CPU= SYS= ROMNAME= -# -# An example of this is: -# -# make CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# Alternatively, you can specify the variables by hardcoding them -# in this file. To do so, uncomment the five lines after these -# comments and change the values as desired. -# If the variables are specified this way, you would then invoke -# the make by simply using "make" -# -# If you want to set them as environment variables, you can -# do this with commands like the following at an OS command -# prompt or in a batch file: -# -# SET CONFIG=zeta -# SET ROMSIZE=512 -# SET CPU=80 -# SET SYS=CPM -# SET ROMNAME=zeta -# -# Note: use "make clean" to delete temporary and output files -# -# A good idea is to do a clean with every build and this can be -# accomplished on one command line doing something like this: -# -# make clean all CONFIG=n8vem ROMSIZE=512 CPU=80 SYS=CPM ROMNAME=n8vem -# -# or, if you are using hard coded variables above: -# -# make clean all -# -# Uncomment and update values below to hardcode settings: -# - - -# 1/19/2013 dwg - tested zeta, - -CONFIG := zeta -ROMSIZE := 512 -CPU := 180 -SYS := CPM -ROMNAME := zeta - -#CONFIG := n8_2312 -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := n8_2312 - -#CONFIG := N8VEM -#ROMSIZE := 512 -#CPU := 180 -#SYS := CPM -#ROMNAME := N8VEM - - - -ifndef ROMNAME -ROMNAME := $(CONFIG) -endif - -CPMCP := bin/cpmcp -CVT := bin/CVT2MAC -SRC := ../Source/ - -ROMDSKFILES := ../RomDsk/$(SYS)_$(ROMSIZE)KB/*.* ../RomDsk/cfg_$(CONFIG)/*.* ../Apps/core/*.* - -ifeq "$(SYS)" "CPM" -DOSBIN := bdosb01.bin -CPBIN := ccpb03.bin -else -DOSBIN := zsdos.bin -CPBIN := zcprw.bin -endif - -OUTDIR := ../Output - -TASM := bin/TASM -TASMTABS := bin -export TASMTABS - -ASMOPT80 := -t$(CPU) -g3 -ASMOPT85 := -t85 -g3 - -ASM80 := $(TASM) $(ASMOPT80) -ASM85 := $(TASM) $(ASMOPT85) -ASMIMG := $(TASM) $(ASMOPT80) -b -fE5 - -NULL := -SPACE := ${NULL} ${NULL} - -%.bin: %.asm - $(ASM80) $< $@ - -%.com: %.asm - $(ASM80) $< $@ - -%.img: %.asm - $(ASMIMG) $< $@ - -%.exe: %.cpp - $(CC) $< -o $@ - -ifneq ($(MAKECMDGOALS),clean) -ifeq "$(and $(CONFIG), $(ROMSIZE), $(CPU), $(SYS), $(ROMNAME))" "" -$(error Usage: make CONFIG= ROMSIZE=[512|1024] CPU=[80|180] SYS=[CPM|ZSYS] ROMNAME=) -endif -endif - -STDS = std-n8.inc std-n8vem.inc std-s100.inc std-s2i.inc std-zeta.inc - -all: $(STDS) tasm80.tab tasm85.tab $(OUTDIR)/$(ROMNAME).rom $(OUTDIR)/$(ROMNAME).sys $(OUTDIR)/$(ROMNAME).com - rm -f *.asm - rm -f *.bin - rm -f *.inc *.tab *.tmp - rm -f diskdefs *.exp - -tasm80.tab: bin/TASM80.TAB - cp bin/TASM80.TAB tasm80.tab - -tasm85.tab: bin/TASM85.TAB - cp bin/TASM85.TAB tasm85.tab - - -build.inc: - /bin/echo ';' >$@ - /bin/echo -n '; RomWBW Configured for '$(CONFIG)' ' >>$@ - date >> $@ - /bin/echo ; >>$@ - /bin/echo -n '#DEFINE TIMESTAMP "' >>$@ - date '+%Y %m %d %H%M"' >>$@ - /bin/echo ; >>$@ - /bin/echo '#DEFINE VARIANT "WBW-$(USERNAME)"' >>$@ - /bin/echo ; >>$@ - /bin/echo ROMSIZE .EQU $(ROMSIZE) >>$@ - /bin/echo ; >>$@ - /bin/echo '#INCLUDE "config_'$(CONFIG)'.asm"' >>$@ - /bin/echo ; >>$@ - -# 12/31/2012 dwg - added xio.asm as dependency -bootrom.bin : bootrom.asm std.asm build.inc ver.inc memmgr.asm config_$(CONFIG).asm xio.asm - $(TASM) $(ASMOPT80) $< $@ - -bootapp.bin: bootapp.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -pgzero.bin: pgzero.asm std.asm build.inc ver.inc - $(TASM) $(ASMOPT80) $< $@ - -zcprw.bin: zcprw.asm zcpr.asm - $(TASM) $(ASMOPT85) $< $@ - -zsdos.bin: zsdos.asm zsdos.lib zsdos-gp.z80 - $(TASM) $(ASMOPT80) $< $@ - -cbios.bin: cbios.asm fd_data.asm ide_data.asm ppide_data.asm sd_data.asm prp_data.asm ppp_data.asm uart.asm vdu.asm std.asm ver.inc build.inc infolist.inc - $(TASM) $(ASMOPT80) -dBLD_SYS=SYS_$(SYS) $< $@ - -dbgmon.bin: dbgmon.asm std.asm ver.inc build.inc - -syscfg.bin: syscfg.asm std.asm build.inc ver.inc - -os.bin: $(CPBIN) $(DOSBIN) cbios.bin - cat $(CPBIN) $(DOSBIN) cbios.bin >>$@ - -rom0.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin romfill.bin dbgmon.bin os.bin hbfill.bin >>$@ - -# fixed 1/16/20113 dwg - added hbios.bin to end of cat list -rom1.bin: pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin - cat pgzero.bin bootrom.bin syscfg.bin loader.bin hbios.bin >>$@ - -$(OUTDIR)/$(ROMNAME).rom: rom0.bin rom1.bin $(ROMDISKFILES) $(OUTDIR)/$(ROMNAME).sys diskdefs - cp $(SRC)blank$(ROMSIZE)KB.dat RomDisk.tmp - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp $(ROMDSKFILES) 0: - $(CPMCP) -f rom$(ROMSIZE)KB RomDisk.tmp ../Output/$(ROMNAME).sys 0:$(SYS).sys - cat rom0.bin rom1.bin RomDisk.tmp >>$@ - -$(OUTDIR)/$(ROMNAME).com: bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin - cat bootapp.bin syscfg.bin loader.bin hbios.bin dbgmon.bin os.bin >>$@ - -$(OUTDIR)/$(ROMNAME).sys: prefix.bin os.bin - cat prefix.bin os.bin >>$@ - -ansi.asm: $(SRC)ansi.asm - cp $< $@ - $(CVT) $@ - -bdosb01.asm: $(SRC)bdosb01.asm - cp $< $@ - $(CVT) $@ - -hbios.asm: $(SRC)hbios.asm kbd.asm fd.asm ppide.asm n8v.asm n8chars.inc ppk.asm sd.asm tty.asm ansi.asm - cp $(SRC)hbios.asm $@ - $(CVT) $@ - -bootapp.asm: $(SRC)bootapp.asm - cp $< $@ - $(CVT) $@ - -bootrom.asm: $(SRC)bootrom.asm - cp $< $@ - $(CVT) $@ - -cbios.asm: $(SRC)cbios.asm - cp $< $@ - $(CVT) $@ - -ccpb03.asm: $(SRC)ccpb03.asm - cp $< $@ - $(CVT) $@ - -cnfgdata.inc: $(SRC)cnfgdata.inc - cp $< $@ - $(CVT) $@ - -##config_zeta.asm: $(SRC)config_zeta.asm -## cp $< $@ -## $(CVT) $@ - -config_$(CONFIG).asm: $(SRC)config_$(CONFIG).asm - cp $< $@ - $(CVT) $@ - -dbgmon.asm: $(SRC)dbgmon.asm - cp $< $@ - $(CVT) $@ - -diskdefs: $(SRC)diskdefs - cp $< $@ - $(CVT) $@ - -fd.asm: $(SRC)fd.asm - cp $< $@ - $(CVT) $@ - -fd_data.asm: $(SRC)fd_data.asm - cp $< $@ - $(CVT) $@ - -hbfill.asm: $(SRC)hbfill.asm - cp $< $@ - $(CVT) $@ - -ide_data.asm: $(SRC)ide_data.asm - cp $< $@ - $(CVT) $@ - -infolist.inc: $(SRC)infolist.inc - cp $< $@ - $(CVT) $@ - -kbd.asm: $(SRC)kbd.asm - cp $< $@ - $(CVT) $@ - -loader.asm: $(SRC)loader.asm util.asm - cp $(SRC)loader.asm $@ - $(CVT) $@ - -memmgr.asm: $(SRC)memmgr.asm - cp $< $@ - $(CVT) $@ - -n8chars.inc: $(SRC)n8chars.inc - cp $< $@ - $(CVT) $@ - -n8v.asm: $(SRC)n8v.asm - cp $< $@ - $(CVT) $@ - -pgzero.asm: $(SRC)pgzero.asm - cp $< $@ - $(CVT) $@ - -ppide.asm: $(SRC)ppide.asm - cp $< $@ - $(CVT) $@ - -ppide_data.asm: $(SRC)ppide_data.asm - cp $< $@ - $(CVT) $@ - -ppk.asm: $(SRC)ppk.asm - cp $< $@ - $(CVT) $@ - -ppp_data.asm: $(SRC)ppp_data.asm - cp $< $@ - $(CVT) $@ - -prefix.asm: $(SRC)prefix.asm - cp $< $@ - $(CVT) $@ - -prp_data.asm: $(SRC)prp_data.asm - cp $< $@ - $(CVT) $@ - -romfill.asm: $(SRC)romfill.asm - cp $< $@ - $(CVT) $@ - -sd.asm: $(SRC)sd.asm - cp $< $@ - $(CVT) $@ - -sd_data.asm: $(SRC)sd_data.asm - cp $< $@ - $(CVT) $@ - -std.asm: $(SRC)std.asm - cp $< $@ - $(CVT) $@ - -std-n8.inc: $(SRC)std-n8.inc - cp $< $@ - $(CVT) $@ - -std-n8vem.inc: $(SRC)std-n8vem.inc - cp $< $@ - $(CVT) $@ - -std-s100.inc: $(SRC)std-s100.inc - cp $< $@ - $(CVT) $@ - -std-s2i.inc: $(SRC)std-s2i.inc - cp $< $@ - $(CVT) $@ - -std-zeta.inc: $(SRC)std-zeta.inc - cp $< $@ - $(CVT) $@ - -syscfg.asm: $(SRC)syscfg.asm config_$(CONFIG).asm cnfgdata.inc - cp $< $@ - $(CVT) $@ - -tty.asm: $(SRC)tty.asm - cp $< $@ - $(CVT) $@ - -uart.asm: $(SRC)uart.asm - cp $< $@ - $(CVT) $@ - -util.asm: $(SRC)util.asm - cp $< $@ - $(CVT) $@ - -vdu.asm: $(SRC)vdu.asm - cp $< $@ - $(CVT) $@ - -ver.inc: $(SRC)ver.inc - cp $< $@ - $(CVT) $@ - -xio.asm: $(SRC)xio.asm - cp $< $@ - $(CVT) $@ - -clean: - rm -f *.tab *.TAB *.inc *.asm *.bin *.com *.img *.rom *.lst *.exp *.tmp - rm -f build.inc diskdefs *.inc - rm -f $(OUTDIR)/*.* diff --git a/branches/s100/XSource/README b/branches/s100/XSource/README deleted file mode 100644 index 4b40c7db..00000000 --- a/branches/s100/XSource/README +++ /dev/null @@ -1,2 +0,0 @@ -test file regarding commit problem - diff --git a/branches/s100/XSource/README.TXT b/branches/s100/XSource/README.TXT deleted file mode 100644 index 49f61a66..00000000 --- a/branches/s100/XSource/README.TXT +++ /dev/null @@ -1,6 +0,0 @@ -This build is experimental. Most likely it is working, -but you should be careful with it until it is verified. - -Douglas Goodall -Santa Maria -9/2012 diff --git a/branches/s100/XSource/bin/8051.H b/branches/s100/XSource/bin/8051.H deleted file mode 100644 index 59ebfa0e..00000000 --- a/branches/s100/XSource/bin/8051.H +++ /dev/null @@ -1,162 +0,0 @@ -;************************************************************* -;* TASM 8051/8052/80154 SFR BIT/BYTE MNEMONIC EQUATES LIST * -;************************************************************* - -P0 .equ 080H ;Port 0 -SP .equ 081H ;Stack pointer -DPL .equ 082H -DPH .equ 083H -PCON .equ 087H -TCON .equ 088H -TMOD .equ 089H -TL0 .equ 08AH -TL1 .equ 08BH -TH0 .equ 08CH -TH1 .equ 08DH -P1 .equ 090H ;Port 1 -SCON .equ 098H -SBUF .equ 099H -P2 .equ 0A0H ;Port 2 -IE .equ 0A8H -P3 .equ 0B0H ;Port 3 -IP .equ 0B8H -T2CON .equ 0C8H ;8052, 80154 only -RCAP2L .equ 0CAH ;8052, 80154 only -RCAP2H .equ 0CBH ;8052, 80154 only -TL2 .equ 0CCH ;8052, 80154 only -TH2 .equ 0CDH ;8052, 80154 only -PSW .equ 0D0H -ACC .equ 0E0H ;Accumulator -B .equ 0F0H ;Secondary Accumulator -IOCON .equ 0F8H ;80154 only - -;PORT 0 BITS -P0.0 .equ 080H ;Port 0 bit 0 -P0.1 .equ 081H ;Port 0 bit 1 -P0.2 .equ 082H ;Port 0 bit 2 -P0.3 .equ 083H ;Port 0 bit 3 -P0.4 .equ 084H ;Port 0 bit 4 -P0.5 .equ 085H ;Port 0 bit 5 -P0.6 .equ 086H ;Port 0 bit 6 -P0.7 .equ 087H ;Port 0 bit 7 - -;PORT 1 BITS -P1.0 .equ 090H ;Port 1 bit 0 -P1.1 .equ 091H ;Port 1 bit 1 -P1.2 .equ 092H ;Port 1 bit 2 -P1.3 .equ 093H ;Port 1 bit 3 -P1.4 .equ 094H ;Port 1 bit 4 -P1.5 .equ 095H ;Port 1 bit 5 -P1.6 .equ 096H ;Port 1 bit 6 -P1.7 .equ 097H ;Port 1 bit 7 - -;PORT 2 BITS -P2.0 .equ 0A0H ;Port 2 bit 0 -P2.1 .equ 0A1H ;Port 2 bit 1 -P2.2 .equ 0A2H ;Port 2 bit 2 -P2.3 .equ 0A3H ;Port 2 bit 3 -P2.4 .equ 0A4H ;Port 2 bit 4 -P2.5 .equ 0A5H ;Port 2 bit 5 -P2.6 .equ 0A6H ;Port 2 bit 6 -P2.7 .equ 0A7H ;Port 2 bit 7 - -;PORT 3 BITS -P3.0 .equ 0B0H ;Port 3 bit 0 -P3.1 .equ 0B1H ;Port 3 bit 1 -P3.2 .equ 0B2H ;Port 3 bit 2 -P3.3 .equ 0B3H ;Port 3 bit 3 -P3.4 .equ 0B4H ;Port 3 bit 4 -P3.5 .equ 0B5H ;Port 3 bit 5 -P3.6 .equ 0B6H ;Port 3 bit 6 -P3.7 .equ 0B7H ;Port 3 bit 7 - -;ACCUMULATOR BITS -ACC.0 .equ 0E0H ;Acc bit 0 -ACC.1 .equ 0E1H ;Acc bit 1 -ACC.2 .equ 0E2H ;Acc bit 2 -ACC.3 .equ 0E3H ;Acc bit 3 -ACC.4 .equ 0E4H ;Acc bit 4 -ACC.5 .equ 0E5H ;Acc bit 5 -ACC.6 .equ 0E6H ;Acc bit 6 -ACC.7 .equ 0E7H ;Acc bit 7 - -;B REGISTER BITS -B.0 .equ 0F0H ;Breg bit 0 -B.1 .equ 0F1H ;Breg bit 1 -B.2 .equ 0F2H ;Breg bit 2 -B.3 .equ 0F3H ;Breg bit 3 -B.4 .equ 0F4H ;Breg bit 4 -B.5 .equ 0F5H ;Breg bit 5 -B.6 .equ 0F6H ;Breg bit 6 -B.7 .equ 0F7H ;Breg bit 7 - -;PSW REGISTER BITS -P .equ 0D0H ;Parity flag -F1 .equ 0D1H ;User flag 1 -OV .equ 0D2H ;Overflow flag -RS0 .equ 0D3H ;Register bank select 1 -RS1 .equ 0D4H ;Register bank select 0 -F0 .equ 0D5H ;User flag 0 -AC .equ 0D6H ;Auxiliary carry flag -CY .equ 0D7H ;Carry flag - -;TCON REGISTER BITS -IT0 .equ 088H ;Intr 0 type control -IE0 .equ 089H ;Intr 0 edge flag -IT1 .equ 08AH ;Intr 1 type control -IE1 .equ 08BH ;Intr 1 edge flag -TR0 .equ 08CH ;Timer 0 run -TF0 .equ 08DH ;Timer 0 overflow -TR1 .equ 08EH ;Timer 1 run -TF1 .equ 08FH ;Timer 1 overflow - -;SCON REGISTER BITS -RI .equ 098H ;RX Intr flag -TI .equ 099H ;TX Intr flag -RB8 .equ 09AH ;RX 9th bit -TB8 .equ 09BH ;TX 9th bit -REN .equ 09CH ;Enable RX flag -SM2 .equ 09DH ;8/9 bit select flag -SM1 .equ 09EH ;Serial mode bit 1 -SM0 .equ 09FH ;Serial mode bit 0 - -;IE REGISTER BITS -EX0 .equ 0A8H ;External intr 0 -ET0 .equ 0A9H ;Timer 0 intr -EX1 .equ 0AAH ;External intr 1 -ET1 .equ 0ABH ;Timer 1 intr -ES .equ 0ACH ;Serial port intr -ET2 .equ 0ADH ;Timer 2 intr -;Reserved 0AEH Reserved -EA .equ 0AFH ;Global intr enable - -;IP REGISTER BITS -PX0 .equ 0B8H ;Priority level-External intr 0 -PT0 .equ 0B9H ;Priority level-Timer 0 intr -PX1 .equ 0BAH ;Priority level-External intr 1 -PT1 .equ 0BBH ;Priority level-Timer 1 intr -PS .equ 0BCH ;Priority level-Serial port intr -PT2 .equ 0BDH ;Priority level-Timer 2 intr -;Reserved 0BEH Reserved -PCT .equ 0BFH ;Global priority level - -;IOCON REGISTER BITS 80154 ONLY -ALF .equ 0F8H ;Power down port condition -P1HZ .equ 0F9H ;Port 1 control -P2HZ .equ 0FAH ;Port 2 control -P3HZ .equ 0FBH ;Port 3 control -IZC .equ 0FCH ;Pullup select -SERR .equ 0FDH ;Serial reception error -T32 .equ 0FEH ;32 bit timer config -WDT .equ 0FFH ;Watchdog config - -;T2CON REGISTER BITS 8052/80154 ONLY -CP/RL2 .equ 0C8H ;Timer 2 capture/reload flag -C/T2 .equ 0C9H ;Timer 2 timer/counter select -TR2 .equ 0CAH ;Timer 2 start/stop -EXEN2 .equ 0CBH ;Timer 2 external enable -TCLK .equ 0CCH ;TX clock flag -RCLK .equ 0CDH ;RX clock flag -EXF2 .equ 0CEH ;Timer 2 external flag -TF2 .equ 0CFH ;Timer 2 overflow - diff --git a/branches/s100/XSource/bin/COPYRIGH.TXT b/branches/s100/XSource/bin/COPYRIGH.TXT deleted file mode 100644 index 4d0d7f17..00000000 --- a/branches/s100/XSource/bin/COPYRIGH.TXT +++ /dev/null @@ -1,62 +0,0 @@ -The Telemark Assembler Copyright Notification - -The files on this disk are: -Copyright 1985-1993 by Speech Technology Incorporated, all rights reserved. -Copyright 1998,1999,2001 by Thomas N. Anderson , all rights reserved. - -The following files on this disk may be freely copied and shared with others: - -TASM.EXE - TASM Assembler, executable -TASM48.TAB - 8048 Instruction definition table -TASM51.TAB - 8051 Instruction definition table -TASM65.TAB - 6502 Instruction definition table -TASM85.TAB - 8085 Instruction definition table -TASM80.TAB - Z80 Instruction definition table -TASM05.TAB - 6805 Instruction definition table -TASM68.TAB - 6800/6801/68HC11 Instruction definition table -TASM3210.TAB - TMS32010 Instruction definition table -TASM3225.TAB - TMS32025 Instruction definition table -TASM70.TAB - TMS7000 Instruction definition table -TASMMAN.HTM - TASM Documentation (HTML) -TASMTABS.HTM - TASM Documentation on individual tables (HTML) -TEST*.ASM - TASM test cases (one for each table) -TESTTABS.BAT - Batch script to execute the test cases -8051.H - Useful register definitions for the 8051 -MOTO.H - Useful directive definitions for Motorola compatibility -README.TXT - Brief Explanation of Disk contents -COPYRIGH.TXT - Copyright notice -ORDERFRM.TXT - Registration Form -ORDERFRM.HTM - Registration Form (HTML) -RELNOTES.TXT - Release notes. - -Although you may freely copy the above files, TASM is not 'free' or -'public domain'. It is copyrighted material which can be copied and -evaluated by people without registration, but those that use it on a -regular basis must register (see the ORDERFRM.TXT or ORDERFRM.HTM files). - -The following files are to be copied only with the following -restrictions: The owner of this software may make as many copies of -the following as is deemed necessary as long as no possibility exists -for the software (or derivitive products) to be in use on more than -one machine at a time. Or, if a site license has been purchased, the -software can only be used on machines at that site. - - TASM.C - TASMMAIN.C - MACRO.C - PARSE.C - STR.C - LOOKUP.C - WRTOBJ.C - FNAME.C - WRTOBJ.C - ERRLOG.C - TASM.H - - - Thomas N. Anderson - Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - - email: andersontn@acm.org diff --git a/branches/s100/XSource/bin/CPMCHATTR b/branches/s100/XSource/bin/CPMCHATTR deleted file mode 100755 index f07ba18a..00000000 Binary files a/branches/s100/XSource/bin/CPMCHATTR and /dev/null differ diff --git a/branches/s100/XSource/bin/CPMCHMOD b/branches/s100/XSource/bin/CPMCHMOD deleted file mode 100755 index d27c2158..00000000 Binary files a/branches/s100/XSource/bin/CPMCHMOD and /dev/null differ diff --git a/branches/s100/XSource/bin/CPMCP b/branches/s100/XSource/bin/CPMCP deleted file mode 100755 index 9006feb7..00000000 Binary files a/branches/s100/XSource/bin/CPMCP and /dev/null differ diff --git a/branches/s100/XSource/bin/CPMLS b/branches/s100/XSource/bin/CPMLS deleted file mode 100755 index 63f1a439..00000000 Binary files a/branches/s100/XSource/bin/CPMLS and /dev/null differ diff --git a/branches/s100/XSource/bin/CPMRM b/branches/s100/XSource/bin/CPMRM deleted file mode 100755 index f41e762c..00000000 Binary files a/branches/s100/XSource/bin/CPMRM and /dev/null differ diff --git a/branches/s100/XSource/bin/CVT2MAC b/branches/s100/XSource/bin/CVT2MAC deleted file mode 100755 index a2443c15..00000000 Binary files a/branches/s100/XSource/bin/CVT2MAC and /dev/null differ diff --git a/branches/s100/XSource/bin/MAKE b/branches/s100/XSource/bin/MAKE deleted file mode 100755 index 58e9f069..00000000 Binary files a/branches/s100/XSource/bin/MAKE and /dev/null differ diff --git a/branches/s100/XSource/bin/MOTO.H b/branches/s100/XSource/bin/MOTO.H deleted file mode 100644 index 989689b2..00000000 --- a/branches/s100/XSource/bin/MOTO.H +++ /dev/null @@ -1,20 +0,0 @@ -; A few handy defines to make TASM more like typcial -; motorola syntax - -.MSFIRST ; Most Significant byte first - -#define EQU .EQU -#define ORG .ORG -#define RMB .BLOCK -#define FCB .BYTE -#define FCC .TEXT -#define FDB .WORD - -#define equ .EQU -#define org .ORG -#define rmb .BLOCK -#define fcb .BYTE -#define fcc .TEXT -#define fdb .WORD - - diff --git a/branches/s100/XSource/bin/Makefile b/branches/s100/XSource/bin/Makefile deleted file mode 100644 index 2fb0b6be..00000000 --- a/branches/s100/XSource/bin/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh -#rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -#rem $Id: testtabs.bat 1.3 1998/02/25 12:27:04 toma Exp $ -#rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -#rem Run TASM on all the table test files. Those that have -#rem extended instuctions use the -x option. - -AS = ./TASM -OBJS = TEST48.obj TEST65.obj TEST51.obj TEST85.obj TESTZ80.obj -OBJS2= TEST05.obj TEST3210.obj TEST3225.obj TEST68.obj TEST70.obj TEST96.obj - -all: $(OBJS) $(OBJS2) -# ./TASM -48 -x TEST48.ASM -# ./TASM -65 -x TEST65.ASM -# ./TASM -51 TEST51.ASM -# ./TASM -85 TEST85.ASM -# ./TASM -80 -x TESTZ80.ASM -# ./TASM -05 -x TEST05.ASM -# ./TASM -3210 TEST3210.ASM -# ./TASM -3225 TEST3225.ASM -# ./TASM -68 -x TEST68.ASM -# ./TASM -70 TEST70.ASM -# ./TASM -96 -x TEST96.ASM - -TEST48.obj: TEST48.ASM - $(AS) -48 -x $< - -TEST65.obj: TEST65.ASM - $(AS) -65 -x $< - -TEST51.obj: TEST51.ASM - $(AS) -51 $< - -TEST85.obj: TEST85.asm - $(AS) -85 $< - -TESTZ80.obj: TESTZ80.ASM - $(AS) -80 -x $< - -TEST05.obj: TEST05.ASM - $(AS) -05 -x $< - -TEST3210.obj: TEST3210.ASM - $(AS) -3210 $< - -TEST3225.obj: TEST3225.ASM - $(AS) -3225 $< - -TEST68.obj: TEST68.ASM - $(AS) -68 -x $< - -TEST70.obj: TEST70.ASM - $(AS) -70 $< - -TEST96.obj: TEST96.ASM - $(AS) -96 -x $< - -clean: - rm -r -f *.obj - rm -r -f *.lst - rm -r -f *.sym - - diff --git a/branches/s100/XSource/bin/ORDERFRM.HTM b/branches/s100/XSource/bin/ORDERFRM.HTM deleted file mode 100644 index f36aa73c..00000000 --- a/branches/s100/XSource/bin/ORDERFRM.HTM +++ /dev/null @@ -1,82 +0,0 @@ - - - -Telemark Cross Assembler (TASM) Order Form - -

TASM Order Form

-

To order TASM, print this page, fill in the details and mail to SVS at:

-

Squak Valley Software
837 Front Street South
Issaquah, WA 98027
USA

-

TASM registration provides the user:

-
    -
  • Most Recent TASM Distribution Disk (includes tables for all supported -processor families)
  • -
  • TASM Source code (in C)
  • -
  • Bound TASM Manual
  • -
  • Telephone Support
  • -
  • Knowledge that they are supporting the development of useful but -inexpensive software
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Item DescriptionUnit PriceAmount Extended
TASM 3.2 Registration $40______________________
TASM 3.2 Site Registration$90______________________
TASM 3.2 Update for registered users$10______________________
Subtotal______________________
Tax (Washington State residents add 8.6%)______________________
Billing Fee (for orders not accompanied by payment)$10______________________
Foreign postage and handling$10______________________
Total______________________
-
    -
  • All payments must be in US funds drawn on a US bank (No credit card -payments)
  • -
  • Orders outside North America please add the indicated foreign postage and -handling.
  • -
  • Purchase orders allowed from North America only (all others must be -prepaid).
-

Ship To:

- - - - - - - - - - - - - - - -
Name____________________________________
Company ___________________________________
Street Address____________________________________
City, State/Province, Postal Code____________________________________
Country ____________________________________
diff --git a/branches/s100/XSource/bin/ORDERFRM.TXT b/branches/s100/XSource/bin/ORDERFRM.TXT deleted file mode 100644 index 6e979430..00000000 --- a/branches/s100/XSource/bin/ORDERFRM.TXT +++ /dev/null @@ -1,55 +0,0 @@ -ORDERING INFORMATION (TASM Version 3.2) - -TASM is distributed as shareware. The shareware portion of the -product may be freely copied and used for evaluation purposes. Use -of TASM beyond a reasonable evaluation period requires registration. -Registered users receive the following benefits: - - 1. The recent version of TASM. - 2. TASM source code (in C). - 3. Bound TASM manual. - 4. Telephone support. - 5. Knowledge that they are supporting the development of - useful but inexpensive software. - -DESCRIPTION UNIT PRICE PRICE --------------------------------------------------------------------- - -TASM Registration (TASM disk, manual, & source) $40.00 _______ - -TASM Site Registration (for sites with multiple 90.00 _______ - users. Includes same materials as above.) - -TASM User's Manual (included above) 10.00 _______ - -TASM update for registered users 10.00 _______ - (latest disk (with source), and manual) - -Subtotal _______ - -Tax (Washington state residents add 8.6%) _______ - -Billing fee (for orders not accompanied by check) 10.00 _______ - -Foreign postage (outside North America) add $10.00 _______ - (Foreign orders must be in US funds drawn on a US bank) - -TOTAL (post paid) _______ - - -Which processors are of primary interest to you? __________________ -(This is for our information only. You will -receive all current TASM tables). - -Shipping Address: - -______________________________________________ - -______________________________________________ - -______________________________________________ - -Send check or money order (no credit cards) to: Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - diff --git a/branches/s100/XSource/bin/README-MAC.PNG b/branches/s100/XSource/bin/README-MAC.PNG deleted file mode 100644 index d02cbe38..00000000 Binary files a/branches/s100/XSource/bin/README-MAC.PNG and /dev/null differ diff --git a/branches/s100/XSource/bin/README.1ST b/branches/s100/XSource/bin/README.1ST deleted file mode 100644 index 26172343..00000000 --- a/branches/s100/XSource/bin/README.1ST +++ /dev/null @@ -1,18 +0,0 @@ -This is the registered distribution disk for TASM - the Telemark Assembler. -The files on the disk are: - -Readme.1st - This file -Tasm32.zip - TASM distribution archive, Version 3.2 - -To extract the archive use pkunzip or pkzip for windows and extract -into the desired directory for TASM. - -See the README.TXT file after extraction. -See the BUILD.TXT file for notes on building from the source archive. - - Thomas N. Anderson - Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - andersontn@acm.org - diff --git a/branches/s100/XSource/bin/README.TXT b/branches/s100/XSource/bin/README.TXT deleted file mode 100644 index d6534ee6..00000000 --- a/branches/s100/XSource/bin/README.TXT +++ /dev/null @@ -1,46 +0,0 @@ -This is the shareware distribution disk for TASM - a table driven -assembler. The files on the disk include: - -TASM.EXE - TASM Assembler, executable -TASM48.TAB - 8048 Instruction definition table -TASM51.TAB - 8051 Instruction definition table -TASM65.TAB - 6502 Instruction definition table -TASM85.TAB - 8085 Instruction definition table -TASM80.TAB - Z80 Instruction definition table -TASM05.TAB - 6805 Instruction definition table -TASM3210.TAB - TMS32010 Instruction definition table -TASM3225.TAB - TMS32025 Instruction definition table -TASM68.TAB - 6800/6801 Instruction definition table -TASM70.TAB - TMS7000 Instruction definition table -TASM96.TAB - 8096 Instruction definition table -TEST*.ASM - TASM test files (one for each table). -TESTTABS.BAT - Batch script to execute TASM for each test case. -8051.H - Useful register definitions for the 8051 -MOTO.H - Useful directive definitions for Motorola compatibility -TASMMAN.HTM - TASM User's Manual (HTML) -TASMTABS.HTM - TASM Table Description Manual (HTML) -README.TXT - Brief Explanation of Disk contents -COPYRIGH.TXT - Copyright notice -ORDERFRM.TXT - Order Form (plain text) -ORDERFRM.HTM - Order Form (HTML) - -For a brief discription of how to run TASM, execute TASM with no command -line parameters. - -If you find TASM useful, why not register? Unregistered use of TASM -beyond a 30 day evaluation period is a violation of the license. -For the $40.00 registration fee you get: - - 1. Latest version of TASM. - 2. Source code (in C). - 3. Bound Manual. - 4. email support. - -To register, use the form on the disk (ORDERFRM.TXT), or just send -$40.00 check or money order to: - - Thomas N. Anderson - Squak Valley Software - 837 Front Street South - Issaquah, WA 98027 - andersontn@acm.org diff --git a/branches/s100/XSource/bin/RELNOTES.TXT b/branches/s100/XSource/bin/RELNOTES.TXT deleted file mode 100644 index 2a195c85..00000000 --- a/branches/s100/XSource/bin/RELNOTES.TXT +++ /dev/null @@ -1,213 +0,0 @@ -TASM RELEASE NOTES [September 2001] - -RELEASE DATE/VERSION DESCRIPTION ------------------------------------------------------------------------ -10/01/85 Version 2.0 First version with external table def files. - -01/01/86 Version 2.1 Added '*=' and '=' directives as - alternatives to .ORG and .EQU (for - more complete MOS Technology compatibility). - Enhanced parsing algorithm so it can - deal with more than one variable expression. - Added -d option - -02/14/86 Version 2.2 Modified so instruction set definition - tables don't need to be compiled in. - Added 8051 tables. - Increased the number of labels allowed. - -03/31/87 Version 2.3 Fixed bug that prevented location 0xffff - from being used and written to object file. - Most changes in wrtobj() and pr_hextab(). - -05/01/87 Version 2.4 Added multiple byte opcode support. - Added shift/or operation capability to - args from instruction set definition table. - Converted to MS C version 3.0 - Added hashing to instruction set table - lookups to speed up. - -11/01/87 Version 2.5 Added DB and DW directives. - Added escape capability in TEXT strings. - Fixed inst_lookup function to treat the - multiple wild card case a little better - Added 8080/8085 and Z80 tables. - Added sorting on label table. - Increased size of read buffer. - Speed enhancements. - Added DEFCONT (macro continuation) directive. - Converted to Microsoft C 5.0 compiler. - Added 6805 table (and related modops). - Added Z80 bit modop. - Minor speed up. - Fixed bug that enters infinite loop - when a macro invocation has no closing paren. - Added some three arg MODOPs. - -8/15/88 Version 2.6.1 Added CODES/NOCODES directives - Fixed bug preventing directives in multiple - statement lines. - 2.6.2 Added COMB_NIBBLE and COMB_NIBBLE_SWAP MODOPS - -2/1/89 Version 2.7 Removed ad hoc heap and now use malloc() - Added MSFIRST and LSFIRST directives. - Added EXPORT directive. - Added symbol table file (-s flag). - Added NSEG/CSEG/BSEG/DSEG/XSEG directives - and the SYM/AVSYM directives to support - the Avocet avsim51 simulator. - Added support for TMS320. - Added -r flag to set read buffer size. - Converted expression evaluation from - signed 16 bit to signed 32 bit (enabling - apparent ability to use signed or unsigned - 16 bit values). - -4/20/89 Version 2.7.1 Return 0x20000 for undefined labels so that - (label+x) type stuff won't confuse zero - page addressing. - Added duplicate label error message on pass 1. - -6/20/89 Version 2.7.2 Improved macro expansion capability. - No expansion in comments. - Context sensitive identifiers. - Revised exit codes. - -6/27/89 Version 2.7.3 Added -a flag for strict error checking: - (1) No outer parens around expressions. - (2) Error message if unused argbytes remain - (3) Duplicate labels - Fixed so ']' can terminate expressions. - Removed parse() from tasm.c - -8/19/89 Version 2.7.4 Added Motorola hex object format. - Fixed bug that complained when \ immediately - followed a opcode with no args. - Slightly improved error reporting (Errorbuf). - -10/31/89 Version 2.7.5 Added TMS7000 support. - Fixed argv[] bug (only dimensioned to 10 in pass1. - -12/23/89 Version 2.7.6 Improved handling of % (modulo vs binary - prefix ambiguity). - Fixed list so lines with more than - 6 bytes go on second line. - -03/04/90 Version 2.7.7 Fixed bug that left off 2 bytes if ORG - went backwards and all 64K was used. - Added a command line option to ignore - case on labels. - Added a couple MODOP rules for TMS9900. - Allow double quoted text strings for BYTE. - -04/15/90 Version 2.7.8 Fixed expression evaluator bug (paren popping) - and changed expression evaluator to a more - conventional left to right evaluation order. - Added TURBOC ifdef's (from Lance Jump). - -08/20/90 Version 2.8 Primarily a documentation update. - Added error check for AJMP/ACALL off of - current 2K block (8051). - -10/15/90 Version 2.8.1 Minor speed up in label searching. - Fixed word addressing for TMS320 - Version 2.8.2 Local labels. - More label table format options (long form - suppress local labels). - -11/30/90 Version 2.8.3 Turbo C conversion. - DS directive added. - -12/27/90 Version 2.8.4 Added COMMENTCHAR directive to change the - comment indicator in the first column. - This was done to support the assembly - files from the small C compiler (sc11) - for the 68CH11. - -02/14/91 Version 2.8.5 Added LOCALLABELCHAR directive to - override the default "_" as the - prefix for local labels. - -03/18/91 Version 2.8.6 Added some MODOPs in support of TMS320C25 - -04/20/91 Version 2.8.7 Fixed sign extend bug in CSWAP modop. - Increased MAXLABS to 10000 for big version. - -05/05/91 Version 2.8.8 Fixed pointer bug in debug output in sort_labels(). - -05/20/91 Version 2.9 TMS320C25 table along with some MODOP enhancements - for it. - TASMTABS.DOC updated (but not TASM.DOC) - -08/09/91 Version 2.9.1 Nested conditionals. - -04/01/92 Version 2.9.2 Fixed long label clobber problem in - find_label() and save_label. Syntax - errors could result in a comment line - after an instruction being lumped together - with a label resulting in a long label. - The label functions were not testing for - labels that exceed the specified size. - Added CHK directive. - Added REL3 MODOD to support uPD75xxx. - Delinting and more ANSIfication. - Modifications due to feedback from B Provo: - Added FILL directive. - Allow multiple labels for EXPORT directive. - Allow address with END directive. - TASM.DOC update - -11/25/92 Version 2.9.3 Improved error reporting for mismatched quotes. - Disallow the single quote character constants. - Convert to BCC++ 3.1 - Provide filename,linenum on all error messages. - Modify format of error messages for compatibility - with the Brief editor. - Added ECHO directive to send output to console. - Performance improvements in macro processing. - "Type Safe" conversion (compatible with C++). - Improved error reporting for imbalanced ifdefs. - - -01/29/93 Version 2.9.4 Added rules for 8096 (I1,I2,I3,I4,I5,I6). - Generate error message on forward reference - in EQUate statements. - Eliminated -a option for enabling the detection - of branches of 2K page for 8051. This - is now built into the table. - Allow white space in double quotes for BYTE - directive. This previously worked for TEXT, - but not BYTE. - Fixed defect with Z80 4 byte indexed instructions. - Fixed macro defect. If the macro definition has - args but the invocation does not some garbage - gets expanded into the source line. - Z80 OTDR opcode was incorrect. - Z80 IN0/OUT0/INA instructions did not require - the parens around the args. - Some experimental support for windows verson of TASM. - -10/24/93 Version 3.0 Documentation update. TASM.DOC, TASMTABS.DOC - and RELNOTES.DOC updated, but the functionality - remains unchanged from version 2.9.4. - -06/16/94 Version 3.0.1 Multiple macros on the same line. - Fixed problem with -c with >8000h bytes used goes bonkers - Corrected word addressing problem for BLOCK/DS directives. - Allow escaped quotes in TEXT strings. - -11/30/97 Version 3.1 LINUX support. - Protect mode version (tasmp) with better memory - management (more labels allowed, etc.) - Added an 8096 table. - Added Logical NOT unary operator. - Added an object file format with word address - -09/01/01 version 3.2 Increased LINESIZ to 512 to enable use of longer macros. - Eliminated -r command line option (to set - read buffer size - Now obsolete.) - Improved list() function to put a max of - six bytes per line to avoid problems with - directives that generate large blocks of - object code (i.e. .FILL). - Built as a 32 bit version using MS C++ 6.0 diff --git a/branches/s100/XSource/bin/TASM b/branches/s100/XSource/bin/TASM deleted file mode 100755 index 4557f651..00000000 Binary files a/branches/s100/XSource/bin/TASM and /dev/null differ diff --git a/branches/s100/XSource/bin/TASM05.TAB b/branches/s100/XSource/bin/TASM05.TAB deleted file mode 100644 index 1072d3dc..00000000 --- a/branches/s100/XSource/bin/TASM05.TAB +++ /dev/null @@ -1,215 +0,0 @@ -"TASM 6805 Assembler. " -/*************************************************************************** -/* $Id -/*************************************************************************** -/* This is the instruction set definition table for the 6805 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, April 1988. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC #* A9 2 NOP 1 -ADC ,X F9 1 NOP 1 -ADC *,X D9 3 MZERO 1 -ADC * C9 3 MZERO 1 - -ADD #* AB 2 NOP 1 -ADD ,X FB 1 NOP 1 -ADD *,X DB 3 MZERO 1 -ADD * CB 3 MZERO 1 - -AND #* A4 2 NOP 1 -AND ,X F4 1 NOP 1 -AND *,X D4 3 MZERO 1 -AND * C4 3 MZERO 1 - -ASLA "" 48 1 NOP 1 -ASLX "" 58 1 NOP 1 -ASL ,X 78 1 NOP 1 -ASL *,X 68 2 NOP 1 -ASL * 38 2 NOP 1 - -ASRA "" 47 1 NOP 1 -ASRX "" 57 1 NOP 1 -ASR ,X 77 1 NOP 1 -ASR *,X 67 2 NOP 1 -ASR * 37 2 NOP 1 - -BCC * 24 2 R1 1 -BCLR *,* 11 2 MBIT 1 -BCS * 25 2 R1 1 -BEQ * 27 2 R1 1 -BHCC * 28 2 R1 1 -BHCS * 29 2 R1 1 -BHI * 22 2 R1 1 -BHS * 24 2 R1 1 -BIH * 2F 2 R1 1 -BIL * 2E 2 R1 1 - -BIT #* A5 2 NOP 1 -BIT ,X F5 1 NOP 1 -BIT *,X D5 3 MZERO 1 -BIT * C5 3 MZERO 1 - -BLO * 25 2 R1 1 -BLS * 23 2 R1 1 -BMC * 2C 2 R1 1 -BMI * 2B 2 R1 1 -BMS * 2D 2 R1 1 -BNE * 26 2 R1 1 -BPL * 2A 2 R1 1 -BRA * 20 2 R1 1 - -BRCLR *,*,* 01 3 MBIT 1 -BRN * 21 2 R1 1 -BRSET *,*,* 00 3 MBIT 1 -BSET *,* 10 2 MBIT 1 -BSR * AD 2 R1 1 - -CLC "" 98 1 NOP 1 -CLI "" 9A 1 NOP 1 - -CLRA "" 4F 1 NOP 1 -CLRX "" 5F 1 NOP 1 -CLR ,X 7F 1 NOP 1 -CLR *,X 6F 2 NOP 1 -CLR * 3F 2 NOP 1 - -CMP #* A1 2 NOP 1 -CMP ,X F1 1 NOP 1 -CMP *,X D1 3 MZERO 1 -CMP * C1 3 MZERO 1 - -CMPX #* A3 2 NOP 1 /* equivalent to CPX */ -CMPX ,X F3 1 NOP 1 -CMPX *,X D3 3 MZERO 1 -CMPX * C3 3 MZERO 1 - -COMA "" 43 1 NOP 1 -COMX "" 53 1 NOP 1 -COM ,X 73 1 NOP 1 -COM *,X 63 2 NOP 1 -COM * 33 2 NOP 1 - -CPX #* A3 2 NOP 1 -CPX ,X F3 1 NOP 1 -CPX *,X D3 3 MZERO 1 -CPX * C3 3 MZERO 1 - -DECA "" 4A 1 NOP 1 -DECX "" 5A 1 NOP 1 -DEX "" 5A 1 NOP 1 -DEC ,X 7A 1 NOP 1 -DEC *,X 6A 2 NOP 1 -DEC * 3A 2 NOP 1 - -EOR #* A8 2 NOP 1 -EOR ,X F8 1 NOP 1 -EOR *,X D8 3 MZERO 1 -EOR * C8 3 MZERO 1 - -INCA "" 4C 1 NOP 1 -INCX "" 5C 1 NOP 1 -INX "" 5C 1 NOP 1 -INC ,X 7C 1 NOP 1 -INC *,X 6C 2 NOP 1 -INC * 3C 2 NOP 1 - -JMP ,X FC 1 NOP 1 -JMP *,X DC 3 MZERO 1 -JMP * CC 3 MZERO 1 - -JSR ,X FD 1 NOP 1 -JSR *,X DD 3 MZERO 1 -JSR * CD 3 MZERO 1 - -LDA #* A6 2 NOP 1 -LDA ,X F6 1 NOP 1 -LDA *,X D6 3 MZERO 1 -LDA * C6 3 MZERO 1 - -LDX #* AE 2 NOP 1 -LDX ,X FE 1 NOP 1 -LDX *,X DE 3 MZERO 1 -LDX * CE 3 MZERO 1 - -LSLA "" 48 1 NOP 1 -LSLX "" 58 1 NOP 1 -LSL ,X 78 1 NOP 1 -LSL *,X 68 2 NOP 1 -LSL * 38 2 NOP 1 - -LSRA "" 44 1 NOP 1 -LSRX "" 54 1 NOP 1 -LSR ,X 74 1 NOP 1 -LSR *,X 64 2 NOP 1 -LSR * 34 2 NOP 1 - -MUL "" 42 1 NOP 4 /* HC05C4 only */ - -NEGA "" 40 1 NOP 1 -NEGX "" 50 1 NOP 1 -NEG ,X 70 1 NOP 1 -NEG *,X 60 2 NOP 1 -NEG * 30 2 NOP 1 - -NOP "" 9D 1 NOP 1 - -ORA #* AA 2 NOP 1 -ORA ,X FA 1 NOP 1 -ORA *,X DA 3 MZERO 1 -ORA * CA 3 MZERO 1 - -ROLA "" 49 1 NOP 1 -ROLX "" 59 1 NOP 1 -ROL ,X 79 1 NOP 1 -ROL *,X 69 2 NOP 1 -ROL * 39 2 NOP 1 - -RORA "" 46 1 NOP 1 -RORX "" 56 1 NOP 1 -ROR ,X 76 1 NOP 1 -ROR *,X 66 2 NOP 1 -ROR * 36 2 NOP 1 - -RSP "" 9C 1 NOP 1 -RTI "" 80 1 NOP 1 -RTS "" 81 1 NOP 1 - -SBC #* A2 2 NOP 1 -SBC ,X F2 1 NOP 1 -SBC *,X D2 3 MZERO 1 -SBC * C2 3 MZERO 1 - -SEC "" 99 1 NOP 1 -SEI "" 9B 1 NOP 1 - -STA ,X F7 1 NOP 1 -STA *,X D7 3 MZERO 1 -STA * C7 3 MZERO 1 - -STOP "" 8E 1 NOP 2 /* M146805 CMOS only */ - -STX ,X FF 1 NOP 1 -STX *,X DF 3 MZERO 1 -STX * CF 3 MZERO 1 - -SUB #* A0 2 NOP 1 -SUB ,X F0 1 NOP 1 -SUB *,X D0 3 MZERO 1 -SUB * C0 3 MZERO 1 - -SWI "" 83 1 NOP 1 - -TAX "" 97 1 NOP 1 - -TSTA "" 4D 1 NOP 1 -TSTX "" 5D 1 NOP 1 -TST ,X 7D 1 NOP 1 -TST *,X 6D 2 NOP 1 -TST * 3D 2 NOP 1 - -TXA "" 9F 1 NOP 1 - -WAIT "" 8F 1 NOP 2 /* M146805 CMOS only */ - diff --git a/branches/s100/XSource/bin/TASM180.TAB b/branches/s100/XSource/bin/TASM180.TAB deleted file mode 100644 index a3dd5839..00000000 --- a/branches/s100/XSource/bin/TASM180.TAB +++ /dev/null @@ -1,594 +0,0 @@ -"TASM Z180 Assembler. " -/**************************************************************************** -/* $Id: tasm80.tab 1.2 1998/02/28 14:31:22 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the Z80 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Carl A. Wall, VE3APY. -/* -/* Class bits assigned as follows: -/* Bit-0 = Z80 (base instruction set) -/* Bit-1 = HD64180 (extended instructions) -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OP BYTES RULE CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC A,(HL) 8E 1 NOP 1 -ADC A,(IX*) 8EDD 3 ZIX 1 -ADC A,(IY*) 8EFD 3 ZIX 1 -ADC A,A 8F 1 NOP 1 -ADC A,B 88 1 NOP 1 -ADC A,C 89 1 NOP 1 -ADC A,D 8A 1 NOP 1 -ADC A,E 8B 1 NOP 1 -ADC A,H 8C 1 NOP 1 -ADC A,L 8D 1 NOP 1 -ADC A,* CE 2 NOP 1 -ADC HL,BC 4AED 2 NOP 1 -ADC HL,DE 5AED 2 NOP 1 -ADC HL,HL 6AED 2 NOP 1 -ADC HL,SP 7AED 2 NOP 1 - -ADD A,(HL) 86 1 NOP 1 -ADD A,(IX*) 86DD 3 ZIX 1 -ADD A,(IY*) 86FD 3 ZIX 1 -ADD A,A 87 1 NOP 1 -ADD A,B 80 1 NOP 1 -ADD A,C 81 1 NOP 1 -ADD A,D 82 1 NOP 1 -ADD A,E 83 1 NOP 1 -ADD A,H 84 1 NOP 1 -ADD A,L 85 1 NOP 1 -ADD A,* C6 2 NOP 1 -ADD HL,BC 09 1 NOP 1 -ADD HL,DE 19 1 NOP 1 -ADD HL,HL 29 1 NOP 1 -ADD HL,SP 39 1 NOP 1 -ADD IX,BC 09DD 2 NOP 1 -ADD IX,DE 19DD 2 NOP 1 -ADD IX,IX 29DD 2 NOP 1 -ADD IX,SP 39DD 2 NOP 1 -ADD IY,BC 09FD 2 NOP 1 -ADD IY,DE 19FD 2 NOP 1 -ADD IY,IY 29FD 2 NOP 1 -ADD IY,SP 39FD 2 NOP 1 - -AND (HL) A6 1 NOP 1 -AND (IX*) A6DD 3 ZIX 1 -AND (IY*) A6FD 3 ZIX 1 -AND A A7 1 NOP 1 -AND B A0 1 NOP 1 -AND C A1 1 NOP 1 -AND D A2 1 NOP 1 -AND E A3 1 NOP 1 -AND H A4 1 NOP 1 -AND L A5 1 NOP 1 -AND * E6 2 NOP 1 - -BIT *,(HL) 46CB 2 ZBIT 1 -BIT *,(IX*) CBDD 4 ZBIT 1 0 4600 -BIT *,(IY*) CBFD 4 ZBIT 1 0 4600 -BIT *,A 47CB 2 ZBIT 1 -BIT *,B 40CB 2 ZBIT 1 -BIT *,C 41CB 2 ZBIT 1 -BIT *,D 42CB 2 ZBIT 1 -BIT *,E 43CB 2 ZBIT 1 -BIT *,H 44CB 2 ZBIT 1 -BIT *,L 45CB 2 ZBIT 1 - -CALL C,* DC 3 NOP 1 -CALL M,* FC 3 NOP 1 -CALL NC,* D4 3 NOP 1 -CALL NZ,* C4 3 NOP 1 -CALL P,* F4 3 NOP 1 -CALL PE,* EC 3 NOP 1 -CALL PO,* E4 3 NOP 1 -CALL Z,* CC 3 NOP 1 -CALL * CD 3 NOP 1 - -CCF "" 3F 1 NOP 1 - -CP (HL) BE 1 NOP 1 -CP (IX*) BEDD 3 ZIX 1 -CP (IY*) BEFD 3 ZIX 1 -CP A BF 1 NOP 1 -CP B B8 1 NOP 1 -CP C B9 1 NOP 1 -CP D BA 1 NOP 1 -CP E BB 1 NOP 1 -CP H BC 1 NOP 1 -CP L BD 1 NOP 1 -CP * FE 2 NOP 1 -CPD "" A9ED 2 NOP 1 -CPDR "" B9ED 2 NOP 1 -CPIR "" B1ED 2 NOP 1 -CPI "" A1ED 2 NOP 1 -CPL "" 2F 1 NOP 1 - -DAA "" 27 1 NOP 1 - -DEC (HL) 35 1 NOP 1 -DEC (IX*) 35DD 3 ZIX 1 -DEC (IY*) 35FD 3 ZIX 1 -DEC A 3D 1 NOP 1 -DEC B 05 1 NOP 1 -DEC BC 0B 1 NOP 1 -DEC C 0D 1 NOP 1 -DEC D 15 1 NOP 1 -DEC DE 1B 1 NOP 1 -DEC E 1D 1 NOP 1 -DEC H 25 1 NOP 1 -DEC HL 2B 1 NOP 1 -DEC IX 2BDD 2 NOP 1 -DEC IY 2BFD 2 NOP 1 -DEC L 2D 1 NOP 1 -DEC SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -DJNZ * 10 2 R1 1 - -EI "" FB 1 NOP 1 -EX (SP),HL E3 1 NOP 1 -EX (SP),IX E3DD 2 NOP 1 -EX (SP),IY E3FD 2 NOP 1 -EX AF,AF' 08 1 NOP 1 -EX DE,HL EB 1 NOP 1 -EXX "" D9 1 NOP 1 -HALT "" 76 1 NOP 1 - -IM 0 46ED 2 NOP 1 -IM 1 56ED 2 NOP 1 -IM 2 5EED 2 NOP 1 - -/* Alternate form of above -IM0 46ED 2 NOP 1 -IM1 56ED 2 NOP 1 -IM2 5EED 2 NOP 1 - -IN A,(C) 78ED 2 NOP 1 -IN B,(C) 40ED 2 NOP 1 -IN C,(C) 48ED 2 NOP 1 -IN D,(C) 50ED 2 NOP 1 -IN E,(C) 58ED 2 NOP 1 -IN H,(C) 60ED 2 NOP 1 -IN L,(C) 68ED 2 NOP 1 - -IN A,(*) DB 2 NOP 1 - -IN0 A,(*) 38ED 3 NOP 1 -IN0 B,(*) 00ED 3 NOP 1 -IN0 C,(*) 08ED 3 NOP 1 -IN0 D,(*) 10ED 3 NOP 1 -IN0 E,(*) 18ED 3 NOP 1 -IN0 H,(*) 20ED 3 NOP 1 -IN0 L,(*) 28ED 3 NOP 1 - -INC (HL) 34 1 NOP 1 -INC (IX*) 34DD 3 ZIX 1 -INC (IY*) 34FD 3 ZIX 1 -INC A 3C 1 NOP 1 -INC B 04 1 NOP 1 -INC BC 03 1 NOP 1 -INC C 0C 1 NOP 1 -INC D 14 1 NOP 1 -INC DE 13 1 NOP 1 -INC E 1C 1 NOP 1 -INC H 24 1 NOP 1 -INC HL 23 1 NOP 1 -INC IX 23DD 2 NOP 1 -INC IY 23FD 2 NOP 1 -INC L 2C 1 NOP 1 -INC SP 33 1 NOP 1 - - -IND "" AAED 2 NOP 1 -INDR "" BAED 2 NOP 1 -INI "" A2ED 2 NOP 1 -INIR "" B2ED 2 NOP 1 - -JP (HL) E9 1 NOP 1 -JP (IX) E9DD 2 NOP 1 -JP (IY) E9FD 2 NOP 1 -JP C,* DA 3 NOP 1 -JP M,* FA 3 NOP 1 -JP NC,* D2 3 NOP 1 -JP NZ,* C2 3 NOP 1 -JP P,* F2 3 NOP 1 -JP PE,* EA 3 NOP 1 -JP PO,* E2 3 NOP 1 -JP Z,* CA 3 NOP 1 -JP * C3 3 NOP 1 - -JR C,* 38 2 R1 1 -JR NC,* 30 2 R1 1 -JR NZ,* 20 2 R1 1 -JR Z,* 28 2 R1 1 -JR * 18 2 R1 1 - -LD (BC),A 02 1 NOP 1 -LD (DE),A 12 1 NOP 1 -LD (HL),A 77 1 NOP 1 -LD (HL),B 70 1 NOP 1 -LD (HL),C 71 1 NOP 1 -LD (HL),D 72 1 NOP 1 -LD (HL),E 73 1 NOP 1 -LD (HL),H 74 1 NOP 1 -LD (HL),L 75 1 NOP 1 -LD (HL),* 36 2 NOP 1 -LD (IX*),A 77DD 3 ZIX 1 -LD (IX*),B 70DD 3 ZIX 1 -LD (IX*),C 71DD 3 ZIX 1 -LD (IX*),D 72DD 3 ZIX 1 -LD (IX*),E 73DD 3 ZIX 1 -LD (IX*),H 74DD 3 ZIX 1 -LD (IX*),L 75DD 3 ZIX 1 -LD (IX*),* 36DD 4 ZIX 1 -LD (IY*),A 77FD 3 ZIX 1 -LD (IY*),B 70FD 3 ZIX 1 -LD (IY*),C 71FD 3 ZIX 1 -LD (IY*),D 72FD 3 ZIX 1 -LD (IY*),E 73FD 3 ZIX 1 -LD (IY*),H 74FD 3 ZIX 1 -LD (IY*),L 75FD 3 ZIX 1 -LD (IY*),* 36FD 4 ZIX 1 -LD (*),A 32 3 NOP 1 -LD (*),BC 43ED 4 NOP 1 -LD (*),DE 53ED 4 NOP 1 -LD (*),HL 22 3 NOP 1 -LD (*),IX 22DD 4 NOP 1 -LD (*),IY 22FD 4 NOP 1 -LD (*),SP 73ED 4 NOP 1 -LD A,(BC) 0A 1 NOP 1 -LD A,(DE) 1A 1 NOP 1 -LD A,(HL) 7E 1 NOP 1 -LD A,(IX*) 7EDD 3 ZIX 1 -LD A,(IY*) 7EFD 3 ZIX 1 -LD A,A 7F 1 NOP 1 -LD A,B 78 1 NOP 1 -LD A,C 79 1 NOP 1 -LD A,D 7A 1 NOP 1 -LD A,E 7B 1 NOP 1 -LD A,H 7C 1 NOP 1 -LD A,I 57ED 2 NOP 1 -LD A,L 7D 1 NOP 1 -LD A,R 5FED 2 NOP 1 -LD A,(*) 3A 3 NOP 1 -LD A,* 3E 2 NOP 1 -LD B,(HL) 46 1 NOP 1 -LD B,(IX*) 46DD 3 ZIX 1 -LD B,(IY*) 46FD 3 ZIX 1 -LD B,A 47 1 NOP 1 -LD B,B 40 1 NOP 1 -LD B,C 41 1 NOP 1 -LD B,D 42 1 NOP 1 -LD B,E 43 1 NOP 1 -LD B,H 44 1 NOP 1 -LD B,L 45 1 NOP 1 -LD B,* 06 2 NOP 1 -LD BC,(*) 4BED 4 NOP 1 -LD BC,* 01 3 NOP 1 -LD C,(HL) 4E 1 NOP 1 -LD C,(IX*) 4EDD 3 ZIX 1 -LD C,(IY*) 4EFD 3 ZIX 1 -LD C,A 4F 1 NOP 1 -LD C,B 48 1 NOP 1 -LD C,C 49 1 NOP 1 -LD C,D 4A 1 NOP 1 -LD C,E 4B 1 NOP 1 -LD C,H 4C 1 NOP 1 -LD C,L 4D 1 NOP 1 -LD C,* 0E 2 NOP 1 -LD D,(HL) 56 1 NOP 1 -LD D,(IX*) 56DD 3 ZIX 1 -LD D,(IY*) 56FD 3 ZIX 1 -LD D,A 57 1 NOP 1 -LD D,B 50 1 NOP 1 -LD D,C 51 1 NOP 1 -LD D,D 52 1 NOP 1 -LD D,E 53 1 NOP 1 -LD D,H 54 1 NOP 1 -LD D,L 55 1 NOP 1 -LD D,* 16 2 NOP 1 -LD DE,(*) 5BED 4 NOP 1 -LD DE,* 11 3 NOP 1 -LD E,(HL) 5E 1 NOP 1 -LD E,(IX*) 5EDD 3 ZIX 1 -LD E,(IY*) 5EFD 3 ZIX 1 -LD E,A 5F 1 NOP 1 -LD E,B 58 1 NOP 1 -LD E,C 59 1 NOP 1 -LD E,D 5A 1 NOP 1 -LD E,E 5B 1 NOP 1 -LD E,H 5C 1 NOP 1 -LD E,L 5D 1 NOP 1 -LD E,* 1E 2 NOP 1 -LD H,(HL) 66 1 NOP 1 -LD H,(IX*) 66DD 3 ZIX 1 -LD H,(IY*) 66FD 3 ZIX 1 -LD H,A 67 1 NOP 1 -LD H,B 60 1 NOP 1 -LD H,C 61 1 NOP 1 -LD H,D 62 1 NOP 1 -LD H,E 63 1 NOP 1 -LD H,H 64 1 NOP 1 -LD H,L 65 1 NOP 1 -LD H,* 26 2 NOP 1 -LD HL,(*) 2A 3 NOP 1 -LD HL,* 21 3 NOP 1 -LD I,A 47ED 2 NOP 1 -LD IX,(*) 2ADD 4 NOP 1 -LD IX,* 21DD 4 NOP 1 -LD IY,(*) 2AFD 4 NOP 1 -LD IY,* 21FD 4 NOP 1 -LD L,(HL) 6E 1 NOP 1 -LD L,(IX*) 6EDD 3 ZIX 1 -LD L,(IY*) 6EFD 3 ZIX 1 -LD L,A 6F 1 NOP 1 -LD L,B 68 1 NOP 1 -LD L,C 69 1 NOP 1 -LD L,D 6A 1 NOP 1 -LD L,E 6B 1 NOP 1 -LD L,H 6C 1 NOP 1 -LD L,L 6D 1 NOP 1 -LD L,* 2E 2 NOP 1 -LD R,A 4FED 2 NOP 1 -LD SP,(*) 7BED 4 NOP 1 -LD SP,HL F9 1 NOP 1 -LD SP,IX F9DD 2 NOP 1 -LD SP,IY F9FD 2 NOP 1 -LD SP,* 31 3 NOP 1 -LDD "" A8ED 2 NOP 1 -LDDR "" B8ED 2 NOP 1 -LDI "" A0ED 2 NOP 1 -LDIR "" B0ED 2 NOP 1 -NEG "" 44ED 2 NOP 1 -NOP "" 00 1 NOP 1 - -MLT BC 4CED 2 NOP 1 -MLT DE 5CED 2 NOP 1 -MLT HL 6CED 2 NOP 1 -MLT SP 7CED 2 NOP 1 - -OR (HL) B6 1 NOP 1 -OR (IX*) B6DD 3 ZIX 1 -OR (IY*) B6FD 3 ZIX 1 -OR A B7 1 NOP 1 -OR B B0 1 NOP 1 -OR C B1 1 NOP 1 -OR D B2 1 NOP 1 -OR E B3 1 NOP 1 -OR H B4 1 NOP 1 -OR L B5 1 NOP 1 -OR * F6 2 NOP 1 - -OTDM "" 8BED 2 NOP 1 -OTDMR "" 9BED 2 NOP 1 -OTDR "" BBED 2 NOP 1 -OTIM "" 83ED 2 NOP 1 -OTIMR "" 93ED 2 NOP 1 -OTIR "" B3ED 2 NOP 1 - -OUT (C),A 79ED 2 NOP 1 -OUT (C),B 41ED 2 NOP 1 -OUT (C),C 49ED 2 NOP 1 -OUT (C),D 51ED 2 NOP 1 -OUT (C),E 59ED 2 NOP 1 -OUT (C),H 61ED 2 NOP 1 -OUT (C),L 69ED 2 NOP 1 -OUT (*),A D3 2 NOP 1 - -OUT0 (*),A 39ED 3 NOP 1 -OUT0 (*),B 01ED 3 NOP 1 -OUT0 (*),C 09ED 3 NOP 1 -OUT0 (*),D 11ED 3 NOP 1 -OUT0 (*),E 19ED 3 NOP 1 -OUT0 (*),H 21ED 3 NOP 1 -OUT0 (*),L 29ED 3 NOP 1 - -OUTD "" ABED 2 NOP 1 -OUTI "" A3ED 2 NOP 1 - -POP AF F1 1 NOP 1 -POP BC C1 1 NOP 1 -POP DE D1 1 NOP 1 -POP HL E1 1 NOP 1 -POP IX E1DD 2 NOP 1 -POP IY E1FD 2 NOP 1 - -PUSH AF F5 1 NOP 1 -PUSH BC C5 1 NOP 1 -PUSH DE D5 1 NOP 1 -PUSH HL E5 1 NOP 1 -PUSH IX E5DD 2 NOP 1 -PUSH IY E5FD 2 NOP 1 - -RES *,(HL) 86CB 2 ZBIT 1 -RES *,(IX*) CBDD 4 ZBIT 1 0 8600 -RES *,(IY*) CBFD 4 ZBIT 1 0 8600 -RES *,A 87CB 2 ZBIT 1 -RES *,B 80CB 2 ZBIT 1 -RES *,C 81CB 2 ZBIT 1 -RES *,D 82CB 2 ZBIT 1 -RES *,E 83CB 2 ZBIT 1 -RES *,H 84CB 2 ZBIT 1 -RES *,L 85CB 2 ZBIT 1 - -RET "" C9 1 NOP 1 -RET C D8 1 NOP 1 -RET M F8 1 NOP 1 -RET NC D0 1 NOP 1 -RET NZ C0 1 NOP 1 -RET P F0 1 NOP 1 -RET PE E8 1 NOP 1 -RET PO E0 1 NOP 1 -RET Z C8 1 NOP 1 -RETI "" 4DED 2 NOP 1 -RETN "" 45ED 2 NOP 1 - -RL (HL) 16CB 2 NOP 1 -RL (IX*) CBDD 4 ZIX 1 0 1600 -RL (IY*) CBFD 4 ZIX 1 0 1600 -RL A 17CB 2 NOP 1 -RL B 10CB 2 NOP 1 -RL C 11CB 2 NOP 1 -RL D 12CB 2 NOP 1 -RL E 13CB 2 NOP 1 -RL H 14CB 2 NOP 1 -RL L 15CB 2 NOP 1 -RLA "" 17 1 NOP 1 - -RLC (HL) 06CB 2 NOP 1 -RLC (IX*) CBDD 4 ZIX 1 0 0600 -RLC (IY*) CBFD 4 ZIX 1 0 0600 -RLC A 07CB 2 NOP 1 -RLC B 00CB 2 NOP 1 -RLC C 01CB 2 NOP 1 -RLC D 02CB 2 NOP 1 -RLC E 03CB 2 NOP 1 -RLC H 04CB 2 NOP 1 -RLC L 05CB 2 NOP 1 -RLCA "" 07 1 NOP 1 -RLD "" 6FED 2 NOP 1 - -RR (HL) 1ECB 2 NOP 1 -RR (IX*) CBDD 4 ZIX 1 0 1E00 -RR (IY*) CBFD 4 ZIX 1 0 1E00 -RR A 1FCB 2 NOP 1 -RR B 18CB 2 NOP 1 -RR C 19CB 2 NOP 1 -RR D 1ACB 2 NOP 1 -RR E 1BCB 2 NOP 1 -RR H 1CCB 2 NOP 1 -RR L 1DCB 2 NOP 1 -RRA "" 1F 1 NOP 1 -RRC (HL) 0ECB 2 NOP 1 -RRC (IX*) CBDD 4 ZIX 1 0 0E00 -RRC (IY*) CBFD 4 ZIX 1 0 0E00 -RRC A 0FCB 2 NOP 1 -RRC B 08CB 2 NOP 1 -RRC C 09CB 2 NOP 1 -RRC D 0ACB 2 NOP 1 -RRC E 0BCB 2 NOP 1 -RRC H 0CCB 2 NOP 1 -RRC L 0DCB 2 NOP 1 -RRCA "" 0F 1 NOP 1 -RRD "" 67ED 2 NOP 1 - -RST 00H C7 1 NOP 1 -RST 08H CF 1 NOP 1 -RST 10H D7 1 NOP 1 -RST 18H DF 1 NOP 1 -RST 20H E7 1 NOP 1 -RST 28H EF 1 NOP 1 -RST 30H F7 1 NOP 1 -RST 38H FF 1 NOP 1 - -/* Alternate form of above -RST 00 C7 1 NOP 1 -RST 08 CF 1 NOP 1 -RST 10 D7 1 NOP 1 -RST 18 DF 1 NOP 1 -RST 20 E7 1 NOP 1 -RST 28 EF 1 NOP 1 -RST 30 F7 1 NOP 1 -RST 38 FF 1 NOP 1 - -SBC A,(HL) 9E 1 NOP 1 -SBC A,(IX*) 9EDD 3 ZIX 1 -SBC A,(IY*) 9EFD 3 ZIX 1 -SBC A,A 9F 1 NOP 1 -SBC A,B 98 1 NOP 1 -SBC A,C 99 1 NOP 1 -SBC A,D 9A 1 NOP 1 -SBC A,E 9B 1 NOP 1 -SBC A,H 9C 1 NOP 1 -SBC A,L 9D 1 NOP 1 -SBC HL,BC 42ED 2 NOP 1 -SBC HL,DE 52ED 2 NOP 1 -SBC HL,HL 62ED 2 NOP 1 -SBC HL,SP 72ED 2 NOP 1 -SBC A,* DE 2 NOP 1 -SCF "" 37 1 NOP 1 - -SET *,(HL) C6CB 2 ZBIT 1 -SET *,(IX*) CBDD 4 ZBIT 1 0 C600 -SET *,(IY*) CBFD 4 ZBIT 1 0 C600 -SET *,A C7CB 2 ZBIT 1 -SET *,B C0CB 2 ZBIT 1 -SET *,C C1CB 2 ZBIT 1 -SET *,D C2CB 2 ZBIT 1 -SET *,E C3CB 2 ZBIT 1 -SET *,H C4CB 2 ZBIT 1 -SET *,L C5CB 2 ZBIT 1 - -SLA (HL) 26CB 2 NOP 1 -SLA (IX*) CBDD 4 ZIX 1 0 2600 -SLA (IY*) CBFD 4 ZIX 1 0 2600 -SLA A 27CB 2 NOP 1 -SLA B 20CB 2 NOP 1 -SLA C 21CB 2 NOP 1 -SLA D 22CB 2 NOP 1 -SLA E 23CB 2 NOP 1 -SLA H 24CB 2 NOP 1 -SLA L 25CB 2 NOP 1 - -SLP "" 76ED 2 NOP 1 - -SRA (HL) 2ECB 2 NOP 1 -SRA (IX*) CBDD 4 ZIX 1 0 2E00 -SRA (IY*) CBFD 4 ZIX 1 0 2E00 -SRA A 2FCB 2 NOP 1 -SRA B 28CB 2 NOP 1 -SRA C 29CB 2 NOP 1 -SRA D 2ACB 2 NOP 1 -SRA E 2BCB 2 NOP 1 -SRA H 2CCB 2 NOP 1 -SRA L 2DCB 2 NOP 1 - -SRL (HL) 3ECB 2 NOP 1 -SRL (IX*) CBDD 4 ZIX 1 0 3E00 -SRL (IY*) CBFD 4 ZIX 1 0 3E00 -SRL A 3FCB 2 NOP 1 -SRL B 38CB 2 NOP 1 -SRL C 39CB 2 NOP 1 -SRL D 3ACB 2 NOP 1 -SRL E 3BCB 2 NOP 1 -SRL H 3CCB 2 NOP 1 -SRL L 3DCB 2 NOP 1 - -SUB (HL) 96 1 NOP 1 -SUB (IX*) 96DD 3 ZIX 1 -SUB (IY*) 96FD 3 ZIX 1 -SUB A 97 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB * D6 2 NOP 1 - -TST A 3CED 2 NOP 1 -TST B 04ED 2 NOP 1 -TST C 0CED 2 NOP 1 -TST D 14ED 2 NOP 1 -TST E 1CED 2 NOP 1 -TST H 24ED 2 NOP 1 -TST L 2CED 2 NOP 1 -TST (HL) 34ED 2 NOP 1 -TST * 64ED 3 NOP 1 - -TSTIO * 74ED 3 NOP 1 - -XOR (HL) AE 1 NOP 1 -XOR (IX*) AEDD 3 ZIX 1 -XOR (IY*) AEFD 3 ZIX 1 -XOR A AF 1 NOP 1 -XOR B A8 1 NOP 1 -XOR C A9 1 NOP 1 -XOR D AA 1 NOP 1 -XOR E AB 1 NOP 1 -XOR H AC 1 NOP 1 -XOR L AD 1 NOP 1 -XOR * EE 2 NOP 1 diff --git a/branches/s100/XSource/bin/TASM3210.TAB b/branches/s100/XSource/bin/TASM3210.TAB deleted file mode 100644 index d5aed946..00000000 --- a/branches/s100/XSource/bin/TASM3210.TAB +++ /dev/null @@ -1,205 +0,0 @@ -"TASM TMS32010 Assembler." -/**************************************************************************** -/* $Id: tasm3210.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the TMS32010 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK */ -/*-------------------------------------------*/ - -/* Generate opcodes high byte first */ -.MSFIRST -/* Don't use '*' as the wild card since it is used for indirect addressing */ -/* In this table '@' is the wild card indicating where expression may appear*/ -.ALTWILD -/* Use word addressing (not byte addressing) -.WORDADDRS -/* All shift/and stuff applies to opcodes, not args -.NOARGSHIFT - -.REGSET *+ A0 1 -.REGSET *- 90 1 -.REGSET * 80 1 - -ABS "" 7F88 2 NOP 1 - -ADD !,@,@ 0000 2 T1 1 8 0F00 -ADD !,@ 0008 2 T1 1 8 0F00 -ADD ! 0008 2 NOP 1 -ADD @,@ 0000 2 TDMA 1 8 0F00 -ADD @ 0000 2 T1 1 0 007F - -ADDH !,@ 6000 2 T1 1 0 01 -ADDH ! 6008 2 NOP 1 -ADDH @ 6000 2 T1 1 0 007F - -ADDS !,@ 6100 2 T1 1 0 01 -ADDS ! 6108 2 NOP 1 -ADDS @ 6100 2 T1 1 0 007F - -AND !,@ 7900 2 T1 1 0 01 -AND ! 7908 2 NOP 1 -AND @ 7900 2 T1 1 0 7F - -APAC "" 7F8F 2 NOP 1 -B @ F900 4 SWAP 1 -BANZ @ F400 4 SWAP 1 -BGEZ @ FD00 4 SWAP 1 -BGZ @ FC00 4 SWAP 1 -BIOZ @ F600 4 SWAP 1 -BLEZ @ FB00 4 SWAP 1 -BLZ @ FA00 4 SWAP 1 -BNZ @ FE00 4 SWAP 1 -BV @ F500 4 SWAP 1 -BZ @ FF00 4 SWAP 1 -CALA "" 7F8C 2 NOP 1 -CALL @ F800 4 SWAP 1 -DINT "" 7F81 2 NOP 1 - -DMOV !,@ 6900 2 T1 1 0 01 -DMOV ! 6908 2 NOP 1 -DMOV @ 6900 2 T1 1 0 007F - -EINT "" 7F82 2 NOP 1 - -IN !,@,@ 4000 2 T1 1 8 0700 -IN !,@ 4008 2 T1 1 8 0700 -IN @,@ 4000 2 TDMA 1 8 0700 - -LAC !,@,@ 2000 2 T1 1 8 0F00 -LAC !,@ 2008 2 T1 1 8 0F00 -LAC ! 2008 2 NOP 1 -LAC @,@ 2000 2 TDMA 1 8 0F00 -LAC @ 2000 2 T1 1 0 007F - -LACK @ 7E00 2 T1 1 0 00FF - -LAR @,!,@ 3800 2 TAR 1 0 0001 -LAR @,! 3808 2 TAR 1 0 0001 -LAR @,@ 3800 2 TAR 1 0 007F - -LARK @,@ 7000 2 TAR 1 0 00FF -LARP @ 6880 2 T1 1 0 0001 - -LDP !,@ 6F00 2 T1 1 0 01 -LDP ! 6F08 2 NOP 1 -LDP @ 6F00 2 T1 1 0 007F - -LDPK @ 6E00 2 T1 1 0 01 - -LST !,@ 7B00 2 T1 1 0 01 -LST ! 7B08 2 NOP 1 -LST @ 7B00 2 T1 1 0 007F - -LT !,@ 6A00 2 T1 1 0 01 -LT ! 6A08 2 NOP 1 -LT @ 6A00 2 T1 1 0 007F - -LTA !,@ 6C00 2 T1 1 0 01 -LTA ! 6C08 2 NOP 1 -LTA @ 6C00 2 T1 1 0 007F - -LTD !,@ 6B00 2 T1 1 0 01 -LTD ! 6B08 2 NOP 1 -LTD @ 6B00 2 T1 1 0 007F - -MAR !,@ 6800 2 T1 1 0 01 -MAR ! 6808 2 NOP 1 -MAR @ 6800 2 T1 1 0 007F - -MPY !,@ 6D00 2 T1 1 0 01 -MPY ! 6D08 2 NOP 1 -MPY @ 6D00 2 T1 1 0 007F - -MPYK @ 8000 2 T1 1 0 1FFF - -NOP "" 7F80 2 NOP 1 - -OR !,@ 7A00 2 T1 1 0 01 -OR ! 7A08 2 NOP 1 -OR @ 7A00 2 T1 1 0 007F - -OUT !,@,@ 4800 2 T1 1 8 0700 -OUT !,@ 4808 2 T1 1 8 0700 -OUT @,@ 4800 2 TDMA 1 8 0700 - -PAC "" 7F8E 2 NOP 1 -POP "" 7F9D 2 NOP 1 -PUSH "" 7F9C 2 NOP 1 -RET "" 7F8D 2 NOP 1 -ROVM "" 7F8A 2 NOP 1 - -/* shift count for SACH can only be 0,1, or 4. The mask allows */ -/* 0,1,4, or 5. Let the user beware */ -SACH !,@,@ 5800 2 T1 1 8 0500 -SACH !,@ 5808 2 T1 1 8 0500 -SACH ! 5808 2 NOP 1 -SACH @,@ 5800 2 TDMA 1 8 0500 -SACH @ 5800 2 T1 1 0 007F - -/* The data book shows a shift field for SACL but states it must be 0. -/* The previous version of this table left the shift field out -/* for simplicity, but here I have put it back for compatibility. -/* The AND mask is set to zero in this case so a error message -/* will result from non-zero shifts. -SACL !,@,@ 5000 2 T1 1 8 0000 -SACL !,@ 5008 2 T1 1 8 0000 -SACL ! 5008 2 NOP 1 -SACL @,@ 5000 2 TDMA 1 8 0000 -SACL @ 5000 2 T1 1 0 007F - -SAR @,!,@ 3000 2 TAR 1 0 0001 -SAR @,! 3008 2 TAR 1 0 0001 -SAR @,@ 3000 2 TAR 1 0 007F - -SOVM "" 7F8B 2 NOP 1 -SPAC "" 7F90 2 NOP 1 - -SST !,@ 7C00 2 T1 1 0 0001 -SST ! 7C08 2 NOP 1 -SST @ 7C00 2 T1 1 0 007F - -SUB !,@,@ 1000 2 T1 1 8 0F00 -SUB !,@ 1008 2 T1 1 8 0F00 -SUB ! 1008 2 NOP 1 -SUB @,@ 1000 2 TDMA 1 8 0F00 -SUB @ 1000 2 T1 1 0 007F - -SUBC !,@ 6400 2 T1 1 0 01 -SUBC ! 6408 2 NOP 1 -SUBC @ 6400 2 T1 1 0 007F - -SUBH !,@ 6200 2 T1 1 0 01 -SUBH ! 6208 2 NOP 1 -SUBH @ 6200 2 T1 1 0 007F - -SUBS !,@ 6300 2 T1 1 0 01 -SUBS ! 6308 2 NOP 1 -SUBS @ 6300 2 T1 1 0 007F - -TBLR !,@ 6700 2 T1 1 0 01 -TBLR ! 6708 2 NOP 1 -TBLR @ 6700 2 T1 1 0 007F - -TBLW !,@ 7D00 2 T1 1 0 01 -TBLW ! 7D08 2 NOP 1 -TBLW @ 7D00 2 T1 1 0 007F - -XOR !,@ 7800 2 T1 1 0 01 -XOR ! 7808 2 NOP 1 -XOR @ 7800 2 T1 1 0 007F - -ZAC "" 7F89 2 NOP 1 - -ZALH !,@ 6500 2 T1 1 0 01 -ZALH ! 6508 2 NOP 1 -ZALH @ 6500 2 T1 1 0 007F - -ZALS !,@ 6600 2 T1 1 0 01 -ZALS ! 6608 2 NOP 1 -ZALS @ 6600 2 T1 1 0 007F - diff --git a/branches/s100/XSource/bin/TASM3225.TAB b/branches/s100/XSource/bin/TASM3225.TAB deleted file mode 100644 index 30dcd4c8..00000000 --- a/branches/s100/XSource/bin/TASM3225.TAB +++ /dev/null @@ -1,456 +0,0 @@ -"TASM TMS32025 Assembler." -/**************************************************************************** -/* $Id: tasm3225.tab 1.2 1997/09/28 22:16:44 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the TMS32025 version of TASM. -/* Bob Stricklin -/* -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK */ -/*-------------------------------------------*/ - -/* Generate opcodes high byte first */ -.MSFIRST -/* Don't use '*' as the wild card since it is used for indirect addressing */ -/* In this table '@' is the wild card indicating where expression may appear*/ -.ALTWILD -.WORDADDRS -.NOARGSHIFT - -/* Addressing mode definitions. -/* Value gets OR'd in to the opcode if the -/* addressing mode is recognized -/* Note: no special classes are defined, so if this -/* table is used for TMS32020, invalid instructions -/* will not result in errors (no BR0+/- addressing mode (for example) -/* The ! character can match any of the patterns in the REGSET: -.REGSET *BR0+ F0 1 -.REGSET *BR0- C0 1 -.REGSET *0+ E0 1 -.REGSET *0- D0 1 -.REGSET *+ A0 1 -.REGSET *- 90 1 -.REGSET * 80 1 - - - - -ABS "" CE1B 2 NOP 1 - -ADD !,@,@ 0088 2 T1 1 8 0F00 -ADD !,@ 0080 2 T1 1 8 0F00 -ADD ! 0080 2 NOP 1 -ADD @,@ 0000 2 TDMA 1 8 0F00 -ADD @ 0000 2 T1 1 0 007F - -ADDC !,@ 4388 2 T1 1 0 0007 -ADDC ! 4380 2 NOP 1 -ADDC @ 4300 2 T1 1 0 007F - -ADDH !,@ 4888 2 T1 1 0 0007 -ADDH ! 4880 2 NOP 1 -ADDH @ 4800 2 T1 1 0 007F - -ADDK @ CC00 2 T1 1 0 00FF ;8 bit constant - -ADDS !,@ 4988 2 T1 1 0 0007 -ADDS ! 4980 2 NOP 1 -ADDS @ 4900 2 T1 1 0 007F - -ADDT !,@ 4A88 2 T1 1 0 0007 -ADDT ! 4A80 2 NOP 1 -ADDT @ 4A00 2 T1 1 0 007F - -ADLK @,@ D002 4 TLK 1 8 0F00 -ADLK @ D002 4 TLK 1 - -ADRK @ 7E00 2 T1 1 0 00FF ;8 bit constant - -AND !,@ 4E88 2 T1 1 0 0007 -AND ! 4E80 2 NOP 1 -AND @ 4E00 2 T1 1 0 007F - -ANDK @,@ D004 4 TLK 1 8 0F00 -ANDK @ D004 4 TLK 1 - -APAC "" CE15 2 NOP 1 - -B @,!,@ FF88 4 TLK 1 0 07 -B @,! FF80 4 SWAP 1 -B @ FF80 4 SWAP 1 - -BACC "" CE25 2 NOP 1 - -BANZ @,!,@ FB88 4 TLK 1 0 07 -BANZ @,! FB80 4 SWAP 1 -BANZ @ FB90 4 SWAP 1 ; Default to the equivalent of - ; BANZ loop,*- (as per spec) for - ; TMS32010 compatibility. - -BBNZ @,!,@ F988 4 TLK 1 0 07 -BBNZ @,! F980 4 SWAP 1 -BBNZ @ F980 4 SWAP 1 - -BBZ @,!,@ F888 4 TLK 1 0 07 -BBZ @,! F880 4 SWAP 1 -BBZ @ F880 4 SWAP 1 - -BC @,!,@ 5E88 4 TLK 1 0 07 -BC @,! 5E80 4 SWAP 1 -BC @ 5E80 4 SWAP 1 - -BGEZ @,!,@ F488 4 TLK 1 0 07 -BGEZ @,! F480 4 SWAP 1 -BGEZ @ F480 4 SWAP 1 - -BGZ @,!,@ F188 4 TLK 1 0 07 -BGZ @,! F180 4 SWAP 1 -BGZ @ F180 4 SWAP 1 - -BIOZ @,!,@ FA88 4 TLK 1 0 07 -BIOZ @,! FA80 4 SWAP 1 -BIOZ @ FA80 4 SWAP 1 - -BIT !,@,@ 9088 2 T1 1 8 0F00 ;8 bit shift -BIT !,@ 9080 2 T1 1 8 0F00 -BIT @,@ 9000 2 TDMA 1 8 0F00 - -BITT !,@ 5788 2 T1 1 0 07 -BITT ! 5780 2 T1 1 -BITT @ 5700 2 T1 1 0 7F - -BLEZ @,!,@ F288 4 TLK 1 0 07 -BLEZ @,! F280 4 SWAP 1 -BLEZ @ F280 4 SWAP 1 - -BLKD @,!,@ FD88 4 TLK 1 0 07 -BLKD @,! FD80 4 TLK 1 0 07 -BLKD @,@ FD00 4 TLK 1 0 FF - -BLKP @,!,@ FC88 4 TLK 1 0 07 -BLKP @,! FC80 4 TLK 1 0 07 -BLKP @,@ FC00 4 TLK 1 0 FF - -BLZ @,!,@ F388 4 TLK 1 0 07 -BLZ @,! F380 4 SWAP 1 -BLZ @ F380 4 SWAP 1 - -BNC @,!,@ 5F88 4 TLK 1 0 07 -BNC @,! 5F80 4 SWAP 1 -BNC @ 5F80 4 SWAP 1 - -BNV @,!,@ F788 4 TLK 1 0 07 -BNV @,! F780 4 SWAP 1 -BNV @ F780 4 SWAP 1 - -BNZ @,!,@ F588 4 TLK 1 0 07 -BNZ @,! F580 4 SWAP 1 -BNZ @ F580 4 SWAP 1 - -BV @,!,@ F088 4 TLK 1 0 07 -BV @,! F080 4 SWAP 1 -BV @ F080 4 SWAP 1 - -BZ @,!,@ F688 4 TLK 1 0 07 -BZ @,! F680 4 SWAP 1 -BZ @ F680 4 SWAP 1 - -CALA "" CE24 2 NOP 1 - -CALL @,!,@ FE88 4 TLK 1 0 07 -CALL @,! FE80 4 SWAP 1 -CALL @ FE80 4 SWAP 1 - -CMPL "" CE27 2 NOP 1 - -CMPR @ CE50 2 T1 1 0 03 ;2 BIT CONTANT - -CNFD "" CE04 2 NOP 1 - -CNFP "" CE05 2 NOP 1 - -CONF "" CE3C 2 T1 4 0 03 ; c26 ONLY - -DINT "" CE01 2 NOP 1 - -DMOV !,@ 5688 2 T1 1 0 07 -DMOV ! 5680 2 NOP 1 -DMOV @ 5600 2 T1 1 0 007F - -EINT "" CE00 2 NOP 1 - -FORT @ CE0E 2 T1 1 0 01 - -IDLE "" CE1F 2 NOP 1 - -IN !,@,@ 8088 2 T1 1 8 0F00 -IN !,@ 8080 2 T1 1 8 0F00 -IN @,@ 8000 2 TDMA 1 8 0F00 - -LAC !,@,@ 2088 2 T1 1 8 0F00 -LAC !,@ 2080 2 T1 1 8 0F00 -LAC ! 2080 2 NOP 1 -LAC @,@ 2000 2 TDMA 1 8 0F00 -LAC @ 2000 2 T1 1 0 007F - -LACK @ CA00 2 T1 1 0 00FF ;tested for -25 - -LACT !,@ 4288 2 T1 1 0 07 -LACT ! 4280 2 NOP 1 -LACT @ 4200 2 T1 1 0 007F - -LALK @,@ D001 4 TLK 1 8 0F00 -LALK @ D001 4 TLK 1 - -LAR @,!,@ 3088 2 TAR 1 0 07 -LAR @,! 3080 2 TAR 1 0 07 -LAR @,@ 3000 2 TAR 1 0 7F - -LARK @,@ C000 2 TAR 1 0 00FF -LARP @ 5588 2 T1 1 0 0007 - -LDP !,@ 5288 2 T1 1 0 07 -LDP ! 5280 2 NOP 1 -LDP @ 5200 2 T1 1 0 007F - -LDPK @ C800 2 T1 1 0 01FF ;9 bit constant - -LPH !,@ 5388 2 T1 1 0 07 -LPH ! 5380 2 NOP 1 -LPH @ 5300 2 T1 1 0 7F - -LRLK @,@ D000 4 T5 1 8 0700 ;, - -LST !,@ 5088 2 T1 1 0 07 -LST ! 5080 2 NOP 1 -LST @ 5000 2 T1 1 0 7F - -LST1 !,@ 5188 2 T1 1 0 07 -LST1 ! 5180 2 NOP 1 -LST1 @ 5100 2 T1 1 0 7F - -LT !,@ 3C88 2 T1 1 0 07 -LT ! 3C80 2 NOP 1 -LT @ 3C00 2 T1 1 0 7F - -LTA !,@ 3D88 2 T1 1 0 07 -LTA ! 3D80 2 NOP 1 -LTA @ 3D00 2 T1 1 0 7F - -LTD !,@ 3F88 2 T1 1 0 07 -LTD ! 3F80 2 NOP 1 -LTD @ 3F00 2 T1 1 0 7F - -LTP !,@ 3E88 2 T1 1 0 07 -LTP ! 3E80 2 NOP 1 -LTP @ 3E00 2 T1 1 0 7F - -LTS !,@ 5B88 2 T1 1 0 07 -LTS ! 5B80 2 NOP 1 -LTS @ 5B00 2 T1 1 0 7F - -MAC @,!,@ 5D88 4 TLK 1 0 07 -MAC @,! 5D80 4 TLK 1 0 07 -MAC @,@ 5D00 4 TLK 1 0 7F - -MACD @,!,@ 5C88 4 TLK 1 0 07 -MACD @,! 5C80 4 TLK 1 0 07 -MACD @,@ 5C00 4 TLK 1 0 7F - -MAR !,@ 5588 2 T1 1 0 07 -MAR ! 5580 2 NOP 1 -MAR @ 5500 2 T1 1 0 7F - -MPY !,@ 3888 2 T1 1 0 07 -MPY ! 3880 2 NOP 1 -MPY @ 3800 2 T1 1 0 7F - -MPYA !,@ 3A88 2 T1 1 0 07 -MPYA ! 3A80 2 NOP 1 -MPYA @ 3A00 2 T1 1 0 7F - -MPYK @ A000 2 T1 1 0 1FFF ;13 BIT CONTSTANT - -MPYS !,@ 3B88 2 T1 1 0 07 -MPYS ! 3B80 2 NOP 1 -MPYS @ 3B00 2 T1 1 0 7F - -MPYU !,@ CF88 2 T1 1 0 07 -MPYU ! CF80 2 NOP 1 -MPYU @ CF00 2 T1 1 0 7F - -NEG "" CE23 2 NOP 1 - -NOP "" 5500 2 NOP 1 - -NORM ! CE82 2 NOP 1 ; C25 -NORM "" CEA2 2 NOP 1 ; C20 - -OR !,@ 4D88 2 T1 1 0 07 -OR ! 4D80 2 NOP 1 -OR @ 4D00 2 T1 1 0 7F - -ORK @,@ D005 4 TLK 1 8 0F00 -ORK @ D005 4 TLK 1 - -OUT !,@,@ E088 2 T1 1 8 0F00 -OUT !,@ E080 2 T1 1 8 0F00 -OUT @,@ E000 2 TDMA 1 8 0F00 - -PAC "" CE14 2 NOP 1 - -POP "" CE1D 2 NOP 1 - -POPD !,@ 7A88 2 T1 1 0 07 -POPD ! 7A80 2 NOP 1 -POPD @ 7A00 2 T1 1 0 7F - -PSHD !,@ 5488 2 T1 1 0 07 -PSHD ! 5480 2 NOP 1 -PSHD @ 5400 2 T1 1 0 7F - -PUSH "" CE1C 2 NOP 1 -RC "" CE30 2 NOP 1 -RET "" CE26 2 NOP 1 -RFSM "" CE36 2 NOP 1 -RHM "" CE38 2 NOP 1 -ROL "" CE34 2 NOP 1 -ROR "" CE35 2 NOP 1 -ROVM "" CE02 2 NOP 1 - -RPT !,@ 4B88 2 T1 1 0 07 -RPT ! 4B80 2 NOP 1 -RPT @ 4B00 2 T1 1 0 7F - -RPTK @ CB00 2 T1 1 0 00FF ;8 bit constant - -RSXM "" CE06 2 NOP 1 -RTC "" CE32 2 NOP 1 -RTXM "" CE20 2 NOP 1 -RXF "" CE0C 2 NOP 1 - -/* shift count for SACH can only be 0,1, or 4 FOR 32020 -/* 0-7 FOR 320c25. For now, build the table specifically for the 320C25 -SACH !,@,@ 6888 2 T1 1 8 0700 -SACH !,@ 6880 2 T1 1 8 0700 -SACH ! 6880 2 NOP 1 -SACH @,@ 6800 2 TDMA 1 8 0700 -SACH @ 6800 2 T1 1 0 007F - -SACL !,@,@ 6088 2 T1 1 8 0700 -SACL !,@ 6080 2 T1 1 8 0700 -SACL ! 6080 2 NOP 1 -SACL @,@ 6000 2 TDMA 1 8 0700 -SACL @ 6000 2 T1 1 0 007F - -SAR @,!,@ 7088 2 TAR 1 0 0007 -SAR @,! 7080 2 TAR 1 0 0007 -SAR @,@ 7000 2 TAR 1 0 007F - -SBLK @,@ D003 4 TLK 1 8 0F00 -SBLK @ D003 4 TLK 1 - -SBRK @ 7F00 2 T1 1 0 00FF - -SC "" CE31 2 NOP 1 -SFL "" CE18 2 NOP 1 -SFR "" CE19 2 NOP 1 -SFSM "" CE37 2 NOP 1 -SHM "" CE39 2 NOP 1 -SOVM "" CE03 2 NOP 1 -SPAC "" CE16 2 NOP 1 - -SPH !,@ 7D88 2 T1 1 0 07 -SPH ! 7D80 2 NOP 1 -SPH @ 7D00 2 T1 1 0 7F - -SPL !,@ 7C88 2 T1 1 0 07 -SPL ! 7C80 2 NOP 1 -SPL @ 7C00 2 T1 1 0 7F - -SPM @ CE08 2 T1 1 0 03 ;2 bit constant - -SQRA !,@ 3988 2 T1 1 0 07 -SQRA ! 3980 2 NOP 1 -SQRA @ 3900 2 T1 1 0 7F - -SQRS !,@ 5A88 2 T1 1 0 07 -SQRS ! 5A80 2 NOP 1 -SQRS @ 5A00 2 T1 1 0 7F - -SST !,@ 7888 2 T1 1 0 07 -SST ! 7880 2 NOP 1 -SST @ 7800 2 T1 1 0 7F - -SST1 !,@ 7988 2 T1 1 0 07 -SST1 ! 7980 2 NOP 1 -SST1 @ 7900 2 T1 1 0 7F - -SSXM "" CE07 2 NOP 1 -STC "" CE33 2 NOP 1 -STXM "" CE21 2 NOP 1 - - -SUB !,@,@ 1088 2 T1 1 8 0F00 -SUB !,@ 1080 2 T1 1 8 0F00 -SUB ! 1080 2 NOP 1 -SUB @,@ 1000 2 TDMA 1 8 0F00 -SUB @ 1000 2 T1 1 0 007F - -SUBB !,@ 4F88 2 T1 1 0 07 -SUBB ! 4F80 2 NOP 1 -SUBB @ 4F00 2 T1 1 0 7F - -SUBC !,@ 4788 2 T1 1 0 07 -SUBC ! 4780 2 NOP 1 -SUBC @ 4700 2 T1 1 0 7F - -SUBH !,@ 4488 2 T1 1 0 07 -SUBH ! 4480 2 NOP 1 -SUBH @ 4400 2 T1 1 0 7F - -SUBK @ CD00 2 T1 1 0 00FF - -SUBS !,@ 4588 2 T1 1 0 07 -SUBS ! 4580 2 NOP 1 -SUBS @ 4500 2 T1 1 0 7F - -SUBT !,@ 4688 2 T1 1 0 07 -SUBT ! 4680 2 NOP 1 -SUBT @ 4600 2 T1 1 0 7F - -SXF "" CE0D 2 NOP 1 - -TBLR !,@ 5888 2 T1 1 0 07 -TBLR ! 5880 2 NOP 1 -TBLR @ 5800 2 T1 1 0 7F - -TBLW !,@ 5988 2 T1 1 0 07 -TBLW ! 5980 2 NOP 1 -TBLW @ 5900 2 T1 1 0 7F - -TRAP "" CE1E 2 NOP 1 - -XOR !,@ 4C88 2 T1 1 0 07 -XOR ! 4C80 2 NOP 1 -XOR @ 4C00 2 T1 1 0 7F - -XORK @,@ D006 4 TLK 1 8 0F00 -XORK @ D006 4 TLK 1 - -ZAC "" CA00 2 NOP 1 - -ZALH !,@ 4088 2 T1 1 0 07 -ZALH ! 4080 2 NOP 1 -ZALH @ 4000 2 T1 1 0 7F - -ZALR !,@ 7B88 2 T1 1 0 07 -ZALR ! 7B80 2 NOP 1 -ZALR @ 7B00 2 T1 1 0 7F - -ZALS !,@ 4188 2 T1 1 0 07 -ZALS ! 4180 2 NOP 1 -ZALS @ 4100 2 T1 1 0 7F - diff --git a/branches/s100/XSource/bin/TASM48.TAB b/branches/s100/XSource/bin/TASM48.TAB deleted file mode 100644 index a76454ae..00000000 --- a/branches/s100/XSource/bin/TASM48.TAB +++ /dev/null @@ -1,281 +0,0 @@ -"TASM 8048 Assembler. " -/**************************************************************************** -/* $Id: tasm48.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8048 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* CLASS bits are assigned as follows: -/* bit 0 = 8X48, 8035, 8039, 8049 instructions -/* bit 1 = 8X41A -/* bit 2 = 8022 -/* bit 3 = 8021 -/* Note that some of the base instructions should be disabled for the -/* 8041, 8022, and 8021, but are not. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ADD A,R0 68 1 NOP 1 -ADD A,R1 69 1 NOP 1 -ADD A,R2 6A 1 NOP 1 -ADD A,R3 6B 1 NOP 1 -ADD A,R4 6C 1 NOP 1 -ADD A,R5 6D 1 NOP 1 -ADD A,R6 6E 1 NOP 1 -ADD A,R7 6F 1 NOP 1 -ADD A,@R0 60 1 NOP 1 -ADD A,@R1 61 1 NOP 1 -ADD A,#* 03 2 NOP 1 - -ADDC A,R0 78 1 NOP 1 -ADDC A,R1 79 1 NOP 1 -ADDC A,R2 7A 1 NOP 1 -ADDC A,R3 7B 1 NOP 1 -ADDC A,R4 7C 1 NOP 1 -ADDC A,R5 7D 1 NOP 1 -ADDC A,R6 7E 1 NOP 1 -ADDC A,R7 7F 1 NOP 1 -ADDC A,@R0 70 1 NOP 1 -ADDC A,@R1 71 1 NOP 1 -ADDC A,#* 13 2 NOP 1 - -ANL A,R0 58 1 NOP 1 -ANL A,R1 59 1 NOP 1 -ANL A,R2 5A 1 NOP 1 -ANL A,R3 5B 1 NOP 1 -ANL A,R4 5C 1 NOP 1 -ANL A,R5 5D 1 NOP 1 -ANL A,R6 5E 1 NOP 1 -ANL A,R7 5F 1 NOP 1 -ANL A,@R0 50 1 NOP 1 -ANL A,@R1 51 1 NOP 1 -ANL A,#* 53 2 NOP 1 -ANL BUS,#* 98 2 NOP 1 -ANL P1,#* 99 2 NOP 1 -ANL P2,#* 9A 2 NOP 1 - -ANLD P4,A 9C 1 NOP 1 -ANLD P5,A 9D 1 NOP 1 -ANLD P6,A 9E 1 NOP 1 -ANLD P7,A 9F 1 NOP 1 - -CALL * 14 2 JMP 1 - -CLR A 27 1 NOP 1 -CLR C 97 1 NOP 1 -CLR F0 85 1 NOP 1 -CLR F1 A5 1 NOP 1 - -CPL A 37 1 NOP 1 -CPL C A7 1 NOP 1 -CPL F0 95 1 NOP 1 -CPL F1 B5 1 NOP 1 - -DA A 57 1 NOP 1 - -DEC A 07 1 NOP 1 -DEC R0 C8 1 NOP 1 -DEC R1 C9 1 NOP 1 -DEC R2 CA 1 NOP 1 -DEC R3 CB 1 NOP 1 -DEC R4 CC 1 NOP 1 -DEC R5 CD 1 NOP 1 -DEC R6 CE 1 NOP 1 -DEC R7 CF 1 NOP 1 - -DIS I 15 1 NOP 1 -DIS TCNTI 35 1 NOP 1 - -DJNZ R0,* E8 2 JTHISPAGE 1 -DJNZ R1,* E9 2 JTHISPAGE 1 -DJNZ R2,* EA 2 JTHISPAGE 1 -DJNZ R3,* EB 2 JTHISPAGE 1 -DJNZ R4,* EC 2 JTHISPAGE 1 -DJNZ R5,* ED 2 JTHISPAGE 1 -DJNZ R6,* EE 2 JTHISPAGE 1 -DJNZ R7,* EF 2 JTHISPAGE 1 - -EN DMA E5 1 NOP 2 ;8041 -EN FLAGS F5 1 NOP 2 ;8041 -EN I 05 1 NOP 1 -EN TCNTI 25 1 NOP 1 -ENT0 CLK 75 1 NOP 1 - -IN A,DBB 22 1 NOP 2 ;8041 -IN A,P0 08 1 NOP 8 ;8021 -IN A,P1 09 1 NOP 1 -IN A,P2 0A 1 NOP 1 - -INC A 17 1 NOP 1 -INC R0 18 1 NOP 1 -INC R1 19 1 NOP 1 -INC R2 1A 1 NOP 1 -INC R3 1B 1 NOP 1 -INC R4 1C 1 NOP 1 -INC R5 1D 1 NOP 1 -INC R6 1E 1 NOP 1 -INC R7 1F 1 NOP 1 -INC @R0 10 1 NOP 1 -INC @R1 11 1 NOP 1 - -INS A,BUS 08 1 NOP 1 - -JB0 * 12 2 JTHISPAGE 1 -JB1 * 32 2 JTHISPAGE 1 -JB2 * 52 2 JTHISPAGE 1 -JB3 * 72 2 JTHISPAGE 1 -JB4 * 92 2 JTHISPAGE 1 -JB5 * B2 2 JTHISPAGE 1 -JB6 * D2 2 JTHISPAGE 1 -JB7 * F2 2 JTHISPAGE 1 - -JMP * 04 2 JMP 1 - -JC * F6 2 JTHISPAGE 1 -JF0 * B6 2 JTHISPAGE 1 -JF1 * 76 2 JTHISPAGE 1 -JNC * E6 2 JTHISPAGE 1 -JNI * 86 2 JTHISPAGE 1 -JNIBF * D6 2 JTHISPAGE 2 ;8041 -JNT0 * 26 2 JTHISPAGE 1 -JNT1 * 46 2 JTHISPAGE 1 -JNZ * 96 2 JTHISPAGE 1 -JOBF * 86 2 JTHISPAGE 2 ;8041 -JTF * 16 2 JTHISPAGE 1 -JT0 * 36 2 JTHISPAGE 1 -JT1 * 56 2 JTHISPAGE 1 -JZ * C6 2 JTHISPAGE 1 - -JMPP @A B3 1 NOP 1 - -MOV A,PSW C7 1 NOP 1 -MOV A,R0 F8 1 NOP 1 -MOV A,R1 F9 1 NOP 1 -MOV A,R2 FA 1 NOP 1 -MOV A,R3 FB 1 NOP 1 -MOV A,R4 FC 1 NOP 1 -MOV A,R5 FD 1 NOP 1 -MOV A,R6 FE 1 NOP 1 -MOV A,R7 FF 1 NOP 1 -MOV A,T 42 1 NOP 1 -MOV A,@R0 F0 1 NOP 1 -MOV A,@R1 F1 1 NOP 1 -MOV A,#* 23 2 NOP 1 -MOV PSW,A D7 1 NOP 1 -MOV R0,A A8 1 NOP 1 -MOV R1,A A9 1 NOP 1 -MOV R2,A AA 1 NOP 1 -MOV R3,A AB 1 NOP 1 -MOV R4,A AC 1 NOP 1 -MOV R5,A AD 1 NOP 1 -MOV R6,A AE 1 NOP 1 -MOV R7,A AF 1 NOP 1 -MOV R0,#* B8 2 NOP 1 -MOV R1,#* B9 2 NOP 1 -MOV R2,#* BA 2 NOP 1 -MOV R3,#* BB 2 NOP 1 -MOV R4,#* BC 2 NOP 1 -MOV R5,#* BD 2 NOP 1 -MOV R6,#* BE 2 NOP 1 -MOV R7,#* BF 2 NOP 1 -MOV STS,A 90 1 NOP 2 ;8041 -MOV T,A 62 1 NOP 1 -MOV @R0,A A0 1 NOP 1 -MOV @R1,A A1 1 NOP 1 -MOV @R0,#* B0 2 NOP 1 -MOV @R1,#* B1 2 NOP 1 - -MOVD A,P4 0C 1 NOP 1 -MOVD A,P5 0D 1 NOP 1 -MOVD A,P6 0E 1 NOP 1 -MOVD A,P7 0F 1 NOP 1 -MOVD P4,A 3C 1 NOP 1 -MOVD P5,A 3D 1 NOP 1 -MOVD P6,A 3E 1 NOP 1 -MOVD P7,A 3F 1 NOP 1 - -MOVP A,@A A3 1 NOP 1 -MOVP3 A,@A E3 1 NOP 1 - -MOVX A,@R0 80 1 NOP 1 -MOVX A,@R1 81 1 NOP 1 -MOVX @R0,A 90 1 NOP 1 -MOVX @R1,A 91 1 NOP 1 - -NOP "" 00 1 NOP 1 - -ORL A,R0 48 1 NOP 1 -ORL A,R1 49 1 NOP 1 -ORL A,R2 4A 1 NOP 1 -ORL A,R3 4B 1 NOP 1 -ORL A,R4 4C 1 NOP 1 -ORL A,R5 4D 1 NOP 1 -ORL A,R6 4E 1 NOP 1 -ORL A,R7 4F 1 NOP 1 -ORL A,@R0 40 1 NOP 1 -ORL A,@R1 41 1 NOP 1 -ORL A,#* 43 2 NOP 1 -ORL BUS,#* 88 2 NOP 1 -ORL P1,#* 89 2 NOP 1 -ORL P2,#* 8A 2 NOP 1 - -ORLD P4,A 8C 1 NOP 1 -ORLD P5,A 8D 1 NOP 1 -ORLD P6,A 8E 1 NOP 1 -ORLD P7,A 8F 1 NOP 1 - -OUTL BUS,A 02 1 NOP 1 -OUT DBB,A 02 1 NOP 2 ;8041 -OUTL P0,A 90 1 NOP 8 ;8021 -OUTL P1,A 39 1 NOP 1 -OUTL P2,A 3A 1 NOP 1 - -RAD "" 80 1 NOP 4 ;8022 - -RET "" 83 1 NOP 1 -RETI "" 93 1 NOP 4 ;8022 -RETR "" 93 1 NOP 1 - -RL A E7 1 NOP 1 -RLC A F7 1 NOP 1 -RR A 77 1 NOP 1 -RRC A 67 1 NOP 1 - -SEL AN0 85 1 NOP 4 ;8022 -SEL AN1 95 1 NOP 4 ;8022 -SEL MB0 E5 1 NOP 1 -SEL MB1 F5 1 NOP 1 -SEL RB0 C5 1 NOP 1 -SEL RB1 D5 1 NOP 1 - -STOP TCNT 65 1 NOP 1 -STRT CNT 45 1 NOP 1 -STRT T 55 1 NOP 1 - -SWAP A 47 1 NOP 1 - -XCH A,R0 28 1 NOP 1 -XCH A,R1 29 1 NOP 1 -XCH A,R2 2A 1 NOP 1 -XCH A,R3 2B 1 NOP 1 -XCH A,R4 2C 1 NOP 1 -XCH A,R5 2D 1 NOP 1 -XCH A,R6 2E 1 NOP 1 -XCH A,R7 2F 1 NOP 1 -XCH A,@R0 20 1 NOP 1 -XCH A,@R1 21 1 NOP 1 - -XCHD A,@R0 30 1 NOP 1 -XCHD A,@R1 31 1 NOP 1 - -XRL A,R0 D8 1 NOP 1 -XRL A,R1 D9 1 NOP 1 -XRL A,R2 DA 1 NOP 1 -XRL A,R3 DB 1 NOP 1 -XRL A,R4 DC 1 NOP 1 -XRL A,R5 DD 1 NOP 1 -XRL A,R6 DE 1 NOP 1 -XRL A,R7 DF 1 NOP 1 -XRL A,@R0 D0 1 NOP 1 -XRL A,@R1 D1 1 NOP 1 -XRL A,#* D3 2 NOP 1 - diff --git a/branches/s100/XSource/bin/TASM51.TAB b/branches/s100/XSource/bin/TASM51.TAB deleted file mode 100644 index 24c2a142..00000000 --- a/branches/s100/XSource/bin/TASM51.TAB +++ /dev/null @@ -1,285 +0,0 @@ -"TASM 8051 Assembler. " -/**************************************************************************** -/* $Id: tasm51.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8051 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* - -.NOARGSHIFT - -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ACALL * 11 2 JMP 1 0 F800 - -ADD A,R0 28 1 NOP 1 -ADD A,R1 29 1 NOP 1 -ADD A,R2 2A 1 NOP 1 -ADD A,R3 2B 1 NOP 1 -ADD A,R4 2C 1 NOP 1 -ADD A,R5 2D 1 NOP 1 -ADD A,R6 2E 1 NOP 1 -ADD A,R7 2F 1 NOP 1 -ADD A,@R0 26 1 NOP 1 -ADD A,@R1 27 1 NOP 1 -ADD A,#* 24 2 NOP 1 -ADD A,* 25 2 NOP 1 - -ADDC A,R0 38 1 NOP 1 -ADDC A,R1 39 1 NOP 1 -ADDC A,R2 3A 1 NOP 1 -ADDC A,R3 3B 1 NOP 1 -ADDC A,R4 3C 1 NOP 1 -ADDC A,R5 3D 1 NOP 1 -ADDC A,R6 3E 1 NOP 1 -ADDC A,R7 3F 1 NOP 1 -ADDC A,@R0 36 1 NOP 1 -ADDC A,@R1 37 1 NOP 1 -ADDC A,#* 34 2 NOP 1 -ADDC A,* 35 2 NOP 1 - -AJMP * 01 2 JMP 1 0 F800 - -ANL A,R0 58 1 NOP 1 -ANL A,R1 59 1 NOP 1 -ANL A,R2 5A 1 NOP 1 -ANL A,R3 5B 1 NOP 1 -ANL A,R4 5C 1 NOP 1 -ANL A,R5 5D 1 NOP 1 -ANL A,R6 5E 1 NOP 1 -ANL A,R7 5F 1 NOP 1 -ANL A,@R0 56 1 NOP 1 -ANL A,@R1 57 1 NOP 1 -ANL A,#* 54 2 NOP 1 -ANL A,* 55 2 NOP 1 -ANL C,/* b0 2 NOP 1 -ANL C,* 82 2 NOP 1 -ANL *,A 52 2 NOP 1 -ANL *,#* 53 3 COMBINE 1 - -CJNE A,#*,* b4 3 CR 1 -CJNE A,*,* b5 3 CR 1 -CJNE R0,#*,* b8 3 CR 1 -CJNE R1,#*,* b9 3 CR 1 -CJNE R2,#*,* ba 3 CR 1 -CJNE R3,#*,* bb 3 CR 1 -CJNE R4,#*,* bc 3 CR 1 -CJNE R5,#*,* bd 3 CR 1 -CJNE R6,#*,* be 3 CR 1 -CJNE R7,#*,* bf 3 CR 1 -CJNE @R0,#*,* b6 3 CR 1 -CJNE @R1,#*,* b7 3 CR 1 - -CLR A e4 1 NOP 1 -CLR C c3 1 NOP 1 -CLR * c2 2 NOP 1 - -CPL A f4 1 NOP 1 -CPL C b3 1 NOP 1 -CPL * b2 2 NOP 1 - -DA A d4 1 NOP 1 - -DEC A 14 1 NOP 1 -DEC R0 18 1 NOP 1 -DEC R1 19 1 NOP 1 -DEC R2 1A 1 NOP 1 -DEC R3 1B 1 NOP 1 -DEC R4 1C 1 NOP 1 -DEC R5 1D 1 NOP 1 -DEC R6 1E 1 NOP 1 -DEC R7 1F 1 NOP 1 -DEC @R0 16 1 NOP 1 -DEC @R1 17 1 NOP 1 -DEC * 15 2 NOP 1 - -DIV AB 84 1 NOP 1 - -DJNZ R0,* d8 2 R1 1 -DJNZ R1,* d9 2 R1 1 -DJNZ R2,* dA 2 R1 1 -DJNZ R3,* dB 2 R1 1 -DJNZ R4,* dC 2 R1 1 -DJNZ R5,* dD 2 R1 1 -DJNZ R6,* dE 2 R1 1 -DJNZ R7,* dF 2 R1 1 -DJNZ *,* d5 3 CR 1 - -INC A 04 1 NOP 1 -INC R0 08 1 NOP 1 -INC R1 09 1 NOP 1 -INC R2 0A 1 NOP 1 -INC R3 0B 1 NOP 1 -INC R4 0C 1 NOP 1 -INC R5 0D 1 NOP 1 -INC R6 0E 1 NOP 1 -INC R7 0F 1 NOP 1 -INC @R0 06 1 NOP 1 -INC @R1 07 1 NOP 1 -INC DPTR a3 1 NOP 1 -INC * 05 2 NOP 1 - -JB *,* 20 3 CR 1 -JBC *,* 10 3 CR 1 -JC * 40 2 R1 1 -JMP @A+DPTR 73 1 NOP 1 -JNB *,* 30 3 CR 1 -JNC * 50 2 R1 1 -JNZ * 70 2 R1 1 -JZ * 60 2 R1 1 - -LCALL * 12 3 SWAP 1 - -LJMP * 02 3 SWAP 1 - -MOV A,R0 e8 1 NOP 1 -MOV A,R1 e9 1 NOP 1 -MOV A,R2 eA 1 NOP 1 -MOV A,R3 eB 1 NOP 1 -MOV A,R4 eC 1 NOP 1 -MOV A,R5 eD 1 NOP 1 -MOV A,R6 eE 1 NOP 1 -MOV A,R7 eF 1 NOP 1 -MOV A,@R0 e6 1 NOP 1 -MOV A,@R1 e7 1 NOP 1 -MOV A,#* 74 2 NOP 1 -MOV A,* e5 2 NOP 1 -MOV C,* a2 2 NOP 1 -MOV DPTR,#* 90 3 SWAP 1 -MOV R0,A f8 1 NOP 1 -MOV R1,A f9 1 NOP 1 -MOV R2,A fA 1 NOP 1 -MOV R3,A fB 1 NOP 1 -MOV R4,A fC 1 NOP 1 -MOV R5,A fD 1 NOP 1 -MOV R6,A fE 1 NOP 1 -MOV R7,A fF 1 NOP 1 -MOV R0,#* 78 2 NOP 1 -MOV R1,#* 79 2 NOP 1 -MOV R2,#* 7A 2 NOP 1 -MOV R3,#* 7B 2 NOP 1 -MOV R4,#* 7C 2 NOP 1 -MOV R5,#* 7D 2 NOP 1 -MOV R6,#* 7E 2 NOP 1 -MOV R7,#* 7F 2 NOP 1 -MOV R0,* a8 2 NOP 1 -MOV R1,* a9 2 NOP 1 -MOV R2,* aA 2 NOP 1 -MOV R3,* aB 2 NOP 1 -MOV R4,* aC 2 NOP 1 -MOV R5,* aD 2 NOP 1 -MOV R6,* aE 2 NOP 1 -MOV R7,* aF 2 NOP 1 -MOV @R0,A f6 1 NOP 1 -MOV @R1,A f7 1 NOP 1 -MOV @R0,#* 76 2 NOP 1 -MOV @R1,#* 77 2 NOP 1 -MOV @R0,* a6 2 NOP 1 -MOV @R1,* a7 2 NOP 1 -MOV *,A f5 2 NOP 1 -MOV *,C 92 2 NOP 1 -MOV *,R0 88 2 NOP 1 -MOV *,R1 89 2 NOP 1 -MOV *,R2 8A 2 NOP 1 -MOV *,R3 8B 2 NOP 1 -MOV *,R4 8C 2 NOP 1 -MOV *,R5 8D 2 NOP 1 -MOV *,R6 8E 2 NOP 1 -MOV *,R7 8F 2 NOP 1 -MOV *,@R0 86 2 NOP 1 -MOV *,@R1 87 2 NOP 1 -MOV *,#* 75 3 COMBINE 1 -MOV *,* 85 3 CSWAP 1 - -MOVC A,@A+DPTR 93 1 NOP 1 -MOVC A,@A+PC 83 1 NOP 1 - -MOVX A,@R0 e2 1 NOP 1 -MOVX A,@R1 e3 1 NOP 1 -MOVX A,@DPTR e0 1 NOP 1 -MOVX @R0,A f2 1 NOP 1 -MOVX @R1,A f3 1 NOP 1 -MOVX @DPTR,A f0 1 NOP 1 - -MUL AB a4 1 NOP 1 - -NOP "" 00 1 NOP 1 - -ORL A,R0 48 1 NOP 1 -ORL A,R1 49 1 NOP 1 -ORL A,R2 4A 1 NOP 1 -ORL A,R3 4B 1 NOP 1 -ORL A,R4 4C 1 NOP 1 -ORL A,R5 4D 1 NOP 1 -ORL A,R6 4E 1 NOP 1 -ORL A,R7 4F 1 NOP 1 -ORL A,@R0 46 1 NOP 1 -ORL A,@R1 47 1 NOP 1 -ORL A,#* 44 2 NOP 1 -ORL A,* 45 2 NOP 1 -ORL C,/* a0 2 NOP 1 -ORL C,* 72 2 NOP 1 -ORL *,A 42 2 NOP 1 -ORL *,#* 43 3 COMBINE 1 - -POP * d0 2 NOP 1 -PUSH * c0 2 NOP 1 - -RET "" 22 1 NOP 1 -RETI "" 32 1 NOP 1 - -RL A 23 1 NOP 1 -RLC A 33 1 NOP 1 -RR A 03 1 NOP 1 -RRC A 13 1 NOP 1 - -SETB C d3 1 NOP 1 -SETB * d2 2 NOP 1 - -SJMP * 80 2 R1 1 - -SUBB A,R0 98 1 NOP 1 -SUBB A,R1 99 1 NOP 1 -SUBB A,R2 9A 1 NOP 1 -SUBB A,R3 9B 1 NOP 1 -SUBB A,R4 9C 1 NOP 1 -SUBB A,R5 9D 1 NOP 1 -SUBB A,R6 9E 1 NOP 1 -SUBB A,R7 9F 1 NOP 1 -SUBB A,@R0 96 1 NOP 1 -SUBB A,@R1 97 1 NOP 1 -SUBB A,#* 94 2 NOP 1 -SUBB A,* 95 2 NOP 1 - -SWAP A c4 1 NOP 1 - -XCH A,R0 c8 1 NOP 1 -XCH A,R1 c9 1 NOP 1 -XCH A,R2 cA 1 NOP 1 -XCH A,R3 cB 1 NOP 1 -XCH A,R4 cC 1 NOP 1 -XCH A,R5 cD 1 NOP 1 -XCH A,R6 cE 1 NOP 1 -XCH A,R7 cF 1 NOP 1 -XCH A,@R0 c6 1 NOP 1 -XCH A,@R1 c7 1 NOP 1 -XCH A,* c5 2 NOP 1 - -XCHD A,@R0 d6 1 NOP 1 -XCHD A,@R1 d7 1 NOP 1 - -XRL A,R0 68 1 NOP 1 -XRL A,R1 69 1 NOP 1 -XRL A,R2 6A 1 NOP 1 -XRL A,R3 6B 1 NOP 1 -XRL A,R4 6C 1 NOP 1 -XRL A,R5 6D 1 NOP 1 -XRL A,R6 6E 1 NOP 1 -XRL A,R7 6F 1 NOP 1 -XRL A,@R0 66 1 NOP 1 -XRL A,@R1 67 1 NOP 1 -XRL A,#* 64 2 NOP 1 -XRL A,* 65 2 NOP 1 -XRL *,A 62 2 NOP 1 -XRL *,#* 63 3 COMBINE 1 - diff --git a/branches/s100/XSource/bin/TASM65.TAB b/branches/s100/XSource/bin/TASM65.TAB deleted file mode 100644 index c6b95ce7..00000000 --- a/branches/s100/XSource/bin/TASM65.TAB +++ /dev/null @@ -1,222 +0,0 @@ -"TASM 6502 Assembler. " -/**************************************************************************** -/* $Id: tasm65.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 6502 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorported, June 1987. -/* Note that there are two classes of extended instructions beyond -/* the standard set. The classes are assigned bits as follows: -/* bit 0 = standard set -/* bit 1 = extended instructions for R65C02 -/* bit 2 = extended instructions for R65C00/21 -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -ADC #* 69 2 NOP 1 -ADC (*,X) 61 2 NOP 1 -ADC (*),Y 71 2 NOP 1 -ADC (*) 72 2 NOP 2 -ADC *,X 7D 3 ZP 1 -ADC *,Y 79 3 NOP 1 -ADC * 6D 3 ZP 1 - -AND #* 29 2 NOP 1 -AND (*,X) 21 2 NOP 1 -AND (*),Y 31 2 NOP 1 -AND (*) 32 2 NOP 2 -AND *,X 3D 3 ZP 1 -AND *,Y 39 3 NOP 1 -AND * 2D 3 ZP 1 - -ASL A 0A 1 NOP 1 -ASL *,X 1E 3 ZP 1 -ASL * 0E 3 ZP 1 - -BBR0 *,* 0f 3 CR 6 -BBR1 *,* 1f 3 CR 6 -BBR2 *,* 2f 3 CR 6 -BBR3 *,* 3f 3 CR 6 -BBR4 *,* 4f 3 CR 6 -BBR5 *,* 5f 3 CR 6 -BBR6 *,* 6f 3 CR 6 -BBR7 *,* 7f 3 CR 6 - -BBS0 *,* 8f 3 CR 6 -BBS1 *,* 9f 3 CR 6 -BBS2 *,* af 3 CR 6 -BBS3 *,* bf 3 CR 6 -BBS4 *,* cf 3 CR 6 -BBS5 *,* df 3 CR 6 -BBS6 *,* ef 3 CR 6 -BBS7 *,* ff 3 CR 6 - -BCC * 90 2 R1 1 -BCS * B0 2 R1 1 -BEQ * F0 2 R1 1 -BMI * 30 2 R1 1 -BNE * D0 2 R1 1 -BPL * 10 2 R1 1 -BRA * 80 2 R1 6 -BVC * 50 2 R1 1 -BVS * 70 2 R1 1 - -BIT #* 89 2 NOP 2 -BIT *,X 3C 3 ZP 2 -BIT * 2C 3 ZP 1 - -BRK "" 00 1 NOP 1 - -CLC "" 18 1 NOP 1 -CLD "" D8 1 NOP 1 -CLI "" 58 1 NOP 1 -CLV "" B8 1 NOP 1 - -CMP #* C9 2 NOP 1 -CMP (*,X) C1 2 NOP 1 -CMP (*),Y D1 2 NOP 1 -CMP (*) D2 2 NOP 2 -CMP *,X DD 3 ZP 1 -CMP *,Y D9 3 NOP 1 -CMP * CD 3 ZP 1 - -CPX #* E0 2 NOP 1 -CPX * EC 3 ZP 1 - -CPY #* C0 2 NOP 1 -CPY * CC 3 ZP 1 - -DEC A 3A 1 NOP 2 -DEC *,X DE 3 ZP 1 -DEC * CE 3 ZP 1 - -DEX "" CA 1 NOP 1 -DEY "" 88 1 NOP 1 - -EOR #* 49 2 NOP 1 -EOR (*,X) 41 2 NOP 1 -EOR (*),Y 51 2 NOP 1 -EOR (*) 52 2 NOP 2 -EOR *,X 5D 3 ZP 1 -EOR *,Y 59 3 NOP 1 -EOR * 4D 3 ZP 1 - -INC A 1A 1 NOP 2 -INC *,X FE 3 ZP 1 -INC * EE 3 ZP 1 - -INX "" E8 1 NOP 1 -INY "" C8 1 NOP 1 - -JMP (*,X) 7C 3 NOP 2 -JMP (*) 6C 3 NOP 1 -JMP * 4C 3 NOP 1 - -JSR * 20 3 NOP 1 - -LDA #* A9 2 NOP 1 -LDA (*,X) A1 2 NOP 1 -LDA (*),Y B1 2 NOP 1 -LDA (*) B2 2 NOP 2 -LDA *,X BD 3 ZP 1 -LDA *,Y B9 3 NOP 1 -LDA * AD 3 ZP 1 - -LDX #* A2 2 NOP 1 -LDX *,Y BE 3 ZP 1 -LDX * AE 3 ZP 1 - -LDY #* A0 2 NOP 1 -LDY *,X BC 3 ZP 1 -LDY * AC 3 ZP 1 - -LSR A 4A 1 NOP 1 -LSR *,X 5E 3 ZP 1 -LSR * 4E 3 ZP 1 - -MUL "" 02 1 NOP 4 /* R65C00/21 only*/ - -NOP "" EA 1 NOP 1 - -ORA #* 09 2 NOP 1 -ORA (*,X) 01 2 NOP 1 -ORA (*),Y 11 2 NOP 1 -ORA (*) 12 2 NOP 2 -ORA *,X 1D 3 ZP 1 -ORA *,Y 19 3 NOP 1 -ORA * 0D 3 ZP 1 - -PHA "" 48 1 NOP 1 -PHP "" 08 1 NOP 1 -PHX "" DA 1 NOP 6 -PHY "" 5A 1 NOP 6 -PLA "" 68 1 NOP 1 -PLP "" 28 1 NOP 1 -PLX "" FA 1 NOP 6 -PLY "" 7A 1 NOP 6 - -RMB0 * 07 2 NOP 6 -RMB1 * 17 2 NOP 6 -RMB2 * 27 2 NOP 6 -RMB3 * 37 2 NOP 6 -RMB4 * 47 2 NOP 6 -RMB5 * 57 2 NOP 6 -RMB6 * 67 2 NOP 6 -RMB7 * 77 2 NOP 6 - -ROL A 2A 1 NOP 1 -ROL *,X 3E 3 ZP 1 -ROL * 2E 3 ZP 1 - -ROR A 6A 1 NOP 1 -ROR *,X 7E 3 ZP 1 -ROR * 6E 3 ZP 1 - -RTI "" 40 1 NOP 1 -RTS "" 60 1 NOP 1 - -SBC #* E9 2 NOP 1 -SBC (*,X) E1 2 NOP 1 -SBC (*),Y F1 2 NOP 1 -SBC (*) F2 2 NOP 2 -SBC *,X FD 3 ZP 1 -SBC *,Y F9 3 NOP 1 -SBC * ED 3 ZP 1 - -SEC "" 38 1 NOP 1 -SED "" F8 1 NOP 1 -SEI "" 78 1 NOP 1 - -SMB0 * 87 2 NOP 6 -SMB1 * 97 2 NOP 6 -SMB2 * a7 2 NOP 6 -SMB3 * b7 2 NOP 6 -SMB4 * c7 2 NOP 6 -SMB5 * d7 2 NOP 6 -SMB6 * e7 2 NOP 6 -SMB7 * f7 2 NOP 6 - -STA (*,X) 81 2 NOP 1 -STA (*),Y 91 2 NOP 1 -STA (*) 92 2 NOP 2 -STA *,X 9D 3 ZP 1 -STA *,Y 99 3 NOP 1 -STA * 8D 3 ZP 1 - -STX *,Y 96 2 ZP 1 -STX * 8E 3 ZP 1 - -STY *,X 94 2 NOP 1 -STY * 8C 3 ZP 1 - -STZ *,X 9e 3 ZP 2 -STZ * 9c 3 ZP 2 - -TAX "" AA 1 NOP 1 -TAY "" A8 1 NOP 1 -TRB * 1c 3 ZP 2 -TSB * 0c 3 ZP 2 -TSX "" BA 1 NOP 1 -TXA "" 8A 1 NOP 1 -TXS "" 9A 1 NOP 1 -TYA "" 98 1 NOP 1 - diff --git a/branches/s100/XSource/bin/TASM68.TAB b/branches/s100/XSource/bin/TASM68.TAB deleted file mode 100644 index 7b9f5190..00000000 --- a/branches/s100/XSource/bin/TASM68.TAB +++ /dev/null @@ -1,348 +0,0 @@ -"TASM 6800-6811 Assembler" -/**************************************************************************** -/* $Id: tasm68.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* Originally submitted by Richard P. White, June 4,1989 */ -/* Corrected and enhanced by T.N. Anderson, STI */ -/* Enhanced for the 68HC11 by George Blat, Nov 3, 1990 -/* Class bits defined as follows: -/* -/* bit 0 for 6800 -/* bit 1 for 6801/6803 -/* bit 2 for 68HC11 -/* -/* Note that TASM deviates from motorola syntax for BCLR, BSET, -/* BRCLR, and BRSET instructions. TASM requires commas between -/* each arg. Motorola requires white space before the make and -/* label args. - -.MSFIRST - -ABA "" 1B 1 NOP 1 -ABX "" 3A 1 NOP 2 -ABY "" 183A 2 NOP 4 - -ADCA #* 89 2 NOP 1 -ADCA *,Y 18A9 3 NOP 4 -ADCA *,X A9 2 NOP 1 -ADCA * B9 3 MZERO 1 - -ADCB #* C9 2 NOP 1 -ADCB *,Y 18E9 3 NOP 4 -ADCB *,X E9 2 NOP 1 -ADCB * F9 3 MZERO 1 - -ADDA #* 8B 2 NOP 1 -ADDA *,Y 18AB 3 NOP 4 -ADDA *,X AB 2 NOP 1 -ADDA * BB 3 MZERO 1 - -ADDB #* CB 2 NOP 1 -ADDB *,Y 18EB 3 NOP 4 -ADDB *,X EB 2 NOP 1 -ADDB * FB 3 MZERO 1 - -ADDD #* C3 3 SWAP 2 -ADDD *,Y 18E3 3 NOP 4 -ADDD *,X E3 2 NOP 2 -ADDD * F3 3 MZERO 2 - -ANDA #* 84 2 NOP 1 -ANDA *,Y 18A4 3 NOP 4 -ANDA *,X A4 2 NOP 1 -ANDA * B4 3 MZERO 1 - -ANDB #* C4 2 NOP 1 -ANDB *,Y 18E4 3 NOP 4 -ANDB *,X E4 2 NOP 1 -ANDB * F4 3 MZERO 1 - -ASL *,Y 1868 3 NOP 4 -ASL *,X 68 2 NOP 1 -ASL * 78 3 SWAP 1 -ASLA "" 48 1 NOP 1 -ASLB "" 58 1 NOP 1 -ASLD "" 05 1 NOP 2 - -ASR *,Y 1867 3 NOP 4 -ASR *,X 67 2 NOP 1 -ASR * 77 3 SWAP 1 -ASRA "" 47 1 NOP 1 -ASRB "" 57 1 NOP 1 - -BCC * 24 2 R1 1 -BCLR *,X,* 1D 3 COMB 4 -BCLR *,Y,* 181D 4 COMB 4 -BCLR *,#* 15 3 COMB 4 /* allow # since mask is immediate data -BCLR *,* 15 3 COMB 4 -BCS * 25 2 R1 1 -BEQ * 27 2 R1 1 -BGE * 2C 2 R1 1 -BGT * 2E 2 R1 1 -BHI * 22 2 R1 1 -BHS * 24 2 R1 1 -BITA #* 85 2 NOP 1 -BITA *,Y 18A5 3 NOP 4 -BITA *,X A5 2 NOP 1 -BITA * B5 3 MZERO 1 -BITB #* C5 2 NOP 1 -BITB *,Y 18E5 3 NOP 4 -BITB *,X E5 2 NOP 1 -BITB * F5 3 MZERO 1 -BLE * 2F 2 R1 1 -BLO * 25 2 R1 1 -BLS * 23 2 R1 1 -BLT * 2D 2 R1 1 -BMI * 2B 2 R1 1 -BNE * 26 2 R1 1 -BPL * 2A 2 R1 1 -BRA * 20 2 R1 1 -BRCLR *,X,*,* 1F 4 3REL 4 -BRCLR *,Y,*,* 181F 5 3REL 4 -BRCLR *,*,* 13 4 3REL 4 -BRN * 21 2 R1 2 /* NOT SURE ABOUT 6803 */ -BRSET *,X,*,* 1E 4 3REL 4 -BRSET *,Y,*,* 181E 5 3REL 4 -BRSET *,*,* 12 4 3REL 4 -BSET *,X,* 1C 3 COMB 4 -BSET *,Y,* 181C 4 COMB 4 -BSET *,#* 14 3 COMB 4 /* allow # -BSET *,* 14 3 COMB 4 -BSR * 8D 2 R1 1 -BVC * 28 2 R1 1 -BVS * 29 2 R1 1 -CBA "" 11 1 NOP 1 -CLC "" 0C 1 NOP 1 -CLI "" 0E 1 NOP 1 -CLR *,Y 186F 3 NOP 4 -CLR *,X 6F 2 NOP 1 -CLR * 7F 3 SWAP 1 -CLRA "" 4F 1 NOP 1 -CLRB "" 5F 1 NOP 1 -CLV "" 0A 1 NOP 1 -CMPA #* 81 2 NOP 1 -CMPA *,X A1 2 NOP 1 -CMPA *,Y 18A1 3 NOP 4 -CMPA * B1 3 MZERO 1 -CMPB #* C1 2 NOP 1 -CMPB *,Y 18E1 3 NOP 4 -CMPB *,X E1 2 NOP 1 -CMPB * F1 3 MZERO 1 -CMPD #* 1A83 4 SWAP 4 /* alias for CPD */ -CMPD *,X 1AA3 3 NOP 4 -CMPD *,Y CDA3 3 NOP 4 -CMPD * 1AB3 4 MZERO 4 -COM *,X 63 2 NOP 1 -COM *,Y 1863 3 NOP 4 -COM * 73 3 SWAP 1 -COMA "" 43 1 NOP 1 -COMB "" 53 1 NOP 1 -CPD #* 1A83 4 SWAP 4 -CPD *,X 1AA3 3 NOP 4 -CPD *,Y CDA3 3 NOP 4 -CPD * 1AB3 4 MZERO 4 -CPX #* 8C 3 SWAP 1 -CPX *,X AC 2 NOP 1 -CPX *,Y CDAC 3 NOP 4 -CPX * BC 3 MZERO 1 -CPY #* 188C 4 SWAP 4 -CPY *,Y 18AC 3 NOP 4 -CPY *,X 1AAC 3 NOP 4 -CPY * 18BC 4 MZERO 4 -DAA "" 19 1 NOP 1 -DEC *,Y 186A 3 NOP 4 -DEC *,X 6A 2 NOP 1 -DEC * 7A 3 SWAP 1 -DECA "" 4A 1 NOP 1 -DECB "" 5A 1 NOP 1 -DES "" 34 1 NOP 1 -DEX "" 09 1 NOP 1 -DEY "" 1809 2 NOP 4 -EORA #* 88 2 NOP 1 -EORA *,Y 18A8 3 NOP 4 -EORA *,X A8 2 NOP 1 -EORA * B8 3 MZERO 1 -EORB #* C8 2 NOP 1 -EORB *,Y 18E8 3 NOP 4 -EORB *,X E8 2 NOP 1 -EORB * F8 3 MZERO 1 -FDIV "" 03 1 NOP 4 -IDIV "" 02 1 NOP 4 -INC *,Y 186C 3 NOP 4 -INC *,X 6C 2 NOP 1 -INC * 7C 3 SWAP 1 -INCA "" 4C 1 NOP 1 -INCB "" 5C 1 NOP 1 -INS "" 31 1 NOP 1 -INX "" 08 1 NOP 1 -INY "" 1808 2 NOP 4 -JMP *,Y 186E 3 NOP 4 -JMP *,X 6E 2 NOP 1 -JMP * 7E 3 SWAP 1 -JSR *,Y 18AD 3 NOP 4 -JSR *,X AD 2 NOP 1 -JSR * BD 3 MZERO 1 - -LDAA #* 86 2 NOP 1 -LDAA *,Y 18A6 3 NOP 4 -LDAA *,X A6 2 NOP 1 -LDAA >* B6 3 SWAP 1 /* Force EXT mode */ -LDAA * B6 3 MZERO 1 - -LDAB #* C6 2 NOP 1 -LDAB *,Y 18E6 3 NOP 4 -LDAB *,X E6 2 NOP 1 -LDAB >* F6 3 SWAP 1 /* Force EXT mode */ -LDAB * F6 3 MZERO 1 - -LDD #* CC 3 SWAP 2 -LDD *,Y 18EC 3 NOP 4 -LDD *,X EC 2 NOP 2 -LDD >* FC 3 SWAP 2 /* Force EXT mode */ -LDD * FC 3 MZERO 2 - -LDS #* 8E 3 SWAP 1 -LDS *,Y 18AE 3 NOP 4 -LDS *,X AE 2 NOP 1 -LDS >* BE 3 SWAP 1 /* Force EXT mode */ -LDS * BE 3 MZERO 1 - -LDX #* CE 3 SWAP 1 -LDX *,X EE 2 NOP 1 -LDX *,Y CDEE 3 NOP 4 -LDX >* FE 3 SWAP 1 /* Force EXT mode */ -LDX * FE 3 MZERO 1 - -LDY #* 18CE 4 SWAP 4 -LDY *,Y 18EE 3 NOP 4 -LDY *,X 1AEE 3 NOP 4 -LDY >* 18FE 4 SWAP 4 /* Force EXT mode */ -LDY * 18FE 4 MZERO 4 - -LSL *,Y 1868 3 NOP 4 -LSL *,X 68 2 NOP 1 /*SAME AS ASL */ -LSL * 78 3 SWAP 1 -LSLA "" 48 1 NOP 1 -LSLB "" 58 1 NOP 1 -LSLD "" 05 1 NOP 2 -LSR *,Y 1864 3 NOP 4 -LSR *,X 64 2 NOP 1 -LSR * 74 3 SWAP 1 -LSRA "" 44 1 NOP 1 -LSRB "" 54 1 NOP 1 -LSRD "" 04 1 NOP 2 -MUL "" 3D 1 NOP 2 -NEG *,Y 1860 3 NOP 4 -NEG *,X 60 2 NOP 1 -NEG * 70 3 SWAP 1 -NEGA "" 40 1 NOP 1 -NEGB "" 50 1 NOP 1 -NOP "" 01 1 NOP 1 -ORAA #* 8A 2 NOP 1 -ORAA *,Y 18AA 3 NOP 4 -ORAA *,X AA 2 NOP 1 -ORAA * BA 3 MZERO 1 -ORAB #* CA 2 NOP 1 -ORAB *,Y 18EA 3 NOP 4 -ORAB *,X EA 2 NOP 1 -ORAB * FA 3 MZERO 1 -PSHA "" 36 1 NOP 1 -PSHB "" 37 1 NOP 1 -PSHX "" 3C 1 NOP 2 -PSHY "" 183C 2 NOP 4 -PULA "" 32 1 NOP 1 -PULB "" 33 1 NOP 1 -PULX "" 38 1 NOP 2 -PULY "" 1838 2 NOP 4 -ROL *,Y 1869 3 NOP 4 -ROL *,X 69 2 NOP 1 -ROL * 79 3 SWAP 1 -ROLA "" 49 1 NOP 1 -ROLB "" 59 1 NOP 1 -ROR *,Y 1866 3 NOP 4 -ROR *,X 66 2 NOP 1 -ROR * 76 3 SWAP 1 -RORA "" 46 1 NOP 1 -RORB "" 56 1 NOP 1 -RTI "" 3B 1 NOP 1 -RTS "" 39 1 NOP 1 -SBA "" 10 1 NOP 1 -SBCA #* 82 2 NOP 1 -SBCA *,Y 18A2 3 NOP 4 -SBCA *,X A2 2 NOP 1 -SBCA * B2 3 MZERO 1 -SBCB #* C2 2 NOP 1 -SBCB *,Y 18E2 3 NOP 4 -SBCB *,X E2 2 NOP 1 -SBCB * F2 3 MZERO 1 -SEC "" 0D 1 NOP 1 -SEI "" 0F 1 NOP 1 -SEV "" 0B 1 NOP 1 - -STAA *,Y 18A7 3 NOP 4 -STAA *,X A7 2 NOP 1 -STAA >* B7 3 SWAP 1 /* Force EXT mode */ -STAA * B7 3 MZERO 1 - -STAB *,Y 18E7 3 NOP 4 -STAB *,X E7 2 NOP 1 -STAB >* F7 3 SWAP 1 /* Force EXT mode */ -STAB * F7 3 MZERO 1 - -STD *,Y 18ED 3 NOP 4 -STD *,X ED 2 NOP 2 -STD >* FD 3 SWAP 2 /* Force EXT mode */ -STD * FD 3 MZERO 2 - -STOP "" CF 1 NOP 1 - -STS *,X AF 2 NOP 1 -STS *,Y 18AF 3 NOP 4 -STS >* BF 3 SWAP 1 /* Force EXT mode */ -STS * BF 3 MZERO 1 - -STX *,X EF 2 NOP 1 -STX *,Y CDEF 3 NOP 4 -STX >* FF 3 SWAP 1 /* Force EXT mode */ -STX * FF 3 MZERO 1 - -STY *,Y 18EF 3 NOP 4 -STY *,X 1AEF 3 NOP 4 -STY >* 18FF 4 SWAP 4 /* Force EXT mode */ -STY * 18FF 4 MZERO 4 - -SUBA #* 80 2 NOP 1 -SUBA *,Y 18A0 3 NOP 4 -SUBA *,X A0 2 NOP 1 -SUBA * B0 3 MZERO 1 - -SUBB #* C0 2 NOP 1 -SUBB *,Y 18E0 3 NOP 4 -SUBB *,X E0 2 NOP 1 -SUBB * F0 3 MZERO 1 - -SUBD #* 83 3 SWAP 2 -SUBD *,Y 18A3 3 NOP 4 -SUBD *,X A3 2 NOP 2 -SUBD * B3 3 MZERO 2 - -SWI "" 3F 1 NOP 1 -TAB "" 16 1 NOP 1 -TAP "" 06 1 NOP 1 -TBA "" 17 1 NOP 1 -TEST "" 00 1 NOP 1 -TPA "" 07 1 NOP 1 -TST *,Y 186D 3 NOP 4 -TST *,X 6D 2 NOP 1 -TST * 7D 3 SWAP 1 -TSTA "" 4D 1 NOP 1 -TSTB "" 5D 1 NOP 1 -TSX "" 30 1 NOP 1 -TSY "" 1830 2 NOP 4 -TXS "" 35 1 NOP 1 -TYS "" 1835 2 NOP 4 -WAI "" 3E 1 NOP 1 -XGDX "" 8F 1 NOP 4 -XGDY "" 188F 2 NOP 4 -/* That's all folks */ - diff --git a/branches/s100/XSource/bin/TASM70.TAB b/branches/s100/XSource/bin/TASM70.TAB deleted file mode 100644 index b1cc5e04..00000000 --- a/branches/s100/XSource/bin/TASM70.TAB +++ /dev/null @@ -1,290 +0,0 @@ -"TASM 7000 Assembler. " -/**************************************************************************** -/* $Id: tasm70.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* Table for TMS7000 micros -/* Note that the table does not require the 'Rnn' nomenclature -/* for reference of locations in the register file. Any expression -/* will do, the value of which indicates the register. This is more -/* flexible then making an entry like "ADC R*,A". -/* -/* TASM has trouble with the MOVD +(B),+ instruction so -/* we convert it to MOVD +[B],+ -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT OR */ -/*-------------------------------------------*/ -.ALTWILD+ - -ADC B,A 69 1 NOP 1 -ADC %+,A 29 2 NOP 1 -ADC %+,B 59 2 NOP 1 -ADC %+,+ 79 3 COMB 1 -ADC +,A 19 2 NOP 1 -ADC +,B 39 2 NOP 1 -ADC +,+ 49 3 COMB 1 - -ADD B,A 68 1 NOP 1 -ADD %+,A 28 2 NOP 1 -ADD %+,B 58 2 NOP 1 -ADD %+,+ 78 3 COMB 1 -ADD +,A 18 2 NOP 1 -ADD +,B 38 2 NOP 1 -ADD +,+ 48 3 COMB 1 - -AND B,A 63 1 NOP 1 -AND %+,A 23 2 NOP 1 -AND %+,B 53 2 NOP 1 -AND %+,+ 73 3 COMB 1 -AND +,A 13 2 NOP 1 -AND +,B 33 2 NOP 1 -AND +,+ 43 3 COMB 1 - -ANDP A,+ 83 2 NOP 1 -ANDP B,+ 93 2 NOP 1 -ANDP %+,+ A3 3 COMB 1 - -BTJO B,A,+ 66 2 R1 1 -BTJO %+,A,+ 26 3 CREL 1 -BTJO %+,B,+ 56 3 CREL 1 -BTJO %+,+,+ 76 4 3REL 1 -BTJO +,A,+ 16 3 CREL 1 -BTJO +,B,+ 36 3 CREL 1 -BTJO +,+,+ 46 4 3REL 1 - - -BTJOP A,+,+ 86 3 CREL 1 -BTJOP B,+,+ 96 3 CREL 1 -BTJOP %+,+,+ A6 4 3REL 1 - -BTJZ B,A,+ 67 2 R1 1 -BTJZ %+,A,+ 27 3 CREL 1 -BTJZ %+,B,+ 57 3 CREL 1 -BTJZ %+,+,+ 77 4 3REL 1 -BTJZ +,A,+ 17 3 CREL 1 -BTJZ +,B,+ 37 3 CREL 1 -BTJZ +,+,+ 47 4 3REL 1 - -BTJZP A,+,+ 87 3 CREL 1 -BTJZP B,+,+ 97 3 CREL 1 -BTJZP %+,+,+ A7 4 3REL 1 - -BR @+(B) AC 3 SWAP 1 -BR @+[B] AC 3 SWAP 1 -BR @+ 8C 3 SWAP 1 -BR *+ 9C 2 NOP 1 - -CALL @+(B) AE 3 SWAP 1 -CALL @+[B] AE 3 SWAP 1 -CALL @+ 8E 3 SWAP 1 -CALL *+ 9E 2 NOP 1 - -CLR A B5 1 NOP 1 -CLR B C5 1 NOP 1 -CLR + D5 2 NOP 1 - -CLRC "" B0 1 NOP 1 - -CMP B,A 6D 1 NOP 1 -CMP %+,A 2D 2 NOP 1 -CMP %+,B 5D 2 NOP 1 -CMP %+,+ 7D 3 COMB 1 -CMP +,A 1D 2 NOP 1 -CMP +,B 3D 2 NOP 1 -CMP +,+ 4D 3 COMB 1 - -CMPA @+(B) AD 3 SWAP 1 -CMPA @+[B] AD 3 SWAP 1 -CMPA @+ 8D 3 SWAP 1 -CMPA *+ 9D 2 NOP 1 - -DAC B,A 6E 1 NOP 1 -DAC %+,A 2E 2 NOP 1 -DAC %+,B 5E 2 NOP 1 -DAC %+,+ 7E 3 COMB 1 -DAC +,A 1E 2 NOP 1 -DAC +,B 3E 2 NOP 1 -DAC +,+ 4E 3 COMB 1 - -DEC A B2 1 NOP 1 -DEC B C2 1 NOP 1 -DEC + D2 2 NOP 1 - -DECD A BB 1 NOP 1 -DECD B CB 1 NOP 1 -DECD + DB 2 NOP 1 - -DINT "" 06 1 NOP 1 - -DJNZ A,+ BA 2 R1 1 -DJNZ B,+ CA 2 R1 1 -DJNZ +,+ DA 3 CREL 1 - -DSB B,A 6F 1 NOP 1 -DSB %+,A 2F 2 NOP 1 -DSB %+,B 5F 2 NOP 1 -DSB %+,+ 7F 3 COMB 1 -DSB +,A 1F 2 NOP 1 -DSB +,B 3F 2 NOP 1 -DSB +,+ 4F 3 COMB 1 - -EINT "" 05 1 NOP 1 - -IDLE "" 01 1 NOP 1 - -INC A B3 1 NOP 1 -INC B C3 1 NOP 1 -INC + D3 2 NOP 1 - -INV A B4 1 NOP 1 -INV B C4 1 NOP 1 -INV + D4 2 NOP 1 - -JMP + E0 2 R1 1 - -JC + E3 2 R1 1 -JEQ + E2 2 R1 1 -JGE + E5 2 R1 1 -JGT + E4 2 R1 1 -JHS + E3 2 R1 1 -JL + E7 2 R1 1 -JN + E1 2 R1 1 /+ ?? -JNC + E7 2 R1 1 -JNE + E6 2 R1 1 -JNZ + E6 2 R1 1 -JP + E4 2 R1 1 -JPZ + E5 2 R1 1 -JZ + E2 2 R1 1 - -LDA @+(B) AA 3 SWAP 1 -LDA @+[B] AA 3 SWAP 1 -LDA @+ 8A 3 SWAP 1 -LDA *+ 9A 2 NOP 1 - -LDSP "" 0D 1 NOP 1 - -MOV A,B C0 1 NOP 1 -MOV B,A 62 1 NOP 1 -MOV A,+ D0 2 NOP 1 -MOV B,+ D1 2 NOP 1 -MOV %+,A 22 2 NOP 1 -MOV %+,B 52 2 NOP 1 -MOV %+,+ 72 3 COMB 1 -MOV +,A 12 2 NOP 1 -MOV +,B 32 2 NOP 1 -MOV +,+ 42 3 COMB 1 - -MOVD %+[B],+ A8 4 CSWAP 1 -MOVD %+,+ 88 4 CSWAP 1 -MOVD +,+ 98 3 COMB 1 - -MOVP A,+ 82 2 NOP 1 -MOVP B,+ 92 2 NOP 1 -MOVP %+,+ A2 3 COMB 1 -MOVP +,A 80 2 NOP 1 -MOVP +,B 91 2 NOP 1 - -MPY B,A 6C 1 NOP 1 -MPY %+,A 2C 2 NOP 1 -MPY %+,B 5C 2 NOP 1 -MPY %+,+ 7C 3 COMB 1 -MPY +,A 1C 2 NOP 1 -MPY +,B 3C 2 NOP 1 -MPY +,+ 4C 3 COMB 1 - -NOP "" 00 1 NOP 1 - -OR B,A 64 1 NOP 1 -OR %+,A 24 2 NOP 1 -OR %+,B 54 2 NOP 1 -OR %+,+ 74 3 COMB 1 -OR +,A 14 2 NOP 1 -OR +,B 34 2 NOP 1 -OR +,+ 44 3 COMB 1 - -ORP A,+ 84 2 NOP 1 -ORP B,+ 94 2 NOP 1 -ORP %+,+ A4 3 COMB 1 - -POP A B9 1 NOP 1 -POP B C9 1 NOP 1 -POP ST 08 1 NOP 1 -POP + D9 2 NOP 1 -POPST "" 08 1 NOP 1 - -PUSH A B8 1 NOP 1 -PUSH B C8 1 NOP 1 -PUSH ST 0E 1 NOP 1 -PUSH + D8 2 NOP 1 -PUSHST "" 0E 1 NOP 1 - -RETI "" 0B 1 NOP 1 - -RETS "" 0A 1 NOP 1 - -RL A BE 1 NOP 1 -RL B CE 1 NOP 1 -RL + DE 2 NOP 1 - -RLC A BF 1 NOP 1 -RLC B CF 1 NOP 1 -RLC + DF 2 NOP 1 - -RR A BC 1 NOP 1 -RR B CC 1 NOP 1 -RR + DC 2 NOP 1 - -RRC A BD 1 NOP 1 -RRC B CD 1 NOP 1 -RRC + DD 2 NOP 1 - -SBB B,A 6B 1 NOP 1 -SBB %+,A 2B 2 NOP 1 -SBB %+,B 5B 2 NOP 1 -SBB %+,+ 7B 3 COMB 1 -SBB +,A 1B 2 NOP 1 -SBB +,B 3B 2 NOP 1 -SBB +,+ 4B 3 COMB 1 - -SETC "" 07 1 NOP 1 - -STA @+(B) AB 3 SWAP 1 -STA @+[B] AB 3 SWAP 1 -STA @+ 8B 3 SWAP 1 -STA *+ 9B 2 NOP 1 - -STSP "" 09 1 NOP 1 - -SUB B,A 6A 1 NOP 1 -SUB %+,A 2A 2 NOP 1 -SUB %+,B 5A 2 NOP 1 -SUB %+,+ 7A 3 COMB 1 -SUB +,A 1A 2 NOP 1 -SUB +,B 3A 2 NOP 1 -SUB +,+ 4A 3 COMB 1 - -SWAP A B7 1 NOP 1 -SWAP B C7 1 NOP 1 -SWAP + D7 2 NOP 1 - -TRAP + FF 1 SUB 1 - -TST A B0 1 NOP 1 -TSTA "" B0 1 NOP 1 -TST B C1 1 NOP 1 -TSTB "" C1 1 NOP 1 - -XCHB A B6 1 NOP 1 -XCHB + D6 2 NOP 1 - -XOR B,A 65 1 NOP 1 -XOR %+,A 25 2 NOP 1 -XOR %+,B 55 2 NOP 1 -XOR %+,+ 75 3 COMB 1 -XOR +,A 15 2 NOP 1 -XOR +,B 35 2 NOP 1 -XOR +,+ 45 3 COMB 1 - -XORP A,+ 85 2 NOP 1 -XORP B,+ 95 2 NOP 1 -XORP %+,+ A5 3 COMB 1 - diff --git a/branches/s100/XSource/bin/TASM80.TAB b/branches/s100/XSource/bin/TASM80.TAB deleted file mode 100644 index f644ccd4..00000000 --- a/branches/s100/XSource/bin/TASM80.TAB +++ /dev/null @@ -1,594 +0,0 @@ -"TASM Z80 Assembler. " -/**************************************************************************** -/* $Id: tasm80.tab 1.2 1998/02/28 14:31:22 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table -/* for the Z80 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Carl A. Wall, VE3APY. -/* -/* Class bits assigned as follows: -/* Bit-0 = Z80 (base instruction set) -/* Bit-1 = HD64180 (extended instructions) -/* See TASM manual for info on table structure. -/* -/*INSTR ARGS OP BYTES RULE CLASS SHIFT OR */ -/*-------------------------------------------*/ - -ADC A,(HL) 8E 1 NOP 1 -ADC A,(IX*) 8EDD 3 ZIX 1 -ADC A,(IY*) 8EFD 3 ZIX 1 -ADC A,A 8F 1 NOP 1 -ADC A,B 88 1 NOP 1 -ADC A,C 89 1 NOP 1 -ADC A,D 8A 1 NOP 1 -ADC A,E 8B 1 NOP 1 -ADC A,H 8C 1 NOP 1 -ADC A,L 8D 1 NOP 1 -ADC A,* CE 2 NOP 1 -ADC HL,BC 4AED 2 NOP 1 -ADC HL,DE 5AED 2 NOP 1 -ADC HL,HL 6AED 2 NOP 1 -ADC HL,SP 7AED 2 NOP 1 - -ADD A,(HL) 86 1 NOP 1 -ADD A,(IX*) 86DD 3 ZIX 1 -ADD A,(IY*) 86FD 3 ZIX 1 -ADD A,A 87 1 NOP 1 -ADD A,B 80 1 NOP 1 -ADD A,C 81 1 NOP 1 -ADD A,D 82 1 NOP 1 -ADD A,E 83 1 NOP 1 -ADD A,H 84 1 NOP 1 -ADD A,L 85 1 NOP 1 -ADD A,* C6 2 NOP 1 -ADD HL,BC 09 1 NOP 1 -ADD HL,DE 19 1 NOP 1 -ADD HL,HL 29 1 NOP 1 -ADD HL,SP 39 1 NOP 1 -ADD IX,BC 09DD 2 NOP 1 -ADD IX,DE 19DD 2 NOP 1 -ADD IX,IX 29DD 2 NOP 1 -ADD IX,SP 39DD 2 NOP 1 -ADD IY,BC 09FD 2 NOP 1 -ADD IY,DE 19FD 2 NOP 1 -ADD IY,IY 29FD 2 NOP 1 -ADD IY,SP 39FD 2 NOP 1 - -AND (HL) A6 1 NOP 1 -AND (IX*) A6DD 3 ZIX 1 -AND (IY*) A6FD 3 ZIX 1 -AND A A7 1 NOP 1 -AND B A0 1 NOP 1 -AND C A1 1 NOP 1 -AND D A2 1 NOP 1 -AND E A3 1 NOP 1 -AND H A4 1 NOP 1 -AND L A5 1 NOP 1 -AND * E6 2 NOP 1 - -BIT *,(HL) 46CB 2 ZBIT 1 -BIT *,(IX*) CBDD 4 ZBIT 1 0 4600 -BIT *,(IY*) CBFD 4 ZBIT 1 0 4600 -BIT *,A 47CB 2 ZBIT 1 -BIT *,B 40CB 2 ZBIT 1 -BIT *,C 41CB 2 ZBIT 1 -BIT *,D 42CB 2 ZBIT 1 -BIT *,E 43CB 2 ZBIT 1 -BIT *,H 44CB 2 ZBIT 1 -BIT *,L 45CB 2 ZBIT 1 - -CALL C,* DC 3 NOP 1 -CALL M,* FC 3 NOP 1 -CALL NC,* D4 3 NOP 1 -CALL NZ,* C4 3 NOP 1 -CALL P,* F4 3 NOP 1 -CALL PE,* EC 3 NOP 1 -CALL PO,* E4 3 NOP 1 -CALL Z,* CC 3 NOP 1 -CALL * CD 3 NOP 1 - -CCF "" 3F 1 NOP 1 - -CP (HL) BE 1 NOP 1 -CP (IX*) BEDD 3 ZIX 1 -CP (IY*) BEFD 3 ZIX 1 -CP A BF 1 NOP 1 -CP B B8 1 NOP 1 -CP C B9 1 NOP 1 -CP D BA 1 NOP 1 -CP E BB 1 NOP 1 -CP H BC 1 NOP 1 -CP L BD 1 NOP 1 -CP * FE 2 NOP 1 -CPD "" A9ED 2 NOP 1 -CPDR "" B9ED 2 NOP 1 -CPIR "" B1ED 2 NOP 1 -CPI "" A1ED 2 NOP 1 -CPL "" 2F 1 NOP 1 - -DAA "" 27 1 NOP 1 - -DEC (HL) 35 1 NOP 1 -DEC (IX*) 35DD 3 ZIX 1 -DEC (IY*) 35FD 3 ZIX 1 -DEC A 3D 1 NOP 1 -DEC B 05 1 NOP 1 -DEC BC 0B 1 NOP 1 -DEC C 0D 1 NOP 1 -DEC D 15 1 NOP 1 -DEC DE 1B 1 NOP 1 -DEC E 1D 1 NOP 1 -DEC H 25 1 NOP 1 -DEC HL 2B 1 NOP 1 -DEC IX 2BDD 2 NOP 1 -DEC IY 2BFD 2 NOP 1 -DEC L 2D 1 NOP 1 -DEC SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -DJNZ * 10 2 R1 1 - -EI "" FB 1 NOP 1 -EX (SP),HL E3 1 NOP 1 -EX (SP),IX E3DD 2 NOP 1 -EX (SP),IY E3FD 2 NOP 1 -EX AF,AF' 08 1 NOP 1 -EX DE,HL EB 1 NOP 1 -EXX "" D9 1 NOP 1 -HALT "" 76 1 NOP 1 - -IM 0 46ED 2 NOP 1 -IM 1 56ED 2 NOP 1 -IM 2 5EED 2 NOP 1 - -/* Alternate form of above -IM0 46ED 2 NOP 1 -IM1 56ED 2 NOP 1 -IM2 5EED 2 NOP 1 - -IN A,(C) 78ED 2 NOP 1 -IN B,(C) 40ED 2 NOP 1 -IN C,(C) 48ED 2 NOP 1 -IN D,(C) 50ED 2 NOP 1 -IN E,(C) 58ED 2 NOP 1 -IN H,(C) 60ED 2 NOP 1 -IN L,(C) 68ED 2 NOP 1 - -IN A,(*) DB 2 NOP 1 - -IN0 A,(*) 38ED 3 NOP 2 -IN0 B,(*) 00ED 3 NOP 2 -IN0 C,(*) 08ED 3 NOP 2 -IN0 D,(*) 10ED 3 NOP 2 -IN0 E,(*) 18ED 3 NOP 2 -IN0 H,(*) 20ED 3 NOP 2 -IN0 L,(*) 28ED 3 NOP 2 - -INC (HL) 34 1 NOP 1 -INC (IX*) 34DD 3 ZIX 1 -INC (IY*) 34FD 3 ZIX 1 -INC A 3C 1 NOP 1 -INC B 04 1 NOP 1 -INC BC 03 1 NOP 1 -INC C 0C 1 NOP 1 -INC D 14 1 NOP 1 -INC DE 13 1 NOP 1 -INC E 1C 1 NOP 1 -INC H 24 1 NOP 1 -INC HL 23 1 NOP 1 -INC IX 23DD 2 NOP 1 -INC IY 23FD 2 NOP 1 -INC L 2C 1 NOP 1 -INC SP 33 1 NOP 1 - - -IND "" AAED 2 NOP 1 -INDR "" BAED 2 NOP 1 -INI "" A2ED 2 NOP 1 -INIR "" B2ED 2 NOP 1 - -JP (HL) E9 1 NOP 1 -JP (IX) E9DD 2 NOP 1 -JP (IY) E9FD 2 NOP 1 -JP C,* DA 3 NOP 1 -JP M,* FA 3 NOP 1 -JP NC,* D2 3 NOP 1 -JP NZ,* C2 3 NOP 1 -JP P,* F2 3 NOP 1 -JP PE,* EA 3 NOP 1 -JP PO,* E2 3 NOP 1 -JP Z,* CA 3 NOP 1 -JP * C3 3 NOP 1 - -JR C,* 38 2 R1 1 -JR NC,* 30 2 R1 1 -JR NZ,* 20 2 R1 1 -JR Z,* 28 2 R1 1 -JR * 18 2 R1 1 - -LD (BC),A 02 1 NOP 1 -LD (DE),A 12 1 NOP 1 -LD (HL),A 77 1 NOP 1 -LD (HL),B 70 1 NOP 1 -LD (HL),C 71 1 NOP 1 -LD (HL),D 72 1 NOP 1 -LD (HL),E 73 1 NOP 1 -LD (HL),H 74 1 NOP 1 -LD (HL),L 75 1 NOP 1 -LD (HL),* 36 2 NOP 1 -LD (IX*),A 77DD 3 ZIX 1 -LD (IX*),B 70DD 3 ZIX 1 -LD (IX*),C 71DD 3 ZIX 1 -LD (IX*),D 72DD 3 ZIX 1 -LD (IX*),E 73DD 3 ZIX 1 -LD (IX*),H 74DD 3 ZIX 1 -LD (IX*),L 75DD 3 ZIX 1 -LD (IX*),* 36DD 4 ZIX 1 -LD (IY*),A 77FD 3 ZIX 1 -LD (IY*),B 70FD 3 ZIX 1 -LD (IY*),C 71FD 3 ZIX 1 -LD (IY*),D 72FD 3 ZIX 1 -LD (IY*),E 73FD 3 ZIX 1 -LD (IY*),H 74FD 3 ZIX 1 -LD (IY*),L 75FD 3 ZIX 1 -LD (IY*),* 36FD 4 ZIX 1 -LD (*),A 32 3 NOP 1 -LD (*),BC 43ED 4 NOP 1 -LD (*),DE 53ED 4 NOP 1 -LD (*),HL 22 3 NOP 1 -LD (*),IX 22DD 4 NOP 1 -LD (*),IY 22FD 4 NOP 1 -LD (*),SP 73ED 4 NOP 1 -LD A,(BC) 0A 1 NOP 1 -LD A,(DE) 1A 1 NOP 1 -LD A,(HL) 7E 1 NOP 1 -LD A,(IX*) 7EDD 3 ZIX 1 -LD A,(IY*) 7EFD 3 ZIX 1 -LD A,A 7F 1 NOP 1 -LD A,B 78 1 NOP 1 -LD A,C 79 1 NOP 1 -LD A,D 7A 1 NOP 1 -LD A,E 7B 1 NOP 1 -LD A,H 7C 1 NOP 1 -LD A,I 57ED 2 NOP 1 -LD A,L 7D 1 NOP 1 -LD A,R 5FED 2 NOP 1 -LD A,(*) 3A 3 NOP 1 -LD A,* 3E 2 NOP 1 -LD B,(HL) 46 1 NOP 1 -LD B,(IX*) 46DD 3 ZIX 1 -LD B,(IY*) 46FD 3 ZIX 1 -LD B,A 47 1 NOP 1 -LD B,B 40 1 NOP 1 -LD B,C 41 1 NOP 1 -LD B,D 42 1 NOP 1 -LD B,E 43 1 NOP 1 -LD B,H 44 1 NOP 1 -LD B,L 45 1 NOP 1 -LD B,* 06 2 NOP 1 -LD BC,(*) 4BED 4 NOP 1 -LD BC,* 01 3 NOP 1 -LD C,(HL) 4E 1 NOP 1 -LD C,(IX*) 4EDD 3 ZIX 1 -LD C,(IY*) 4EFD 3 ZIX 1 -LD C,A 4F 1 NOP 1 -LD C,B 48 1 NOP 1 -LD C,C 49 1 NOP 1 -LD C,D 4A 1 NOP 1 -LD C,E 4B 1 NOP 1 -LD C,H 4C 1 NOP 1 -LD C,L 4D 1 NOP 1 -LD C,* 0E 2 NOP 1 -LD D,(HL) 56 1 NOP 1 -LD D,(IX*) 56DD 3 ZIX 1 -LD D,(IY*) 56FD 3 ZIX 1 -LD D,A 57 1 NOP 1 -LD D,B 50 1 NOP 1 -LD D,C 51 1 NOP 1 -LD D,D 52 1 NOP 1 -LD D,E 53 1 NOP 1 -LD D,H 54 1 NOP 1 -LD D,L 55 1 NOP 1 -LD D,* 16 2 NOP 1 -LD DE,(*) 5BED 4 NOP 1 -LD DE,* 11 3 NOP 1 -LD E,(HL) 5E 1 NOP 1 -LD E,(IX*) 5EDD 3 ZIX 1 -LD E,(IY*) 5EFD 3 ZIX 1 -LD E,A 5F 1 NOP 1 -LD E,B 58 1 NOP 1 -LD E,C 59 1 NOP 1 -LD E,D 5A 1 NOP 1 -LD E,E 5B 1 NOP 1 -LD E,H 5C 1 NOP 1 -LD E,L 5D 1 NOP 1 -LD E,* 1E 2 NOP 1 -LD H,(HL) 66 1 NOP 1 -LD H,(IX*) 66DD 3 ZIX 1 -LD H,(IY*) 66FD 3 ZIX 1 -LD H,A 67 1 NOP 1 -LD H,B 60 1 NOP 1 -LD H,C 61 1 NOP 1 -LD H,D 62 1 NOP 1 -LD H,E 63 1 NOP 1 -LD H,H 64 1 NOP 1 -LD H,L 65 1 NOP 1 -LD H,* 26 2 NOP 1 -LD HL,(*) 2A 3 NOP 1 -LD HL,* 21 3 NOP 1 -LD I,A 47ED 2 NOP 1 -LD IX,(*) 2ADD 4 NOP 1 -LD IX,* 21DD 4 NOP 1 -LD IY,(*) 2AFD 4 NOP 1 -LD IY,* 21FD 4 NOP 1 -LD L,(HL) 6E 1 NOP 1 -LD L,(IX*) 6EDD 3 ZIX 1 -LD L,(IY*) 6EFD 3 ZIX 1 -LD L,A 6F 1 NOP 1 -LD L,B 68 1 NOP 1 -LD L,C 69 1 NOP 1 -LD L,D 6A 1 NOP 1 -LD L,E 6B 1 NOP 1 -LD L,H 6C 1 NOP 1 -LD L,L 6D 1 NOP 1 -LD L,* 2E 2 NOP 1 -LD R,A 4FED 2 NOP 1 -LD SP,(*) 7BED 4 NOP 1 -LD SP,HL F9 1 NOP 1 -LD SP,IX F9DD 2 NOP 1 -LD SP,IY F9FD 2 NOP 1 -LD SP,* 31 3 NOP 1 -LDD "" A8ED 2 NOP 1 -LDDR "" B8ED 2 NOP 1 -LDI "" A0ED 2 NOP 1 -LDIR "" B0ED 2 NOP 1 -NEG "" 44ED 2 NOP 1 -NOP "" 00 1 NOP 1 - -MLT BC 4CED 2 NOP 2 -MLT DE 5CED 2 NOP 2 -MLT HL 6CED 2 NOP 2 -MLT SP 7CED 2 NOP 2 - -OR (HL) B6 1 NOP 1 -OR (IX*) B6DD 3 ZIX 1 -OR (IY*) B6FD 3 ZIX 1 -OR A B7 1 NOP 1 -OR B B0 1 NOP 1 -OR C B1 1 NOP 1 -OR D B2 1 NOP 1 -OR E B3 1 NOP 1 -OR H B4 1 NOP 1 -OR L B5 1 NOP 1 -OR * F6 2 NOP 1 - -OTDM "" 8BED 2 NOP 2 -OTDMR "" 9BED 2 NOP 2 -OTDR "" BBED 2 NOP 1 -OTIM "" 83ED 2 NOP 2 -OTIMR "" 93ED 2 NOP 2 -OTIR "" B3ED 2 NOP 1 - -OUT (C),A 79ED 2 NOP 1 -OUT (C),B 41ED 2 NOP 1 -OUT (C),C 49ED 2 NOP 1 -OUT (C),D 51ED 2 NOP 1 -OUT (C),E 59ED 2 NOP 1 -OUT (C),H 61ED 2 NOP 1 -OUT (C),L 69ED 2 NOP 1 -OUT (*),A D3 2 NOP 1 - -OUT0 (*),A 39ED 3 NOP 2 -OUT0 (*),B 01ED 3 NOP 2 -OUT0 (*),C 09ED 3 NOP 2 -OUT0 (*),D 11ED 3 NOP 2 -OUT0 (*),E 19ED 3 NOP 2 -OUT0 (*),H 21ED 3 NOP 2 -OUT0 (*),L 29ED 3 NOP 2 - -OUTD "" ABED 2 NOP 1 -OUTI "" A3ED 2 NOP 1 - -POP AF F1 1 NOP 1 -POP BC C1 1 NOP 1 -POP DE D1 1 NOP 1 -POP HL E1 1 NOP 1 -POP IX E1DD 2 NOP 1 -POP IY E1FD 2 NOP 1 - -PUSH AF F5 1 NOP 1 -PUSH BC C5 1 NOP 1 -PUSH DE D5 1 NOP 1 -PUSH HL E5 1 NOP 1 -PUSH IX E5DD 2 NOP 1 -PUSH IY E5FD 2 NOP 1 - -RES *,(HL) 86CB 2 ZBIT 1 -RES *,(IX*) CBDD 4 ZBIT 1 0 8600 -RES *,(IY*) CBFD 4 ZBIT 1 0 8600 -RES *,A 87CB 2 ZBIT 1 -RES *,B 80CB 2 ZBIT 1 -RES *,C 81CB 2 ZBIT 1 -RES *,D 82CB 2 ZBIT 1 -RES *,E 83CB 2 ZBIT 1 -RES *,H 84CB 2 ZBIT 1 -RES *,L 85CB 2 ZBIT 1 - -RET "" C9 1 NOP 1 -RET C D8 1 NOP 1 -RET M F8 1 NOP 1 -RET NC D0 1 NOP 1 -RET NZ C0 1 NOP 1 -RET P F0 1 NOP 1 -RET PE E8 1 NOP 1 -RET PO E0 1 NOP 1 -RET Z C8 1 NOP 1 -RETI "" 4DED 2 NOP 1 -RETN "" 45ED 2 NOP 1 - -RL (HL) 16CB 2 NOP 1 -RL (IX*) CBDD 4 ZIX 1 0 1600 -RL (IY*) CBFD 4 ZIX 1 0 1600 -RL A 17CB 2 NOP 1 -RL B 10CB 2 NOP 1 -RL C 11CB 2 NOP 1 -RL D 12CB 2 NOP 1 -RL E 13CB 2 NOP 1 -RL H 14CB 2 NOP 1 -RL L 15CB 2 NOP 1 -RLA "" 17 1 NOP 1 - -RLC (HL) 06CB 2 NOP 1 -RLC (IX*) CBDD 4 ZIX 1 0 0600 -RLC (IY*) CBFD 4 ZIX 1 0 0600 -RLC A 07CB 2 NOP 1 -RLC B 00CB 2 NOP 1 -RLC C 01CB 2 NOP 1 -RLC D 02CB 2 NOP 1 -RLC E 03CB 2 NOP 1 -RLC H 04CB 2 NOP 1 -RLC L 05CB 2 NOP 1 -RLCA "" 07 1 NOP 1 -RLD "" 6FED 2 NOP 1 - -RR (HL) 1ECB 2 NOP 1 -RR (IX*) CBDD 4 ZIX 1 0 1E00 -RR (IY*) CBFD 4 ZIX 1 0 1E00 -RR A 1FCB 2 NOP 1 -RR B 18CB 2 NOP 1 -RR C 19CB 2 NOP 1 -RR D 1ACB 2 NOP 1 -RR E 1BCB 2 NOP 1 -RR H 1CCB 2 NOP 1 -RR L 1DCB 2 NOP 1 -RRA "" 1F 1 NOP 1 -RRC (HL) 0ECB 2 NOP 1 -RRC (IX*) CBDD 4 ZIX 1 0 0E00 -RRC (IY*) CBFD 4 ZIX 1 0 0E00 -RRC A 0FCB 2 NOP 1 -RRC B 08CB 2 NOP 1 -RRC C 09CB 2 NOP 1 -RRC D 0ACB 2 NOP 1 -RRC E 0BCB 2 NOP 1 -RRC H 0CCB 2 NOP 1 -RRC L 0DCB 2 NOP 1 -RRCA "" 0F 1 NOP 1 -RRD "" 67ED 2 NOP 1 - -RST 00H C7 1 NOP 1 -RST 08H CF 1 NOP 1 -RST 10H D7 1 NOP 1 -RST 18H DF 1 NOP 1 -RST 20H E7 1 NOP 1 -RST 28H EF 1 NOP 1 -RST 30H F7 1 NOP 1 -RST 38H FF 1 NOP 1 - -/* Alternate form of above -RST 00 C7 1 NOP 1 -RST 08 CF 1 NOP 1 -RST 10 D7 1 NOP 1 -RST 18 DF 1 NOP 1 -RST 20 E7 1 NOP 1 -RST 28 EF 1 NOP 1 -RST 30 F7 1 NOP 1 -RST 38 FF 1 NOP 1 - -SBC A,(HL) 9E 1 NOP 1 -SBC A,(IX*) 9EDD 3 ZIX 1 -SBC A,(IY*) 9EFD 3 ZIX 1 -SBC A,A 9F 1 NOP 1 -SBC A,B 98 1 NOP 1 -SBC A,C 99 1 NOP 1 -SBC A,D 9A 1 NOP 1 -SBC A,E 9B 1 NOP 1 -SBC A,H 9C 1 NOP 1 -SBC A,L 9D 1 NOP 1 -SBC HL,BC 42ED 2 NOP 1 -SBC HL,DE 52ED 2 NOP 1 -SBC HL,HL 62ED 2 NOP 1 -SBC HL,SP 72ED 2 NOP 1 -SBC A,* DE 2 NOP 1 -SCF "" 37 1 NOP 1 - -SET *,(HL) C6CB 2 ZBIT 1 -SET *,(IX*) CBDD 4 ZBIT 1 0 C600 -SET *,(IY*) CBFD 4 ZBIT 1 0 C600 -SET *,A C7CB 2 ZBIT 1 -SET *,B C0CB 2 ZBIT 1 -SET *,C C1CB 2 ZBIT 1 -SET *,D C2CB 2 ZBIT 1 -SET *,E C3CB 2 ZBIT 1 -SET *,H C4CB 2 ZBIT 1 -SET *,L C5CB 2 ZBIT 1 - -SLA (HL) 26CB 2 NOP 1 -SLA (IX*) CBDD 4 ZIX 1 0 2600 -SLA (IY*) CBFD 4 ZIX 1 0 2600 -SLA A 27CB 2 NOP 1 -SLA B 20CB 2 NOP 1 -SLA C 21CB 2 NOP 1 -SLA D 22CB 2 NOP 1 -SLA E 23CB 2 NOP 1 -SLA H 24CB 2 NOP 1 -SLA L 25CB 2 NOP 1 - -SLP "" 76ED 2 NOP 2 - -SRA (HL) 2ECB 2 NOP 1 -SRA (IX*) CBDD 4 ZIX 1 0 2E00 -SRA (IY*) CBFD 4 ZIX 1 0 2E00 -SRA A 2FCB 2 NOP 1 -SRA B 28CB 2 NOP 1 -SRA C 29CB 2 NOP 1 -SRA D 2ACB 2 NOP 1 -SRA E 2BCB 2 NOP 1 -SRA H 2CCB 2 NOP 1 -SRA L 2DCB 2 NOP 1 - -SRL (HL) 3ECB 2 NOP 1 -SRL (IX*) CBDD 4 ZIX 1 0 3E00 -SRL (IY*) CBFD 4 ZIX 1 0 3E00 -SRL A 3FCB 2 NOP 1 -SRL B 38CB 2 NOP 1 -SRL C 39CB 2 NOP 1 -SRL D 3ACB 2 NOP 1 -SRL E 3BCB 2 NOP 1 -SRL H 3CCB 2 NOP 1 -SRL L 3DCB 2 NOP 1 - -SUB (HL) 96 1 NOP 1 -SUB (IX*) 96DD 3 ZIX 1 -SUB (IY*) 96FD 3 ZIX 1 -SUB A 97 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB * D6 2 NOP 1 - -TST A 3CED 2 NOP 2 -TST B 04ED 2 NOP 2 -TST C 0CED 2 NOP 2 -TST D 14ED 2 NOP 2 -TST E 1CED 2 NOP 2 -TST H 24ED 2 NOP 2 -TST L 2CED 2 NOP 2 -TST (HL) 34ED 2 NOP 2 -TST * 64ED 3 NOP 2 - -TSTIO * 74ED 3 NOP 2 - -XOR (HL) AE 1 NOP 1 -XOR (IX*) AEDD 3 ZIX 1 -XOR (IY*) AEFD 3 ZIX 1 -XOR A AF 1 NOP 1 -XOR B A8 1 NOP 1 -XOR C A9 1 NOP 1 -XOR D AA 1 NOP 1 -XOR E AB 1 NOP 1 -XOR H AC 1 NOP 1 -XOR L AD 1 NOP 1 -XOR * EE 2 NOP 1 diff --git a/branches/s100/XSource/bin/TASM85.TAB b/branches/s100/XSource/bin/TASM85.TAB deleted file mode 100644 index 83c866bb..00000000 --- a/branches/s100/XSource/bin/TASM85.TAB +++ /dev/null @@ -1,257 +0,0 @@ -"TASM 8085 Assembler. " -/**************************************************************************** -/* $Id: tasm85.tab 1.1 1993/07/31 01:12:40 toma Exp $ -/**************************************************************************** -/* This is the instruction set definition table for the 8085 version of TASM. -/* Thomas N. Anderson, Speech Technology Incorporated -/* This table authored and submitted by Gary Kirk Bach. -/* -/*INSTR ARGS OPCODE BYTES MOD CLASS */ -/*-----------------*/ -ACI * CE 2 NOP 1 -ADC B 88 1 NOP 1 -ADC C 89 1 NOP 1 -ADC D 8A 1 NOP 1 -ADC E 8B 1 NOP 1 -ADC H 8C 1 NOP 1 -ADC L 8D 1 NOP 1 -ADC M 8E 1 NOP 1 -ADC A 8F 1 NOP 1 -ADD B 80 1 NOP 1 -ADD C 81 1 NOP 1 -ADD D 82 1 NOP 1 -ADD E 83 1 NOP 1 -ADD H 84 1 NOP 1 -ADD L 85 1 NOP 1 -ADD M 86 1 NOP 1 -ADD A 87 1 NOP 1 -ADI * C6 2 NOP 1 -ANA B A0 1 NOP 1 -ANA C A1 1 NOP 1 -ANA D A2 1 NOP 1 -ANA E A3 1 NOP 1 -ANA H A4 1 NOP 1 -ANA L A5 1 NOP 1 -ANA M A6 1 NOP 1 -ANA A A7 1 NOP 1 -ANI * E6 2 NOP 1 -CALL * CD 3 NOP 1 -CC * DC 3 NOP 1 -CM * FC 3 NOP 1 -CMA "" 2F 1 NOP 1 -CMC "" 3F 1 NOP 1 -CMP B B8 1 NOP 1 -CMP C B9 1 NOP 1 -CMP D BA 1 NOP 1 -CMP E BB 1 NOP 1 -CMP H BC 1 NOP 1 -CMP L BD 1 NOP 1 -CMP M BE 1 NOP 1 -CMP A BF 1 NOP 1 -CNC * D4 3 NOP 1 -CNZ * C4 3 NOP 1 -CP * F4 3 NOP 1 -CPE * EC 3 NOP 1 -CPI * FE 2 NOP 1 -CPO * E4 3 NOP 1 -CZ * CC 3 NOP 1 -DAA "" 27 1 NOP 1 -DAD B 09 1 NOP 1 -DAD D 19 1 NOP 1 -DAD H 29 1 NOP 1 -DAD SP 39 1 NOP 1 -DCR B 05 1 NOP 1 -DCR C 0D 1 NOP 1 -DCR D 15 1 NOP 1 -DCR E 1D 1 NOP 1 -DCR H 25 1 NOP 1 -DCR L 2D 1 NOP 1 -DCR M 35 1 NOP 1 -DCR A 3D 1 NOP 1 -DCX B 0B 1 NOP 1 -DCX D 1B 1 NOP 1 -DCX H 2B 1 NOP 1 -DCX SP 3B 1 NOP 1 -DI "" F3 1 NOP 1 -EI "" FB 1 NOP 1 -HLT "" 76 1 NOP 1 -IN * DB 2 NOP 1 -INR B 04 1 NOP 1 -INR C 0C 1 NOP 1 -INR D 14 1 NOP 1 -INR E 1C 1 NOP 1 -INR H 24 1 NOP 1 -INR L 2C 1 NOP 1 -INR M 34 1 NOP 1 -INR A 3C 1 NOP 1 -INX B 03 1 NOP 1 -INX D 13 1 NOP 1 -INX H 23 1 NOP 1 -INX SP 33 1 NOP 1 -JC * DA 3 NOP 1 -JM * FA 3 NOP 1 -JMP * C3 3 NOP 1 -JNC * D2 3 NOP 1 -JNZ * C2 3 NOP 1 -JP * F2 3 NOP 1 -JPE * EA 3 NOP 1 -JPO * E2 3 NOP 1 -JZ * CA 3 NOP 1 -LDA * 3A 3 NOP 1 -LDAX B 0A 1 NOP 1 -LDAX D 1A 1 NOP 1 -LHLD * 2A 3 NOP 1 -LXI B,* 01 3 NOP 1 -LXI D,* 11 3 NOP 1 -LXI H,* 21 3 NOP 1 -LXI SP,* 31 3 NOP 1 -MOV B,B 40 1 NOP 1 -MOV B,C 41 1 NOP 1 -MOV B,D 42 1 NOP 1 -MOV B,E 43 1 NOP 1 -MOV B,H 44 1 NOP 1 -MOV B,L 45 1 NOP 1 -MOV B,M 46 1 NOP 1 -MOV B,A 47 1 NOP 1 -MOV C,B 48 1 NOP 1 -MOV C,C 49 1 NOP 1 -MOV C,D 4A 1 NOP 1 -MOV C,E 4B 1 NOP 1 -MOV C,H 4C 1 NOP 1 -MOV C,L 4D 1 NOP 1 -MOV C,M 4E 1 NOP 1 -MOV C,A 4F 1 NOP 1 -MOV D,B 50 1 NOP 1 -MOV D,C 51 1 NOP 1 -MOV D,D 52 1 NOP 1 -MOV D,E 53 1 NOP 1 -MOV D,H 54 1 NOP 1 -MOV D,L 55 1 NOP 1 -MOV D,M 56 1 NOP 1 -MOV D,A 57 1 NOP 1 -MOV E,B 58 1 NOP 1 -MOV E,C 59 1 NOP 1 -MOV E,D 5A 1 NOP 1 -MOV E,E 5B 1 NOP 1 -MOV E,H 5C 1 NOP 1 -MOV E,L 5D 1 NOP 1 -MOV E,M 5E 1 NOP 1 -MOV E,A 5F 1 NOP 1 -MOV H,B 60 1 NOP 1 -MOV H,C 61 1 NOP 1 -MOV H,D 62 1 NOP 1 -MOV H,E 63 1 NOP 1 -MOV H,H 64 1 NOP 1 -MOV H,L 65 1 NOP 1 -MOV H,M 66 1 NOP 1 -MOV H,A 67 1 NOP 1 -MOV L,B 68 1 NOP 1 -MOV L,C 69 1 NOP 1 -MOV L,D 6A 1 NOP 1 -MOV L,E 6B 1 NOP 1 -MOV L,H 6C 1 NOP 1 -MOV L,L 6D 1 NOP 1 -MOV L,M 6E 1 NOP 1 -MOV L,A 6F 1 NOP 1 -MOV M,B 70 1 NOP 1 -MOV M,C 71 1 NOP 1 -MOV M,D 72 1 NOP 1 -MOV M,E 73 1 NOP 1 -MOV M,H 74 1 NOP 1 -MOV M,L 75 1 NOP 1 -MOV M,A 77 1 NOP 1 -MOV A,B 78 1 NOP 1 -MOV A,C 79 1 NOP 1 -MOV A,D 7A 1 NOP 1 -MOV A,E 7B 1 NOP 1 -MOV A,H 7C 1 NOP 1 -MOV A,L 7D 1 NOP 1 -MOV A,M 7E 1 NOP 1 -MOV A,A 7F 1 NOP 1 -MVI B,* 06 2 NOP 1 -MVI C,* 0E 2 NOP 1 -MVI D,* 16 2 NOP 1 -MVI E,* 1E 2 NOP 1 -MVI H,* 26 2 NOP 1 -MVI L,* 2E 2 NOP 1 -MVI M,* 36 2 NOP 1 -MVI A,* 3E 2 NOP 1 -NOP "" 00 1 NOP 1 -ORA B B0 1 NOP 1 -ORA C B1 1 NOP 1 -ORA D B2 1 NOP 1 -ORA E B3 1 NOP 1 -ORA H B4 1 NOP 1 -ORA L B5 1 NOP 1 -ORA M B6 1 NOP 1 -ORA A B7 1 NOP 1 -ORI * F6 2 NOP 1 -OUT * D3 2 NOP 1 -PCHL "" E9 1 NOP 1 -POP B C1 1 NOP 1 -POP D D1 1 NOP 1 -POP H E1 1 NOP 1 -POP PSW F1 1 NOP 1 -PUSH B C5 1 NOP 1 -PUSH D D5 1 NOP 1 -PUSH H E5 1 NOP 1 -PUSH PSW F5 1 NOP 1 -RAL "" 17 1 NOP 1 -RAR "" 1F 1 NOP 1 -RC "" D8 1 NOP 1 -RET "" C9 1 NOP 1 -RIM "" 20 1 NOP 1 -RLC "" 07 1 NOP 1 -RM "" F8 1 NOP 1 -RNC "" D0 1 NOP 1 -RNZ "" C0 1 NOP 1 -RP "" F0 1 NOP 1 -RPE "" E8 1 NOP 1 -RPO "" E0 1 NOP 1 -RRC "" 0F 1 NOP 1 -RST 0 C7 1 NOP 1 -RST 1 CF 1 NOP 1 -RST 2 D7 1 NOP 1 -RST 3 DF 1 NOP 1 -RST 4 E7 1 NOP 1 -RST 5 EF 1 NOP 1 -RST 6 F7 1 NOP 1 -RST 7 FF 1 NOP 1 -RZ "" C8 1 NOP 1 -SBB B 98 1 NOP 1 -SBB C 99 1 NOP 1 -SBB D 9A 1 NOP 1 -SBB E 9B 1 NOP 1 -SBB H 9C 1 NOP 1 -SBB L 9D 1 NOP 1 -SBB M 9E 1 NOP 1 -SBB A 9F 1 NOP 1 -SBI * DE 2 NOP 1 -SHLD * 22 3 NOP 1 -SIM "" 30 1 NOP 1 -SPHL "" F9 1 NOP 1 -STA * 32 3 NOP 1 -STAX B 02 1 NOP 1 -STAX D 12 1 NOP 1 -STC "" 37 1 NOP 1 -SUB B 90 1 NOP 1 -SUB C 91 1 NOP 1 -SUB D 92 1 NOP 1 -SUB E 93 1 NOP 1 -SUB H 94 1 NOP 1 -SUB L 95 1 NOP 1 -SUB M 96 1 NOP 1 -SUB A 97 1 NOP 1 -SUI * D6 2 NOP 1 -XCHG "" EB 1 NOP 1 -XRA B A8 1 NOP 1 -XRA C A9 1 NOP 1 -XRA D AA 1 NOP 1 -XRA E AB 1 NOP 1 -XRA H AC 1 NOP 1 -XRA L AD 1 NOP 1 -XRA M AE 1 NOP 1 -XRA A AF 1 NOP 1 -XRI * EE 2 NOP 1 -XTHL "" E3 1 NOP 1 - diff --git a/branches/s100/XSource/bin/TASM96.TAB b/branches/s100/XSource/bin/TASM96.TAB deleted file mode 100644 index ca6669b6..00000000 --- a/branches/s100/XSource/bin/TASM96.TAB +++ /dev/null @@ -1,393 +0,0 @@ -"TASM 8096 Assembler." -/**************************************************************************** -/* $Id: tasm96.tab 1.5 1997/09/28 22:14:30 toma Exp $ -/**************************************************************************** -;* This is the instruction set definition table -;* for the 8096 version of TASM. -;* Thomas N. Anderson, Speech Technology Incorporated -;* -;* See TASM manual for info on table structure. -;* -;*INSTR ARGS OPCODE BYTES MOD CLASS SHIFT MASK -;*-------------------------------------------* -; Revisions: -; Added I7 rule for single arg direct/far (PUSH/POP) -; Changed ADDB *,*,*[*] entry from rule I1 to I6. -; -; Generate opcodes high byte first/ -.MSFIRST -.NOARGSHIFT -; -; Note: -; The I1 rule uses ARGVAL for arg validation. If the combined -; args AND ARGVAL is not equal to the combined args then an -; error message is generated. -; -; The I1 rule also uses ARGOR. The value of that mask is OR'd -; with the first byte of the args. -; -; ARGOR -; BYTES CLASS | -; | | | -;INST ARGS OP v RULE v v ARGVAL -;-----------------------------------------; -;OK ADD -ADD *,*,[*]+ 46 4 I1 1 01 00FeFeFe ; -ADD *,*,[*] 46 4 I1 1 00 00FeFeFe ; -ADD *,*,*[*] 47 6 I6 1 00 00FeFeFe ; -ADD *,*,#* 45 5 I1 1 00 FeFeFFFF ; -ADD *,[*]+ 66 3 I1 1 01 0000FFFe ; 1st arg must be even, make odd -ADD *,[*] 66 3 I1 1 00 0000FFFe ; 1st arg must be even -ADD *,*[*] 67 5 I6 1 00 00FFFFFF ; -ADD *,*,* 4701 6 I3 1 00 0000FeFe ; 3rd arg may be far -ADD *,#* 65 4 I1 1 00 00FeFFFF ; 1st arg must be even -ADD *,* 6701 5 I2 1 00 0000FeFe ; 2nd arg may be far - -;OK ADDB -ADDB *,*,[*]+ 56 4 I1 1 01 00000000 ; no validation yet -ADDB *,*,[*] 56 4 I1 1 00 00000000 ; no validation yet -ADDB *,*,*[*] 57 6 I6 1 00 00000000 ; no validation yet -ADDB *,*,#* 55 4 I1 1 00 00000000 ; no validation yet -ADDB *,[*]+ 76 3 I1 1 01 0000FFFe ; 1st arg must be even, make odd -ADDB *,[*] 76 3 I1 1 00 0000FFFe ; 1st arg must be even -ADDB *,*[*] 77 5 I6 1 00 00FeFFFe ; 1st,3rd must be even -ADDB *,*,* 5701 6 I3 1 00 00000000 ; 3rd arg may be far -ADDB *,#* 75 3 I1 1 00 00FFFFFF ; odd args ok for byte operations -ADDB *,* 7701 5 I2 1 00 00000000 ; 2nd arg may be far - -; No three arg forms for ADDC or ADDCB -ADDC *,[*]+ A6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ADDC *,[*] A6 3 I1 1 00 0000FFFe ;1st arg must be even -ADDC *,*[*] A7 5 I6 1 00 00FFFFFF ; -ADDC *,#* A5 4 I1 1 00 00FeFFFF ;1st arg must be even -ADDC *,* A701 5 I2 1 00 00000000 ;2nd arg may be far - -ADDCB *,[*]+ B6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ADDCB *,[*] B6 3 I1 1 00 0000FFFe ;1st arg must be even -ADDCB *,*[*] B7 5 I6 1 00 00FFFFFF ; -ADDCB *,#* B5 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ADDCB *,* B701 5 I2 1 00 00000000 ;2nd arg may be far - -; OK AND -AND *,*,[*]+ 42 4 I1 1 01 00000000 ;no validation yet -AND *,*,[*] 42 4 I1 1 00 00000000 ;no validation yet -AND *,*,*[*] 43 6 I6 1 00 00000000 ;no validation yet -AND *,*,#* 41 5 I1 1 00 00000000 ;no validation yet -AND *,[*]+ 62 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -AND *,[*] 62 3 I1 1 00 0000FFFe ;1st arg must be even -AND *,*[*] 63 5 I6 1 00 00FeFFFe ;1st,3rd must be even -AND *,*,* 4301 6 I3 1 00 00000000 ;3rd arg may be far -AND *,#* 61 4 I1 1 00 00FeFFFF ;1st arg must be even -AND *,* 6301 5 I2 1 00 00000000 ;2nd arg may be far - -ANDB *,*,[*]+ 52 4 I1 1 01 00000000 ;no validation yet -ANDB *,*,[*] 52 4 I1 1 00 00000000 ;no validation yet -ANDB *,*,*[*] 53 6 I6 1 00 00000000 ;no validation yet -ANDB *,*,#* 51 4 I1 1 00 00000000 ;no validation yet -ANDB *,[*]+ 72 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ANDB *,[*] 72 3 I1 1 00 0000FFFe ;1st arg must be even -ANDB *,*[*] 73 5 I6 1 00 00FFFFFF ; -ANDB *,*,* 5301 6 I3 1 00 00000000 ;3rd arg may be far -ANDB *,#* 71 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ANDB *,* 7301 5 I2 1 00 00000000 ;2nd arg may be far - -BMOV *,* C1 3 I1 2 00 0000FcFF ;long word ptr to two words -BMOVI *,* AD 3 I1 2 00 0000FcFF ;long word ptr to two words - -BR [*] E3 2 I1 1 00 00000000 ; -BR * 2000 2 I5 1 00 00000000 ; Same As SJMP - -CLR * 01 2 NOP 1 00 00000000 ; -CLRB * 11 2 NOP 1 00 00000000 ; -CLRC "" F8 1 NOP 1 00 00000000 ; -CLRVT "" FC 1 NOP 1 00 00000000 ; - -CMP *,[*]+ 8A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -CMP *,[*] 8A 3 I1 1 00 0000FFFe ;1st arg must be even -CMP *,*[*] 8B 5 I6 1 00 00FFFFFF ; -CMP *,#* 89 4 I1 1 00 00FeFFFF ;1st arg must be even -CMP *,* 8B01 5 I2 1 00 00000000 ;2nd arg may be far - -CMPB *,[*]+ 9A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -CMPB *,[*] 9A 3 I1 1 00 0000FFFe ;1st arg must be even -CMPB *,*[*] 9B 5 I6 1 00 00FFFFFF ; -CMPB *,#* 99 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -CMPB *,* 9B01 5 I2 1 00 00000000 ;2nd arg may be far - -CMPL *,* C5 3 I1 2 00 0000FcFc ;long align multiple of 4 - -DEC * 05 2 NOP 1 00 00000000 ; -DECB * 15 2 NOP 1 00 00000000 ; -DJNZ *,* E0 3 CREL 1 00 00000000 ; -DJNZW *,* E1 3 CREL 2 00 00000000 ; - -DI "" FA 1 NOP 1 00 00000000 ; - -DIVU *,[*]+ 8E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVU *,[*] 8E 3 I1 1 00 0000FFFe ;1st arg must be even -DIVU *,*[*] 8F 5 I6 1 00 0000FFFe ;1st arg must be even -DIVU *,#* 8D 4 I1 1 00 00FeFFFF ;1st arg must be even -DIVU *,* 8F01 5 I2 1 00 00000000 ;2nd arg may be far - -DIVUB *,[*]+ 9E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVUB *,[*] 9E 3 I1 1 00 0000FFFe ;1st arg must be even -DIVUB *,*[*] 9F 5 I6 1 00 0000FFFF ; -DIVUB *,#* 9D 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -DIVUB *,* 9F01 5 I2 1 00 00000000 ;2nd arg may be far - -DIV *,[*]+ FE8E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIV *,[*] FE8E 4 I1 1 00 0000FFFe ;1st arg must be even -DIV *,*[*] FE8F 6 I6 1 00 0000FFFe ;1st arg must be even -DIV *,#* FE8D 5 I1 1 00 00FeFFFF ;1st arg must be even -DIV *,* FE8F01 6 I2 1 00 00000000 ;2nd arg may be far - -DIVB *,[*]+ FE9E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -DIVB *,[*] FE9E 4 I1 1 00 0000FFFe ;1st arg must be even -DIVB *,*[*] FE9F 6 I6 1 00 0000FFFF ; -DIVB *,#* FE9D 4 I1 1 00 00FFFFFF ;odd args ok for byte operations; -DIVB *,* FE9F01 6 I2 1 00 00000000 ;2nd arg may be far - -DPTS "" EC 1 NOP 2 00 00000000 ; -EPTS "" ED 1 NOP 2 00 00000000 ; - -EI "" FB 1 NOP 1 00 00000000 ; - -EXT * 06 2 NOP 1 00 00000000 ; -EXTB * 16 2 NOP 1 00 00000000 ; - -IDLPD #* F6 2 NOP 2 00 00000000 ; - -INC * 07 2 NOP 1 00 00000000 ; -INCB * 17 2 NOP 1 00 00000000 ; - -JC * DB 2 R1 1 00 00000000 -JNC * D3 2 R1 1 00 00000000 -JH * D9 2 R1 1 00 00000000 -JNH * D1 2 R1 1 00 00000000 -JE * DF 2 R1 1 00 00000000 -JNE * D7 2 R1 1 00 00000000 -JV * DD 2 R1 1 00 00000000 -JNV * D5 2 R1 1 00 00000000 -JGE * D6 2 R1 1 00 00000000 -JLT * DE 2 R1 1 00 00000000 -JVT * DC 2 R1 1 00 00000000 -JNVT * D4 2 R1 1 00 00000000 -JGT * D2 2 R1 1 00 00000000 -JLE * DA 2 R1 1 00 00000000 -JST * D8 2 R1 1 00 00000000 -JNST * D0 2 R1 1 00 00000000 - -JBC *,*,* 30 3 I4 1 00 00000000 -JBS *,*,* 38 3 I4 1 00 00000000 - -LJMP * E7 3 R2 1 00 00000000 -LCALL * EF 3 R2 1 00 00000000 - -LD *,[*]+ A2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LD *,[*] A2 3 I1 1 00 0000FFFe ;1st arg must be even -LD *,*[*] A3 5 I6 1 00 00FFFFFF ; -LD *,#* A1 4 I1 1 00 00FFFFFF ; -LD *,* A301 5 I2 1 00 00000000 ;2nd arg may be far - -LDB *,[*]+ B2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDB *,[*] B2 3 I1 1 00 0000FFFe ;1st arg must be even -LDB *,*[*] B3 5 I6 1 00 00FFFFFF ; -LDB *,#* B1 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDB *,* B301 5 I2 1 00 00000000 ;2nd arg may be far - -LDBSE *,[*]+ BE 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDBSE *,[*] BE 3 I1 1 00 0000FFFe ;1st arg must be even -LDBSE *,*[*] BF 5 I6 1 00 00FeFFFe ;1st,3rd must be even -LDBSE *,#* BD 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDBSE *,* BF01 5 I2 1 00 00000000 ;2nd arg may be far - -LDBZE *,[*]+ AE 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -LDBZE *,[*] AE 3 I1 1 00 0000FFFe ;1st arg must be even -LDBZE *,*[*] AF 5 I6 1 00 00FeFFFe ;1st,3rd must be even -LDBZE *,#* AD 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -LDBZE *,* AF01 5 I2 1 00 00000000 ;2nd arg may be far - -MULU *,*,[*]+ 4E 4 I1 1 01 00000000 ;no validation yet -MULU *,*,[*] 4E 4 I1 1 00 00000000 ;no validation yet -MULU *,*,*[*] 4F 6 I6 1 00 00000000 ;no validation yet -MULU *,*,#* 4D 5 I1 1 00 00000000 ;no validation yet -MULU *,[*]+ 6E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULU *,[*] 6E 3 I1 1 00 0000FFFe ;1st arg must be even -MULU *,*[*] 6F 5 I6 1 00 00FeFFFe ;1st,3rd must be even -MULU *,*,* 4F01 6 I3 1 00 00000000 ;3rd arg may be far -MULU *,#* 6D 4 I1 1 00 00FeFFFF ;1st arg must be even -MULU *,* 6F01 5 I2 1 00 00000000 ;2nd arg may be far - - -MULUB *,*,[*]+ 5E 4 I1 1 01 00000000 ;no validation yet -MULUB *,*,[*] 5E 4 I1 1 00 00000000 ;no validation yet -MULUB *,*,*[*] 5F 6 I6 1 00 00000000 ;no validation yet -MULUB *,*,#* 5D 4 I1 1 00 00000000 ;no validation yet -MULUB *,[*]+ 7E 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULUB *,[*] 7E 3 I1 1 00 0000FFFe ;1st arg must be even -MULUB *,*[*] 7F 5 I6 1 00 00FFFFFF ; -MULUB *,*,* 5F01 6 I3 1 00 00000000 ;3rd arg may be far -MULUB *,#* 7D 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -MULUB *,* 7F01 5 I2 1 00 00000000 ;2nd arg may be far - -MUL *,*,[*]+ FE4E 5 I1 1 01 00000000 ;no validation yet -MUL *,*,[*] FE4E 5 I1 1 00 00000000 ;no validation yet -MUL *,*,*[*] FE4F 7 I6 1 00 00000000 ;no validation yet -MUL *,*,#* FE4D 6 I1 1 00 00000000 ;no validation yet -MUL *,[*]+ FE6E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -MUL *,[*] FE6E 4 I1 1 00 0000FFFe ;1st arg must be even -MUL *,*[*] FE6F 6 I6 1 00 00FeFFFe ;1st,3rd must be even -MUL *,*,* FE4F01 7 I3 1 00 00000000 ;3rd arg may be far -MUL *,#* FE6D 5 I1 1 00 00FFFFFF ;odd args ok for byte operations -MUL *,* FE6F01 6 I2 1 00 00000000 ;2nd arg may be far - -MULB *,*,[*]+ FE5E 5 I1 1 01 00000000 ;no validation yet -MULB *,*,[*] FE5E 5 I1 1 00 00000000 ;no validation yet -MULB *,*,*[*] FE5F 7 I6 1 00 00000000 ;no validation yet -MULB *,*,#* FE5D 5 I1 1 00 00000000 ;no validation yet -MULB *,[*]+ FE7E 4 I1 1 01 0000FFFe ;1st arg must be even, make odd -MULB *,[*] FE7E 4 I1 1 00 0000FFFe ;1st arg must be even -MULB *,*[*] FE7F 6 I6 1 00 00FFFFFF ; -MULB *,*,* FE5F01 7 I3 1 00 00000000 ;3rd arg may be far -MULB *,#* FE7D 4 I1 1 00 00FFFFFF ;odd args ok for byte operations -MULB *,* FE7F01 6 I2 1 00 00000000 ;2nd arg may be far - -NEG * 03 2 I1 1 00 000000FE ;arg must be even -NEGB * 13 2 I1 1 00 000000FF ; - -NOP "" FD 1 NOP 1 00 00000000 ; - -NORML *,* 0F 3 I1 1 00 0000FFFF ;long align - -NOT * 02 2 NOP 1 00 00000000 ; -NOTB * 12 2 NOP 1 00 00000000 ; - -OR *,[*]+ 82 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -OR *,[*] 82 3 I1 1 00 0000FFFe ;1st arg must be even -OR *,*[*] 83 5 I6 1 00 00FeFFFe ;1st,3rd must be even -OR *,#* 81 4 I1 1 00 00FeFFFF ;1st arg must be even -OR *,* 8301 5 I2 1 00 00000000 ;2nd arg may be far - -ORB *,[*]+ 92 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ORB *,[*] 92 3 I1 1 00 0000FFFe ;1st arg must be even -ORB *,*[*] 93 5 I6 1 00 00FFFFFF ; -ORB *,#* 91 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -ORB *,* 9301 5 I2 1 00 00000000 ;2nd arg may be far - -PUSH #* C9 3 I1 1 00 00000000 ; -PUSH [*]+ CA 2 I1 1 01 000000Fe ;arg must be even -PUSH [*] CA 2 I1 1 00 000000Fe ;arg must be even -PUSH *[*] CB 4 I6 1 00 00FFFFFe ;arg must be even -PUSH * CB01 4 I7 1 00 0000FFFe ;arg must be even - -PUSHF "" F2 1 NOP 1 00 00000000 ; -PUSHA "" F4 1 NOP 1 00 00000000 ; - -POP [*]+ CE 2 I1 1 01 000000Fe ;arg must be even -POP [*] CE 2 I1 1 00 000000Fe ;arg must be even -POP *[*] CF 4 I6 1 00 00FFFFFE ; -POP * CF01 4 I7 1 00 0000FFFe ;arg must be even - -POPF "" F3 1 NOP 1 00 00000000 ; -POPA "" F5 1 NOP 1 00 00000000 ; - -RET "" F0 1 NOP 1 00 00000000 ; -RST "" FF 1 NOP 1 00 00000000 ; - -SJMP * 2000 2 I5 1 00 00000000 -SCALL * 2800 2 I5 1 00 00000000 - -SUB *,*,[*]+ 4A 4 I1 1 01 00000000 ;no validation yet -SUB *,*,[*] 4A 4 I1 1 00 00000000 ;no validation yet -SUB *,*,*[*] 4B 6 I6 1 00 00000000 ;no validation yet -SUB *,*,#* 49 5 I1 1 00 00000000 ;no validation yet -SUB *,[*]+ 6A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUB *,[*] 6A 3 I1 1 00 0000FFFe ;1st arg must be even -SUB *,*[*] 6B 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUB *,*,* 4B01 6 I3 1 00 00000000 ;3rd arg may be far -SUB *,#* 69 4 I1 1 00 00FeFFFF ;1st arg must be even -SUB *,* 6B01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBB *,*,[*]+ 5A 4 I1 1 01 00000000 ;no validation yet -SUBB *,*,[*] 5A 4 I1 1 00 00000000 ;no validation yet -SUBB *,*,*[*] 5B 6 I6 1 00 00000000 ;no validation yet -SUBB *,*,#* 59 4 I1 1 00 00000000 ;no validation yet -SUBB *,[*]+ 7A 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBB *,[*] 7A 3 I1 1 00 0000FFFe ;1st arg must be even -SUBB *,*[*] 7B 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBB *,*,* 5B01 6 I3 1 00 00000000 ;3rd arg may be far -SUBB *,#* 79 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -SUBB *,* 7B01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBC *,[*]+ AA 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBC *,[*] AA 3 I1 1 00 0000FFFe ;1st arg must be even -SUBC *,*[*] AB 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBC *,#* A9 4 I1 1 00 00FeFFFF ;1st arg must be even -SUBC *,* AB01 5 I2 1 00 00000000 ;2nd arg may be far - -SUBCB *,[*]+ BA 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -SUBCB *,[*] BA 3 I1 1 00 0000FFFe ;1st arg must be even -SUBCB *,*[*] BB 5 I6 1 00 00FeFFFe ;1st,3rd must be even -SUBCB *,#* B9 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -SUBCB *,* BB01 5 I2 1 00 00000000 ;2nd arg may be far - -SHL *,#* 09 3 I1 1 00 0000FE0F ; F -SHL *,* 09 3 I1 1 00 0000FEFF ; -SHLB *,#* 19 3 I1 1 00 0000FF0F ; -SHLB *,* 19 3 I1 1 00 0000FFFF ; -SHLL *,#* 0D 3 I1 1 00 0000FF0F ; -SHLL *,* 0D 3 I1 1 00 0000FFFF ; - -SHR *,#* 08 3 I1 1 00 0000FF0F ;word align -SHR *,* 08 3 I1 1 00 0000FFFF ;word align -SHRB *,#* 18 3 I1 1 00 0000FF0F ;byte align -SHRB *,* 18 3 I1 1 00 0000FFFF ;byte align -SHRL *,#* 0C 3 I1 1 00 0000FF0F ;long align -SHRL *,* 0C 3 I1 1 00 0000FFFF ;long align - -SHRA *,#* 0A 3 I1 1 00 0000FF0F ;word align -SHRA *,* 0A 3 I1 1 00 0000FFFF ;word align -SHRAB *,#* 1A 3 I1 1 00 0000FF0F ;byte align -SHRAB *,* 1A 3 I1 1 00 0000FFFF ;byte align -SHRAL *,#* 0E 3 I1 1 00 0000FF0F ;long align -SHRAL *,* 0E 3 I1 1 00 0000FFFF ;long align - -SETC "" F9 1 NOP 1 00 00000000 ; - - -SKIP "" 0000 2 NOP 1 00 00000000 ; -SKIP * 00 2 I1 1 00 00000000 ; - -ST *,[*]+ C2 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -ST *,[*] C2 3 I1 1 00 0000FFFe ;1st arg must be even -ST *,*[*] C3 5 I6 1 00 FFFFFFFe ;1st,3rd must be even -ST *,* C301 5 I2 1 00 00000000 ;2nd arg may be far - -STB *,[*]+ C6 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -STB *,[*] C6 3 I1 1 00 0000FFFe ;1st arg must be even -STB *,*[*] C7 5 I6 1 00 FFFFFFFe ;1st,3rd must be even -STB *,* C701 5 I2 1 00 00000000 ;2nd arg may be far - -TRAP "" F7 1 NOP 1 00 00000000 ; - -TIJMP *,[*],#* E2 4 I8 2 00 00FEFEFF ; - -XCH *,*[*] 0B 5 I6 2 00 00FeFFFe ;1st,3rd must be even -XCH *,* 0B01 5 I2 2 0C 00000000 ;2nd arg may be far - -XCHB *,*[*] 1B 5 I6 2 00 00FFFFFF ; -XCHB *,* 1B01 5 I2 2 0C 00000000 ;2nd arg may be far - -XOR *,[*]+ 86 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -XOR *,[*] 86 3 I1 1 00 0000FFFe ;1st arg must be even -XOR *,*[*] 87 5 I6 1 00 00FeFFFe ;1st,3rd must be even -XOR *,#* 85 4 I1 1 00 00FeFFFF ;1st arg must be even -XOR *,* 8701 5 I2 1 00 00000000 ;2nd arg may be far - -XORB *,[*]+ 96 3 I1 1 01 0000FFFe ;1st arg must be even, make odd -XORB *,[*] 96 3 I1 1 00 0000FFFe ;1st arg must be even -XORB *,*[*] 97 5 I6 1 00 00FFFFFF ; -XORB *,#* 95 3 I1 1 00 00FFFFFF ;odd args ok for byte operations -XORB *,* 9701 5 I2 1 00 00000000 ;2nd arg may be far - - diff --git a/branches/s100/XSource/bin/TASMMAN.HTM b/branches/s100/XSource/bin/TASMMAN.HTM deleted file mode 100644 index 0471e90e..00000000 --- a/branches/s100/XSource/bin/TASMMAN.HTM +++ /dev/null @@ -1,2865 +0,0 @@ - - - - - - - The Telemark Assembler (TASM) User Manual - - - - -
-

-The Telemark Assembler (TASM) User Manual

- -
Version 3.2
-
- -
Thomas N. Anderson
- -
Squak Valley Software
- -
837 Front Street South
- -
Issaquah, WA 98027
- -
email: andersontn@acm.org
- -
www.halcyon.com/squakvly/
-
- -
Copyright (C) 1985-2000 by Thomas N. Anderson. All rights reserved.
- -
-

-TABLE OF CONTENTS

- - - -
-

-INTRODUCTION

-The Telemark Assembler (TASM) is a table driven cross assembler for the -MS-DOS and LINUX environments. Assembly source code, written in the appropriate -dialect (generally very close to the manufacturers assembly language), -can be assembled with TASM, and the resulting object code transferred to -the target microprocessor system via PROM or other mechanisms. - -

The microprocessor families supported by TASM are: -

    -
  • -6502
  • - -
  • -6800/6801/68HC11
  • - -
  • -6805
  • - -
  • -8048
  • - -
  • -8051
  • - -
  • -8080/8085, Z80
  • - -
  • -TMS32010, TMS320C25
  • - -
  • -TMS7000
  • - -
  • -8096/80196
  • -
-The user so inclined may build tables for other microprocessors. The descriptions -of the various existing tables and instructions on building new tables -are not in this document but can be found in the TASMTABS.HTM file on the -TASM distribution disk. - -

TASM characteristics include: -

    -
  1. -Powerful expression parsing (17 operators).
  2. - -
  3. -Supports a subset of the 'C' preprocessor commands.
  4. - -
  5. -Macro capability (through use of DEFINE directive).
  6. - -
  7. -Multiple statements per line.
  8. - -
  9. -Four object file formats: Intel hex, MOS Technology hex, Motorola hex, -binary.
  10. - -
  11. -Absolute code generation only.
  12. - -
  13. -Source code available (in C).
  14. - -
  15. -Uniform syntax across versions for different target machines.
  16. - -
  17. -Features in support of PROM programming (preset memory, contiguous block).
  18. - -
  19. -Supports extended instructions for many of the supported microprocessor -families.
  20. - -
  21. -Tables read at run time - single TASM executable for all table versions.
  22. - -
  23. -Symbol table export for inclusion in subsequent assemblies.
  24. - -
  25. -Symbol table export file for import with some simulator products.
  26. -
- -
-

-SHAREWARE

-TASM is distributed as shareware. TASM is not in the public domain. The -TASM distribution files may be freely copied (excluding the source code -files) and freely used for the purpose of evaluating the suitability of -TASM for a given purpose. Use of TASM beyond a reasonable evaluation period -requires registration. Prolonged use without registration is unethical.  -
-

-INVOCATION

-TASM can be invoked as follows (optional fields shown in brackets, symbolic -fields in italics): -
  tasm -pn [-options ...] src_file [obj_file [lst_file [exp_file [sym_file]]]]
-Where options can be one or more of the following: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-table Specify version (table = table designation) 
-ttable Table (alternate form of above) 
-aamask Assembly control (optional error checking) 
-b Produce object in binary (.COM) format 
-c Object file written as a contiguous block 
-dmacro Define a macro (or just a macro label) 
-e Show source lines after macro expansion 
-ffillbyte Fill entire memory space with fillbyte (hex) 
-gobjtype Object file (0=Intel Hex, 1=MOS Tech, 2=Motorola, -3=binary,4=Intel Hex (Word)) 
-h Produce hex table of the assembled code (in list -file) 
-i Ignore case for labels 
-l[al] Produce a label table in the listing 
-m Produce object in MOS Technology format 
-oobytes Bytes per object record (for hex obj formats) 
-p[linesPage the listing file (lines per page. default=60) 
-q Quiet, disable the listing file 
-s Write a symbol table file 
-x[xmaskEnable extended instruction set (if any) 
-y Time the assembly 
-

The filename parameters are defined as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
src_file Source file name 
obj_file Object code file name 
lst_file Listing file name 
exp_file Symbol export file (only if the EXPORT directive -is used).
sym_file Symbol table file (only if the -s option -or the SYM/AVSYM directives are used). 
-

The source file must be specified. If not, some usage information is displayed. -Default file names for all the other files are generated if they are not -explicitly provided. The filename is formed by taking the source filename -and changing the extension to one of the following: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Extension File type 
.OBJ Object file 
.LST Listing file 
.EXP Symbol export file 
.SYM Symbol table file 
-

TASM has no built-in instruction set tables. Instruction set definition -files are read at run time. TASM determines which table to use based on -the '-table' field shown above. For example, to assemble the code -in a file called source.asm, one would enter -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
tasm -48 source.asm for an 8048 assembly 
tasm -65 source.asm for a 6502 assembly 
tasm -51 source.asm for an 8051 assembly. 
tasm -85 source.asm for an 8085 assembly. 
tasm -80 source.asm for a Z80 assembly. 
tasm -05 source.asm for a 6805 assembly. 
tasm -68 source.asm for a 6800/6801/68HC11 assembly. 
tasm -70 source.asm for a TMS7000 assembly. 
tasm -3210 source.asm for a TMS32010 assembly. 
tasm -3225 source.asm for a TMS320C25 assembly. 
tasm -96 source.asm for a 8096/80196 assembly
-

-Tables are read from a file named by taking the digits specified after -the '-' and appending it to 'TASM' then appending the '.TAB' extension. -Thus, the -48 flag would cause the tables to be read from the file -'TASM48.TAB'. - -

It is possible to designate tables by non numeric part numbers if the --t flag is used. For example, if a user built a table called TASMF8.TAB -then TASM could be invoked as follows: -

    tasm -tf8 source.asm
-Each option flag must be preceded by a dash. Options need not precede the -file names. The various options are described in the sections that follow. -

-a - Assembly Control

-TASM can provide additional error checking by specifying the -a -option at the time of execution. If the -a is provided without a -digit following, then all the available error checking is done. If a digit -follows, then it is used as a mask to determine the error checks to be -made. The bits of the mask are defined as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bit Option Default Description 
-a1 OFF Check for apparent illegal use of indirection 
-a2 ON Check for unused data in the arguments 
-a4 ON Check for duplicate labels 
-a8 OFF Check for non-unary operators at start of expression. 
-

Combinations of the above bits can also be used. For example, -a5 -would enable the checking for illegal indirection and duplicate labels. - -

Illegal indirection applies to micros that use parenthesis around an -argument to indicate indirection. Since it is always legal to put an extra -pair of parenthesis around any expression (as far as the expression parser -is concerned), the user may think that he/she is indicating indirection -for an instruction that has no indirection and TASM would not complain. -Enabling this checking will result in an error message (warning) whenever -an outer pair of parenthesis is used and the instruction set definition -table does not explicitly indicate that to be a valid form of addressing. - -

Unused data in arguments applies to cases where a single byte of data -is needed from an argument, but the argument contains more than one byte -of data. If a full sixteen bit address is used in a 'Load Immediate' type -instruction that needs only a single byte, for example, an error message -would be generated. Here is an example (6502 code): -

    0001   1234                    .org $1234
-    test.asm line 0002: Unused data in MS byte of argument.
-    0002   1234 A9 34       start  lda  #start
-To make the above checks occur whenever you do an assembly, add a line -like this to your AUTOEXEC.BAT file: -
    SET TASMOPTS=-a
- -

-b - Binary Object Format

-This option causes the object file to be written in binary - one byte for -each byte of code/data. Note that no address information is included in -the object file in this format. The contiguous block (-c) output mode is -forced when this option is invoked. This flag is equivalent to -g3. -

-c - Contiguous Block Output

-If this option is specified, then all bytes in the range from the lowest -used byte to the highest will be defined in the object file. Normally, -with the default Intel Hex object format enabled, if the Program Counter -(PC) jumps forward because of an .ORG directive, the -bytes skipped over will not have any value assigned them in the object -file. With this option enabled, no output to the object file occurs until -the end of the assembly at which time the whole block is written. This -is useful when using TASM to generate code that will be put into a PROM -so that all locations will have a known value. This option is often used -in conjunction with the -f option to ensure all unused bytes will have -a known value. -

-d - Define a Macro

-Macros are defined on the command line generally to control the assembly -of various IFDEF's that are in the source file. This is a convenient way -to generate various versions of object code from a single source file. -

-e - Expand Source.

-Normally TASM shows lines in the listing file just as they are in the source -file. If macros are in use (via the DEFINE directive) -it is sometimes desirable to see the source lines after expansion. Use -the '-e' flag to accomplish this. -

-f - Fill Memory.

-This option causes the memory image that TASM maintains to be initialized -to the value specified by the two hex characters immediately following -the 'f'. TASM maintains a memory image that is a full 64K bytes in size -(even if the target processor cannot utilize that memory space). Invocation -of this option introduces a delay at start up time. -

-g - Object File Format.

-TASM can generate object code in the formats indicated below: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Option Description
-g0 Intel hex (default) 
-g1 MOS Technology hex (same as -m
-g2 Motorola hex 
-g3 binary (same as -b
-g4 Intel hex with word addresses
-

The -m and -b flags may also be used, as indicated above. -If both are used the right-most option on the command line will be obeyed. - -

See the section on OBJECT FILE FORMATS for descriptions of each -of the above. -

-h - Hex Object Code Table.

-This option causes a hex table of the produced object code to appear in -the listing file. Each line of the table shows sixteen bytes of code. -

-i - Ignore Case in Labels.

-TASM is normally case sensitive when dealing with labels. For those that -prefer case insensitivity, the '-i' command line option can be employed. -

-l - Label Table.

-This option causes a label table to appear in the listing file. Each label -is shown with its corresponding value. Macro labels (as established via -the DEFINE directives) do not appear. - -

Two optional suffixes may follow the -l option: -
  - - - - - - - - - - - - - - - - - - -
Suffix Description 
Use long form listing 
Show all labels (including local labels) 
-

The suffix should immediately follow the '-l'. Here are some examples: -
  - - - - - - - - - - - - - - - - - - - - - - - - -
-l to show non-local labels in the short form 
-la to show all labels in the short form 
-ll to show non-local labels in the long form 
-lal to show all labels in the long form 
- -

-m - MOS Technology Object Format.

-This option causes the object file to be written in MOS Technology hex -format rather than the default Intel hex format. See section on OBJECT -FILE FORMATS for a description of the format. -

-o - Set Number of Bytes per Object Record.

-When generating object code in either the MOS Technology format or the -Intel hex format, a default of 24 (decimal) bytes of object are defined -on each record. This can be altered by invoking the '-o' option immediately -followed by two hex digits defining the number of bytes per record desired. -For example, if 32 bytes per record are desired, one might invoke TASM -as: -
    tasm -48 -o20 source.asm
- -

-p - Page Listing File.

-This option causes the listing file to have top of page headers and form -feeds inserted at appropriate intervals (every sixty lines of output). -To override the default of sixty lines per page, indicate the desired number -of lines per page as a decimal number immediately following the '-p'. Here -is an example: -
    tasm -48 -p56 source.asm
- -

-q - Disable Listing File.

-This option causes all output to the listing file to be suppressed, unless -a .LIST directive is encountered in the source file (see LIST/NOLIST -directives). -

-s - Enable Symbol File Generation.

-If this flag is set, a symbol file is generated at the end of the assembly. -The format of the file is one line per label, each label starts in the -first column and is followed by white space and then four hexadecimal digits -representing the value of the label. The following illustrates the format: -
    label1         FFFE
-    label2         FFFF
-    label3         1000
-The symbol file name can be provided as the fifth file name on the command -line, or the name will be generated from the source file name with a '.SYM' -extension. The symbol table file can also be generated by invoking the -SYM directive. The AVSYM directive also generates the symbol file but in -a different format (see section on ASSEMBLER -DIRECTIVES). -

-t - Table Name.

-As an alternative to specifying the instruction set table as two decimal -digits, the table indication may be proceeded by the '-t' option. This -is useful if the desired table name starts with a non-numeric. Thus, a -table for an F8 might be selected as: -
    tasm -tf8 source.asm
-TASM would expect to read the instruction set definition tables from a -file named TASMF8.TAB. -

-x - Enable Extended Instruction Set.

-If a processor family has instructions that are valid for only certain -members, this option can be used to enable those beyond the basic standard -instruction set. A hex digit may follow the 'x' to indicate a mask value -used in selecting the appropriate instruction set. Bit 0 of the mask selects -the basic instruction set, thus a '-x1' would have no effect. A '-x3' would -enable the basic set plus whatever instructions have bit 1 set in their -class mask. A '-x' without a digit following is equivalent to a '-xf' which -sets all four of the mask bits. The following table indicates the current -extended instruction sets available in the TASM tables: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Base Table Base Family Ext 1 (-x3) Ext 2 (-x7) Ext 3 (-x5) Ext 4 (-x9) 
48 8048 8041A 8022 8021 
65 6502 R65C02 R65C00/21 
05 6805 M146805 CMOS HC05C4 
80 Z80 HD64180 
68 6800 6801/6803 68HC11 
51 8051 
85 8080 
3210 TMS32010 
3225 TMS320C25 TMS320C26 
70 TMS7000 
-  -
  - -

The above table does not attempt to show the many microprocessor family -members that may apply under a given column. - -

See the TASMTABS.HTM on-line document for details on each specific table. -

-y - Enable Assembly Timing

-If this option is enabled TASM will generate a statement of elapsed time -and assembled lines per second at the end of the assembly. -

- -
ENVIRONMENT VARIABLES

-The TASM environment can be customized by using the environment variables -listed below: -

-TASMTABS

-The TASMTABS variable specifies the path to be searched for TASM instruction -set definition tables. If it is not defined then the table(s) must exist -in the current working directory. The following examples illustrate possible -usage: -
  - - - - - - - - - - - - -
For MSDOS set TASMTABS=C:\TASM
For LINUX TASMTABS=/tasm
- -

-TASMOPTS

-This variable specifies TASM command line options that are to be invoked -every time TASM is executed. For example, if TASM is being used for 8048 -assemblies with binary object file output desired, the following statement -would be appropriate in the AUTOEXEC.BAT file: -
    set TASMOPTS=-48 -b
- -

-TASMERRFORMAT

-The TASMERRFORMAT variable provides user control of the format of error -messages.  The format string must be a valid printf format string -for ANSI C.  The default value is: -
    -
    "%s line %04d: %s %s"
    -
-Which provides error messages like this: -
    -
    Main.asm line 1234: No such label: Start
    -
-The four fields associated with an error message are: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field DescriptionAssociated Data Type (ANSI C)
File namechar *
Line number within fileint
Error descriptionchar *
Error data (optional)char *
- - -

No user control of the order of the error message fields is provided. -
Here are sample usages: - -

For MSDOS: -

    -
    set TASMERRFORMAT=”%s(%d) %s %s”
    -
-For LINUX: -
    -
    TASMERRFORMAT=”%s(%d) %s %s”
    -
- -
-

-EXIT CODES

-When TASM terminates, it will return to the OS the following exit codes: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Exit Code Definition
Normal completion, no assembly errors 
Normal completion, with assembly errors 
Abnormal completion, insufficient memory 
Abnormal completion, file access error 
Abnormal completion, general error 
-

Exit codes 2 and above will also be accompanied by messages to the console -concerning the error. -
-


-

-SOURCE FILE FORMAT

-Statements in the source file must conform to a format as follows (except -for assembler directive statements which are described in a subsequent -section): -
  -
    label operation operand comment
-All of the fields are optional, under appropriate circumstances. An arbitrary -amount of white space (space and tabs) can separate each field (as long -as the maximum line length of 255 characters is not exceeded). Each of -the fields are described in the following sections. -

-Label Field.

-If the first character of the line is alphabetic, it is assumed to be the -start of a label. Subsequent characters are accepted as part of that label -until a space, tab, or ':' is encountered. The assembler assigns a value -to the label corresponding to the current location counter. Labels can -be a maximum of 32 characters long. Labels can contain upper and lower -case letters, digits, underscores, and periods (the first character must -be alphabetic). Labels are case sensitive - the label 'START' is a different -label from 'start' - unless the '-i' (ignore case) option is enabled. -

-Operation Field.

-The operation field contains an instruction mnemonic which specifies the -action to be carried out by the target processor when this instruction -is executed. The interpretation of each mnemonic is dependent on the target -microprocessor (as indicated by the selected TASM table). The operation -field may begin in any column except the first. The operation field is -case insensitive. -

-Operand Field.

-The operand field specifies the data to be operated on by the instruction. -It may include expressions and/or special symbols describing the addressing -mode to be used. The actual format and interpretation is dependent on the -target processor. For a description of the format for currently supported -processors, see the TASMTABS.DOC file on the TASM distribution disk. -

-Comment Field.

-The comment field always begins with a semicolon. The rest of the line -from the semicolon to the end of the line is ignored by TASM, but passed -on to the listing file for annotation purposes. The comment field must -be the last field on a line, but it may be the only field, starting in -column one, if desired. -

-Multiple Statement Lines.

-If the backslash character is encountered on a source line, it is treated -as a newline. The remainder of the line following the backslash will be -processed as an independent line of source code. This allows one to put -multiple statements on a line. This facility is not so useful of itself, -but when coupled with the capability of the DEFINE directive, powerful -multiple statement macros can be constructed (see section on ASSEMBLER -DIRECTIVES). Note that when using the statement separator, the -character immediately following it should be considered the first character -of a new line, and thus must either be a start of a label or white space -(not an instruction). As the examples show, a space is put between the -backslash and the start of the next instruction. -

-Sample Source Listing.

-Some examples of valid source statements follow (6502 mnemonics shown): -
  lab1       lda    byte1   ;get the first byte
-             dec    byte1
-             jne    label1
-  ;            
-  lab2       sta    byte2,X
-  ;  a multiple statement line follows
-             lda    byte1\ sta byte1+4\ lda byte2\ sta byte2+4
- -
-

-EXPRESSIONS

-Expressions are made up of various syntactic elements combined according -to a set of syntactical rules. Expressions can be comprised of the following -elements: -
    -
  • -Labels
  • - -
  • -Constants
  • - -
  • -Location Counter Symbol
  • - -
  • -Operators
  • - -
  • -Parenthesis
  • -
- -

-Labels

-Labels are strings of characters that have a numeric value associated with -them, generally representing an address. Labels can contain upper and lower -case letters, digits, underscores, and periods. The first character must -be a letter or the local label prefix (default '_'). The value of a label -is limited to 32 bit precision. Labels can contain up to 32 characters, -all of which are significant (none are ignored when looking at a label's -value, as in some assemblers). Case is significant unless the '-i' command -line option is invoked. - -

Local labels must only be unique within the scope of the current module. -Modules are defined with the MODULE directive. Here -is an example: -

          .MODULE xxx
-          lda regx
-          jne _skip
-          dec
-   _skip  rts
-          .MODULE yyy
-          lda regy
-          jne _skip
-          dec
-   _skip  rts
-In the above example, the _skip label is reused without harm. As -a default, local labels are not shown in the label table listing (resulting -from the '-l' command line option). See also sections on MODULE -and LOCALLABELCHAR directives. -

-Numeric Constants

-Numeric constants must always begin with a decimal digit (thus hexadecimal -constants that start with a letter must be prefixed by a '0' unless the -'$' prefix is used). The radix is determined by a letter immediately following -the digit string according to the following table: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Radix Suffix Prefix 
B or b 
O or o 
10 D or d (or nothing) 
16 H or h 
- -

Decimal is the default radix, so decimal constants need no suffix or prefix. - -

The following representations are equivalent: -

    1234H          or     $1234
-    100d           or     100
-    177400o        or     @177400
-    01011000b      or     %01011000
-The prefixes are provided for compatibility with some other source code -formats but introduce a problem of ambiguity. Both '%' and '$' have alternate -uses ('%' for modulo, '$' for location counter symbol). The ambiguity is -resolved by examining the context. The '%' character is interpreted as -the modulo operator only if it is in a position suitable for a binary operator. -Similarly, if the first character following a '$' is a valid hexadecimal -digit, it is assumed to be a radix specifier and not the location counter. -

-Character Constants

-Character constants are single characters surrounded by single quotes. -The ASCII value of the character in the quotes is returned. No escape provision -exists to represent non-printable characters within the quotes, but this -is not necessary since these can be just as easily represented as numeric -constants (or using the TEXT directive which does allow -escapes). -

-String Constants.

-String constants are one or more characters surrounded by double quotes. -Note that string constants are not allowed in expressions. They are only -allowable following the TITLE, BYTE, -DB, and TEXT assembler directives. -The quoted strings may also contain escape sequences to put in unprintable -values. The following escape sequences are supported: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Escape Sequence Description 
\n Line Feed 
\r Carriage return 
\b Backspace 
\t Tab 
\f Formfeed 
\\ Backslash 
\" Quote 
\000 Octal value of character 
- -

-Location Counter Symbol

-The current value of the location counter (PC) can be used in expressions -by placing a '$' in the desired place. The Location Counter Symbol is allowable -anywhere a numeric constant is. (Note that if the '$' is followed by a -decimal digit then it is taken to be the hexadecimal radix indicator instead -of the Location Counter symbol, as mentioned above). The '*' may also be -used to represent the location counter, but is less preferred because of -its ambiguity with the multiplicative operator. -

-Operators

-Expressions can optionally contain operators to perform some alterations -or calculations on particular values. The operators are summarized as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Operator Type Description 
Additive addition 
subtraction 
Multiplicative multiplication 
division 
modulo 
<<logical shift left 
>> logical shift right 
Unary bit inversion (one's complement) 
unary negation 
Relational equal 
== equal 
!= not equal 
<less than 
>greater than 
<= less than or equal 
>= greater than or equal 
&Binary binary 'and' 
binary 'or' 
binary 'exclusive or' 
- -

The syntax is much the same as in ANSI C with the following notes: - -

    -
  1. -No operator precedence is in effect. Evaluation is from left to right unless -grouped by parenthesis (see example below).
  2. - -
  3. -All evaluations are done with 32 bit signed precision.
  4. - -
  5. -Both '=' and '==' are allowable equality checkers. This is allowed since -the syntax does not provide assignment capability (as '=' would normally -imply).
  6. -
-The relational operators return a value of 1 if the relation is true and -0 if it is false. Thirty-two bit signed arithmetic is used. - -

It is always a good idea to explicitly indicate the desired order of -evaluation with parenthesis, especially to maintain portability since TASM -does not evaluate expressions in the same manner as many other assemblers. -To understand how it does arrive at the values for expressions, consider -the following example: -

    1 + 2*3 + 4
-TASM would evaluate this as: -
    (((1 + 2) * 3) + 4) = 13
-Typical rules of precedence would cause the (2*3) to be evaluated first, -such as: -
    1 + (2*3) + 4      = 11
-To make sure you get the desired order of evaluation, use parenthesis liberally. -Here are some examples of valid expressions: -
    (0f800H + tab)
-    (label_2 >> 8)
-    (label_3 << 8) & $f000
-    $ + 4
-    010010000100100b + 'a'
-    (base + ((label_4 >> 5) & (mask << 2))
- -
-

-ASSEMBLER DIRECTIVES

-Most of the assembler directives have a format similar to the machine instruction -format. However, instead of specifying operations for the processor to -carry out, the directives cause the assembler to perform some function -related to the assembly process. TASM has two types of assembler directives -- those that mimic the 'C' preprocessor functions, and those that resemble -the more traditional assembler directive functions. Each of these will -be discussed. - -

The ANSI C preprocessor style directives are invoked with a '#' as the -first character of the line followed by the appropriate directive (just -as in 'C'). Thus, these directives cannot have a label preceding them (on -the same line). Note that in the examples directives are shown in upper -case, however, either upper or lower case is acceptable. -

-ADDINSTR

-The ADDINSTR directive can be used to define additional instructions for -TASM to use in this assembly. The format is: -
    [label] .ADDINSTR inst args opcode nbytes rule class shift binor
-The fields are separated by white space just as they would appear in an -instruction definition file. See the TASMTABS.HTM file on the TASM distribution -disk for more detail. -

-AVSYM

-See SYM/AVSYM. -

-BLOCK

-The BLOCK directive causes the Instruction Pointer to advance the specified -number of bytes without assigning values to the skipped over locations. -The format is: -
    [label] .BLOCK        expr
-Some valid examples are: -
    word1   .BLOCK     2
-    byte1   .block     1
-    buffer  .block     80
- -

-BSEG/CSEG/DSEG/NSEG/XSEG

-These directives can be invoked to indicate the appropriate address space -for symbols and labels defined in the subsequent code. The invocation of -these directives in no way affects the code generated, only provides more -information in the symbol table file if the AVSYM directive is employed. -Segment control directives such as these are generally supported by assemblers -that generate relocatable object code. TASM does not generate relocatable -object code and does not support a link phase, so these directives have -no direct effect on the resulting object code. The segments are defined -as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Directive Segment Description 
BSEG Bit address 
CSEG Code address 
DSEG Data address (internal RAM) 
NSEG Number or constant (EQU) 
XSEG External data address (external RAM) 
- -

-BYTE

-The BYTE directive allows a value assignment to the byte pointed to by -the current Instruction Pointer. The format is: -
    [label] .BYTE   expr [, expr ...]
-Only the lower eight bits of expr are used. Multiple bytes may be -assigned by separating them with commas or (for printable strings) enclosed -in double quotes. Here are some examples: -
    label1   .BYTE     10010110B
-             .byte     'a'
-             .byte     0
-             .byte     100010110b,'a',0
-             .byte     "Hello", 10, 13, "World"
- -

-CHK

-The CHK directive causes a checksum to be computed and deposited at the -current location. The starting point of the checksum calculation is indicated -as an argument. Here is the format: -
    [label]    .CHK    starting_addr
-Here is an example: -
    start: NOP
-           LDA #1
-           .CHK start
-The checksum is calculated as the simple arithmetic sum of all bytes starting -at the starting_addr up to but not including the address of the -CHK directive. The least significant byte is all that -is used. -

-CODES/NOCODES

-The CODES/NOCODES directives can be used to alternately turn on or off -the generation of formatted listing output with line numbers, opcodes, -data, etc. With NOCODES in effect, the source lines are sent to the listing -file untouched. This is useful around blocks of comments that need a full -80 columns of width for clarity. -

-DB

-This is alternate form of the BYTE directive. -

-DW

-This is alternate form of the WORD directive. -

-DEFINE

-The DEFINE directive is one of the most powerful of the directives and -allows string substitution with optional arguments (macros). The format -is as follows: -
    #DEFINE  macro_label[(arg_list)]  [macro_definition]
-Where: -
-
-macro_label
- -
-character string to be expanded when found in the source file
- -
-arg_list
- -
-optional argument list for variable substitution in macro expansion
- -
-macro_def
- -
-string to replace the occurrences of macro_label in the source file.
-
-The simplest form of the DEFINE directive might look like this: -
    #DEFINE         MLABEL
-Notice that no substitutionary string is specified. The purpose of a statement -like this would typically be to define a label for the purpose of controlling -some subsequent conditional assembly (IFDEF or IFNDEF). - -

A more complicated example, performing simple substitution, might look -like this: -

    #DEFINE         VAR1_LO         (VAR1 & 255)
-This statement would cause all occurrences of the string 'VAR1_LO' in the -source to be substituted with '(VAR1 & 255)'. - -

As a more complicated example, using the argument expansion capability, -consider this: -

    #DEFINE  ADD(xx,yy)    clc\ lda xx\ adc yy\ sta xx
-If the source file then contained a line like this: -
    ADD(VARX,VARY)
-It would be expanded to: -
    clc\ lda VARX\ adc VARY\ sta VARX
-The above example shows the use of the backslash ('\') character as a multiple -instruction statement delimiter. This approach allows the definition of -fairly powerful, multiple statement macros. The example shown generates -6502 instructions to add one memory location to another. - -

Some rules associated with the argument list: -

    -
  1. -Use a maximum of 10 arguments.
  2. - -
  3. -Each argument should be a maximum of 15 characters.
  4. -
-Note that macros can be defined on the TASM command line, also, with the --d option flag. -

-DEFCONT

-The DEFCONT directive can be used to add to the last macro started with -a DEFINE directive. This provides a convenient way -to define long macros without running off the edge of the page. The ADD -macro shown above could be defined as follows: -
    #DEFINE         ADD(xx,yy)     clc
-    #DEFCONT                     \ lda xx
-    #DEFCONT                     \ adc yy
-    #DEFCONT                     \ sta xx
- -

-ECHO

-The ECHO directive can be used to send output to the console (stderr). -It can accept either a quoted text string (with the standard escape sequences -allowed) or a valid expression. It can accept only one or the other, however. -Multiple instances of the directive may be used to create output that contains -both. Consider the following example: -
    .ECHO "The size of the table is "
-    .ECHO (table_end - table_start)
-    .ECHO " bytes long.\n"
-This would result in a single line of output something like this: -
    The size of the table is 196 bytes long.
- -

-EJECT

-The EJECT directive can be used to force a top-of-form and the generation -of a page header on the list file. It has no effect if the paging mode -is off (see PAGE/NOPAGE). The format is: -
    [label]    .EJECT
- -

-ELSE

-The ELSE directive can optionally be used with IFDEF, IFNDEF and IF to -delineate an alternate block of code to be assembled if the block immediately -following the IFDEF, IFNDEF or IF is not assembled. - -

Here are some examples of the use of IFDEF, IFNDEF, IF, ELSE, and ENDIF: -

    #IFDEF   label1
-        lda      byte1
-        sta      byte2
-    #ENDIF   
-
-    #ifdef   label1
-        lda      byte1
-    #else    
-        lda      byte2
-    #endif   
-
-    #ifndef  label1
-        lda      byte2
-    #else    
-        lda      byte1
-    #endif   
-
-    #if ($ >= 1000h)
-    ; generate an invalid statement to cause an error
-    ;  when we go over the 4K boundary.
-    !!! PROM bounds exceeded.
-    #endif
- -

-END

-The END directive should follow all code/data generating statements in -the source file. It forces the last record to be written to the object -file. The format is: -
    [label]       .END [addr]
-The optional addr will appear in the last object record (Motorola -S9 record type) if the object format is Motorola hex. The addr field -is ignored for all other object formats. -

-ENDIF

-The ENDIF directive must always follow an IFDEF, IFNDEF, or IF directive -and signifies the end of the conditional block. -

-EQU

-The EQU directive can be used to assign values to labels. The labels can -then be used in expressions in place of the literal constant. The format -is: -
    label   .EQU   expr
-Here is an example: -
    MASK   .EQU  0F0H
-    ;
-           lda   IN_BYTE
-           and   MASK
-           sta   OUT_BYTE
-An alternate form of the EQU directive is '='. The previous example is -equivalent to any of the following: -
    MASK    =   0F0H
-    MASK    =0F0H
-    MASK    =$F0
-White space must exist after the label, but none is required after -the '='. -

-EXPORT

-The EXPORT directive can be used to define labels (symbols) that are to -be written to the export symbol file. The symbols are written as equates -(using the .EQU directive) so that the resulting file can be included in -a subsequent assembly. This feature can help overcome some of the deficiencies -of TASM due to its lack of a relocating linker. The format is: -
    [label]  .EXPORT      label [,label...]
-The following example illustrates the use of the EXPORT directive and the -format of the resulting export file: - -

Source file: -

    EXPORT        read_byte
-    EXPORT        write_byte, open_file
-Resulting export file: -
    read_byte      .EQU   $1243
-    write_byte     .EQU   $12AF
-    open_file      .EQU   $1301
- -

-FILL

-The FILL directive can be used to fill a selected number of object bytes -with a fixed value. Object memory is filled from the current program counter -forward. The format is as follows: -
    [label]  .FILL      number_of_bytes [,fill_value]
-The number_of_bytes value can be provided as any valid expression. -The optional fill_value can also be any valid expression. If fill_value -is not provided, a default value of 255 ($FF) is used. -

-IFDEF

-The IFDEF directive can be used to optionally assemble a block of code. -It has the following form: -
    #IFDEF  macro_label
-When invoked, the list of macro labels (established via DEFINE -directives) is searched. If the label is found, the following lines of -code are assembled. If not found, the input file is skipped until an ENDIF -or ELSE directive is found. - -

Lines that are skipped over still appear in the listing file, but a -'~' will appear immediately after the current PC and no object code will -be generated (this is applicable to IFDEF, IFNDEF, and IF). -

-IFNDEF

-The IFNDEF directive is the opposite of the IFDEF directive. The block -of code following is assembled only if the specified macro_label -is undefined. It has the following form: -
    #IFNDEF  macro_label
-When invoked, the list of macro labels (established via DEFINE directives) -is searched. If the label is not found, the following lines of code are -assembled. If it is found, the input file is skipped until an ENDIF or -ELSE directive is found. -

-IF

-The IF directive can be used to optionally assemble a block of code dependent -on the value of a given expression. The format is as follows: -
    #IF     expr
-If the expression expr evaluates to non-zero, the following block -of code is assembled (until an ENDIF or ELSE is encountered). -

-INCLUDE

-The INCLUDE directive reads in and assembles the indicated source file. -INCLUDEs can be nested up to four levels. This allows a convenient means -to keep common definitions, declarations, or subroutines in files to be -included as needed. The format is as follows: -
#INCLUDE        filename
-The filename must be enclosed in double quotes. Here are some examples: -
    #INCLUDE       "macros.h"
-    #include       "equates"
-    #include       "subs.asm"
- -

-LIST/NOLIST

-The LIST and NOLIST directives can be used to alternately turn the output -to the list file on (LIST) or off (NOLIST). The formats are: -
    .LIST
-    .NOLIST
- -

-LOCALLABELCHAR

-The LOCALLABELCHAR directive can be used to override the default "_" as -the label prefix indicating a local label. For example, to change the prefix -to "?" do this: -
    [label]   .LOCALLABELCHAR "?"
-Be careful to use only characters that are not operators for expression -evaluation. To do so causes ambiguity for the expression evaluator. Some -safe characters are "?", "{", and "}".  See Labels -for an example of local label usage. -

-LSFIRST/MSFIRST

-The LSFIRST and MSFIRST directives determine the byte order rule to be -employed for the WORD directive. The default (whether -correct or not) for all TASM versions is the least significant byte first -(LSFIRST). The following illustrates its effect: -
    0000  34 12    .word $1234
-    0002           .msfirst
-    0002  12 34    .word $1234
-    0004           .lsfirst
-    0004  34 12    .word $1234
- -

-MODULE

-The MODULE directive defines the scope of local labels. The format is: -
    [label]   .MODULE label
-Here is an example: -
          .MODULE module_x
-          lda regx
-          jne _skip
-          dec
-   _skip  rts
-          .MODULE module_y
-          lda regy
-          jne _skip
-          dec
-   _skip  rts
-In the above example, the local label _skip is reused without harm -since the two usages are in separate modules. See also section LOCALLABELCHAR -directive. -

-ORG

-The ORG directive provides the means to set the Instruction Pointer (a.k.a. -Program Counter) to the desired value. The format is: -
    [label] .ORG    expr
-The label is optional. The Instruction pointer is assigned the value -of the expr. For example, to generate code starting at address 1000H, -the following could be done: -
    start   .ORG    1000H
-The expression (expr) may contain references to the current Instruction -Pointer, thus allowing various manipulations to be done. For example, to -align the Instruction Pointer on the next 256 byte boundary, the following -could be done: -
    .ORG  (($ + 0FFH) & 0FF00H)
-ORG can also be used to reserve space without assigning values: -
    .ORG    $+8
-An alternate form of ORG is '*=' or '$='. Thus the following two examples -are exactly equivalent to the previous example: -
    *=*+8
-    $=$+8
- -

-PAGE/NOPAGE

-The PAGE/NOPAGE directives can be used to alternately turn the paging mode -on (PAGE) or off (NOPAGE). If paging is in effect, then every sixty lines -of output will be followed by a Top of Form character and a two line header -containing page number, filename, and the title. The format is: -
    
-    .PAGE
-    .NOPAGE
-The number of lines per page can be set with the '-p' command line option. -

-SET

-The SET directive allows the value of an existing label to be changed. -The format is: -
    label   .SET    expr
-The use of the SET directive should be avoided since changing the value -of a label can sometimes cause phase errors between pass 1 and pass 2 of -the assembly. -

-SYM/AVSYM

-These directives can be used to cause a symbol table file to be generated. -The format is: -
    .SYM    ["symbol_filename"]
-    .AVSYM  ["symbol_filename"]
-For example: -
    .SYM       "symbol.map"
-    .SYM       
-    .AVSYM     "prog.sym"
-    .AVSYM
-The two directives are similar, but result in a different format of the -symbol table file. The format of the SYM file is one line per symbol, each -symbol starts in the first column and is followed by white space and then -four hexadecimal digits representing the value of the symbol. The following -illustrates the format: -
    label1         FFFE
-    label2         FFFF
-    label3         1000
-The AVSYM directive is provided to generate symbol tables compatible with -the Avocet 8051 simulator. The format is similar, but each line is prefixed -by an 'AS' and each symbol value is prefixed by a segment indicator: -
    AS     start          C:1000
-    AS     read_byte      C:1245
-    AS     write_byte     C:1280
-    AS     low_nib_mask   N:000F
-    AS     buffer         X:0080
-The segment prefixes are determined by the most recent segment directive -invoked (see BSEG/CSEG/DSEG/NSEG/XSEG directives). -

-TEXT

-This directive allows an ASCII string to be used to assign values to a -sequence of locations starting at the current Instruction Pointer. The -format is: -
    [label] .TEXT   "string"
-The ASCII value of each character in string is taken and assigned to the -next sequential location. Some escape sequences are supported as follows: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Escape Sequence Description 
\n Line Feed 
\r Carriage return 
\b Backspace 
\t Tab 
\f Formfeed 
\\ Backslash 
\" Quote 
\000 Octal value of character 
- -

Here are some examples: - -

    message1   .TEXT   "Disk I/O error"
-    message2   .text   "Enter file name "
-               .text   "abcdefg\n\r"
-               .text   "I said \"NO\""
- -

-TITLE

-The TITLE directive allows the user to define a title string that appears -at the top of each page of the list file (assuming the PAGE mode is on). -The format is: -
    [label]    .TITLE  "string"
-The string should not exceed 80 characters. Here are some examples: -
    .TITLE  "Controller version 1.1"
-    .title  "This is the title of the assembly"
-    .title  ""
- -

-WORD

-The WORD directive allows a value assignment to the next two bytes pointed -to by the current Instruction Pointer. The format is: -
    [label] .WORD expr [,expr...]
-The least significant byte of expr is put at the current Instruction Pointer -with the most significant byte at the next sequential location (unless -the MSFIRST directive has been invoked). Here are some examples: -
    data_table     .WORD   (data_table + 1)
-                   .word   $1234
-                   .Word   (('x' - 'a')  << 2)
-                   .Word  12, 55, 32
- -
-

-OBJECT FILE FORMATS

-TASM can generate object code in the formats indicated below: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Option Description
-g0 Intel hex (default) 
-g1 MOS Technology hex (same as -m
-g2 Motorola hex 
-g3 binary (same as -b
-g4 Intel hex with word addresses
-

The -m and -b flags may also be used, as indicated above. -If both are used the right-most option on the command line will be obeyed. -

-Intel Hex Object Format

-This is the default object file format. This format is line oriented and -uses only printable ASCII characters except for the carriage return/line -feed at the end of each line. The format is symbolically represented as: - -

:NN AAAA RR HH CC CRLF - -

Where: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
:Record Start Character (colon)
NNByte Count (2 hex digits)
AAAAAddress of first byte (4 hex digits)
RRRecord Type (00 except for last record -which is 01)
HHData Bytes (a pair of hex digits for each byte -of data in the record)
CCCheck Sum (2 hex digits)
CRLFLine Terminator (CR/LF for DOS, LF for LINUX)
-

The last line of the file will be a record conforming to the above format -with a byte count of zero. - -

The checksum is defined as: - -

sum = byte_count+address_hi+address_lo+record_type+(sum of all data -bytes) -
checksum = ((-sum) & ffh) - -

Here is a sample listing file followed by the resulting object file: -

0001   0000             
-0002   1000                     .org   $1000
-0003   1000 010203040506        .byte  1, 2, 3, 4, 5, 6, 7, 8
-0003   1006 0708
-0004   1008 090A0B0C0D0E        .byte  9,10,11,12,13,14,15,16
-0004   100E 0F10
-0005   1010 111213141516        .byte 17,18,19,20,21,22,23,24,25,26
-0005   1016 1718191A
-0006   101A                     .end
- -
    :181000000102030405060708090A0B0C0D0E0F101112131415161718AC
-    :02101800191AA3
-    :00000001FF
- -

-Intel Hex Word Address Object Format

-This format is identical to the Intel Hex Object Format except that -the address for each line of object code is divided by two thus converting -it to a word address (16 bit word). All other fields are identical. - -

Here is an example: -

:180800000102030405060708090A0B0C0D0E0F101112131415161718AC
-:02080C00191AA3
-:00000001FF
- -

-MOS Technology Hex Object Format

-This format is line oriented and uses only printable ASCII characters except -for the carriage return/line feed at the end of each line. Each line in -the file is of the following format: - -

:NN AAAA HH CC CRLF - -

Where: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;Record Start Character (semicolon)
NNByte Count (2 hex digits)
AAAAAddress of first byte (4 hex digits)
HHData Bytes (a pair of hex digits for each byte -of data in the record)
CCCCCheck Sum (4 hex digits)
CRLFLine Terminator (CR/LF for DOS, LF for LINUX)
-

The last line of the file will be a record conforming to the above format -with a byte count of zero. - -

The checksum is defined as: - -

sum =byte_count+address_hi+address_lo+record_type+(sum of all data -bytes) -
checksum = (sum & ffffh) - -

Here is a sample object file: -

;1810000102030405060708090A0B0C0D0E0F1011121314151617180154
-;021018191A005D
-;00
- -

-Motorola Hex Object Format

-This format is line oriented and uses only printable ASCII characters except -for the carriage return/line feed at the end of each line. The format is -symbolically represented as: - -

S1 NN AAAA HH CCCC CRLF - -

Where: -
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
S1Record Start tag 
NNByte Count (2 hex digits) (data byte count + -3)
AAAAAddress of first byte (4 hex digits)
HHData Bytes (a pair of hex digits for each byte -of data in the record)
CCCheck Sum (2 hex digits)
CRLFLine Terminator (CR/LF for DOS, LF for LINUX)
- -

The checksum is defined as: - -

sum = byte_count+address_hi+address_lo+(sum of all data bytes) -
checksum = ((~sum) & ffh) - -

Here is a sample file: -

S11B10000102030405060708090A0B0C0D0E0F101112131415161718A8
-S1051018191A9F
-S9030000FC
-

The last line of the file will be a record with a byte count of zero and -a tag of S9. The address field will be 0000 unless and address was provided -with the END directive in which case it will appear in the address field. -

-Binary Object Format.

-This file format is essentially a memory image of the object code without -address, checksum or format description information. - -

Note that when this object format is selected (-b option), the -c option -is forced. This is done so that no ambiguity results from the lack of address -information in the file. Without the -c option, discontinuous blocks of -object code would appear contiguous. -
  - -

-


-

-LISTING FILE FORMAT

-Each line of source code generates one (or more) lines of output in the -listing file. The fields of the output line are as follows: -
    -
  1. -Current source file line number (4 decimal digits).
  2. - -
  3. -An optional '+' appears if this is an 'INCLUDE' file. (One '+' for each -level of INCLUDE invoked).
  4. - -
  5. -Current Instruction Pointer (4 hex digits). An optional '~' follows the -Instruction Pointer if the line of source code is not being assembled because -of an IFDEF, IFNDEF, or IF directive.
  6. - -
  7. -Resulting code/data generated from this source line (two hex digits per -byte, each byte separated by a space, up to six bytes per line).
  8. - -
  9. -The source line exactly as it appears in the source file.
  10. -
-If paging is enabled (by either the '-p' option flag or the .PAGE directive) -some additional fields will be inserted into the listing file every 60 -lines. These fields are: -
    -
  1. -Top of Form (form feed).
  2. - -
  3. -Assembler identifier (e.g. "TASM 6502 Assembler").
  4. - -
  5. -Initial source file name.
  6. - -
  7. -Page number.
  8. - -
  9. -Title.
  10. -
-If errors are encountered, then error messages will be interspersed in -the listing. TASM outputs error messages proceeding the offending line. -The following example illustrates the format: -
    0001   0000             label1  .equ  40h
-    0002   0000             label2  .equ  44h
-    0003   0000 
-    0004   1000             start:  .org  1000h
-    0005   1000 E6 40               inc   label1
-    0006   1002 E6 44               inc   label2
-    tt.asm line 0007: Label not found: (label3)
-    0007   1004 EE 00 00            inc   label3
-    0008   1007 4C 00 10            jmp   start
-    0009   100A                     .end  
-    0010   100A                            
-    tasm: Number of errors = 1
- -
-

-PROM PROGRAMMING

-A wide variety of PROM programming equipment is available that can use -object code in one or more of the formats supported by TASM. Here are some -notes concerning the generation of code to be programmed into PROMs: -

-PRESET MEMORY

-It is often desirable to have all bytes in the PROM programmed even if -not explicitly assigned a value in the source code (e.g. the bytes are -skipped over with a .ORG statement). This can be accomplished by using -the -c (contiguous block) and the -f (fill) command line -option flags. The -c will ensure that every byte from the lowest -byte assigned a value to the highest byte assigned a value will be in the -object file with no gaps. The -f flag will assign the specified -value to all bytes before the assembly begins so that when the object file -is written, all bytes not assigned a value in the source code will have -a known value. As an example, the following command line will generate -object code in the default Intel Hex format with all bytes not assigned -a value in the source set to EA (hex, 6502 NOP instruction): -
    tasm -65 -c -fEA test.asm
- -

-CONTIGUOUS BLOCKS

-To ensure that TASM generates object code to cover the full address range -of the target PROM, put a .ORG statement at the end of the source file -set to the last address desired. For example, to generate code to be put -in a 2716 EPROM (2 Kbytes) from hex address $1000 to $17ff, do something -like this in the source file: -
    ;start of the file
-        .ORG    $1000
-    ;rest of the source code follows
-    source code
-    ;end of the source code
-        .ORG    $17ff
-        .BYTE   0
-        .END
-Now, to invoke TASM to generate the code in the binary format with all -unassigned bytes set to 00 (6502 BRK instruction), do the following: -
tasm -65 -b -f00 test.asm
-Note: -b forces the -c option. -
-
-

-ERROR MESSAGES

- -

-Error Message Format

-TASM error messages take the following general form: -
    filename line line_number: error_message
-For example: -
    main.asm line 0032: Duplicate label (start)
-Many editors and IDE’s can run assemblies from within and parse the error -messages to make it convenient to jump to each error and correct.  -If the above format is not satisfactory for your editor or IDE, use the -TASMERRFORMAT environment variable to alter -the error message format. - -

When using automatic invocation of TASM from within an editor or IDE, -it may be useful to use the TASMOPTS environment -variable to set other command line options.  For example, to cause -TASM to perform 6502 assemblies, set TASMOPTS like this: -

    -
    SET TASMOPTS=-65
    -
- -

-ERROR MESSAGE DESCRIPTIONS

- -
-
-Binary operator where value expected
- -
-Two binary operators in a row indicate a missing value.
- -
-Branch off of current 2K page
- -
-An instruction is attempting to branch to a location not within the current -2K byte page.
- -
-Branch off of current page
- -
-An instruction is attempting to branch to a location not within the current -256 byte page.
- -
-Cannot malloc for label storage
- -
-Insufficient memory to store more labels. See LIMITATIONS.
- -
-Duplicate label
- -
-The label for the current line has already been assigned a value. Duplicate -label checks are optionally enabled by the -a option.
- -
-File name too short
- -
-A file name on the command line is fewer than 3 characters. A two character -file name may be valid, of course, but it is detected as an error to prevent -a garbled option flag from being taken as a source file, which in turn -can result in the true source file being taken as the object file. Since -the object file is truncated at startup time, the source file could be -clobbered.
- -
-Forward reference in equate
- -
-An EQU directive is using a label on the right hand side that has not yet -been defined.
- -
-Heap overflow on label definition
- -
-TASM was unable to allocate memory to store the label.
- -
-Imbalanced conditional.
- -
-An end-of-file was encountered at which time the level of descent in conditional -directives was different from when the file was entered. Conditional directives -include IF, IFDEF, and IFNDEF.
- -
-Invalid Object file type.
- -
-An object file type was requested by the -g command line option that is -not valid. See section on Option g - Object File Format.
- -
-Invalid operand.
- -
-No indirection for this instruction. The first character of an operand -was a left parenthesis for an instruction that does not explicitly specify -that as the format. Some micros use the parenthesis as an indicator of -indirection, but putting a layer of parenthesis around an expression is -always a valid thing to do (as far as the expression evaluator is concerned). -The test for this case is only done if the -a4 option is selected. -See section on ASSEMBLY CONTROL.
- -
-Invalid token where value expected.
- -
-Two binary operators in a row are not allowed.
- -
-Label too long.
- -
-Labels are limited to 31 characters.
- -
-Label value misaligned
- -
-The value of a label appears to have a different value on the second pass -then it was computed to have on the first pass. This is generally due to -Zero Page Addressing mode problems with the 6502 version of TASM. Labels -that are used in operands for statements that could utilize Zero Page addressing -mode should always be defined before used as an operand.
- -
-Label not found
- -
-A label used in an expression was not found in the current label table.
- -
-Label must pre-exist for SET.
- -
-The SET directive can only be applied to an existing label.
- -
-Label table overflow
- -
-To many labels have been encountered.
- -
-List file open error
- -
-TASM was not able to open the specified list file.
- -
-Macro expansion too long.
- -
-The expansion of a macro resulted in a line that exceeded the maximum length.
- -
-Max number of nested conditionals exceeded
- -
-Too many levels of IF, IFDEF, or IFNDEF.
- -
-Maximum number of args exceeded
- -
-Too many macro arguments.
- -
-Maximum number of macros exceeded
- -
-Too many macros (DEFINEs) have been encountered.
- -
-No END directive before EOF
- -
-The source file did not have an END directive in it. This is not fatal, -but may cause the last object file record to be lost.
- -
-No files specified
- -
-TASM was invoked with no source file specified.
- -
-No such label
- -
-A SET directive was encountered for a label not yet defined. The value -of labels that are modified by the SET directive must already exist.
- -
-No terminating quote
- -
-A double quote was used at the start of a a text string but was not used -at the end of the string.
- -
-No indirection for this instruction.
- -
-A parenthesis was found around the operand expression. This may indicate -an attempt to use indirection where it is inappropriate.
- -
-Non-unary operator at start of expression
- -
-A binary operator (such as '*') was found at the beginning of an expression. -Some micros use '*' as an indirection operator. Since it is also a legitimate -operator in an expression, some ambiguity can arise. If a particular instruction/addressing -mode does not allow indirection, and a '*' is placed in front of the associated -expression, the assembler will assume this error. See the -a8 option -of ASSEMBLY CONTROL.
- -
-Object file open error
- -
-TASM was not able to open the specified object file.
- -
-Range of argument exceeded
- -
-The value of an argument exceeds the valid range for the current instruction -and addressing mode.
- -
-Range of relative branch exceeded
- -
-A branch instruction exceeds the maximum range.
- -
-Source file open error
- -
-TASM was not able to open the specified source file.
- -
-Unrecognized directive
- -
-A statement starting with a '.' or '#' has a mnemonic that is not defined -as a directive.
- -
-Unrecognized instruction
- -
-A statement has an opcode mnemonic that is not defined.
- -
-Unrecognized argument
- -
-A statement has an operand format that is not defined.
- -
-Unknown token
- -
-Unexpected characters were encountered while parsing an expression.
- -
-Unused data in MS byte of argument
- -
-An instruction or directive used the least significant byte of an argument -and left the most significant byte unused, but it was non-zero.
- -
-Unknown option Flag.
- -
-Invalid option flag has been specified on the command line. invoke TASM -with nothing on the command line to see a list of valid options.
-
- -
-

-LIMITATIONS

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Maximum number of labels 15000 
Maximum length of labels 32 characters 
Maximum address space 64 Kbytes (65536 bytes) 
Maximum number of nested INCLUDES
Maximum length of TITLE string 79 characters 
Maximum source line length 511 characters 
Maximum length after macro expansion 511 characters 
Maximum length of expressions 511 characters 
Maximum length of pathnames 79 characters 
Maximum length of command line 127 characters 
Maximum number of instructions (per table) 1200 
Maximum number of macros 1000 
Maximum number of macro arguments 10 
Maximum length of macro argument 16 characters 
Memory requirements 512K 
- -

-Other Limitations

- -
    -
  1. -The 8048 version of TASM does not check for use of memory beyond any reasonable -bounds (e.g. an 8048 has a maximum address space of 4 Kbytes but TASM will -let you pretend that you have 64 Kbytes).
  2. - -
  3. -Expression evaluation has no operator precedence in effect which can make -for unexpected results if not explicitly grouped with parenthesis.
  4. - -
  5. -First page of listing file will not show a user defined title (defined -via TITLE directive).
  6. -
- -
-
Top - - diff --git a/branches/s100/XSource/bin/TASMTABS.HTM b/branches/s100/XSource/bin/TASMTABS.HTM deleted file mode 100644 index f009361a..00000000 --- a/branches/s100/XSource/bin/TASMTABS.HTM +++ /dev/null @@ -1,2989 +0,0 @@ - - - -TASM Table Syntax - -

TASM TABLE SYNTAX DESCRIPTION

-

The tables that control TASM's interpretation of the source file are read -from a file at run time. The table file name is determined by taking the -numeric option field specified on the TASM command line and appending it to the -string "TASM", then a ".TAB" extension is added. Thus, -if the following command line is entered: -

-
        tasm -51  test.asm
-
-

then TASM would read the table file named "TASM51.TAB". -

-

The following rules apply to the structure of the table file: -

-
    -
  • The first line of the file should contain a string surrounded by double -quotes that should identify the version of the assembler table. This string -will appear at the top of each page in the list file. It should be limited to -24 characters.
  • -
  • Any line that starts with a '.' is considered a directive. Directives -should preceed instruction defintion lines. The following directives are -available: -
- - - - - - - - - - - - - - - - - - -
DIRECTIVEDESCRIPTION
MSFIRSTGenerate opcodes MS byte first. Useful for tables with multibyte opcodes.
ALTWILDUse '@' instead of '*' as the wild card in the table. Useful if the -instruction syntax uses '*' to denote certain addressing modes.
NOARGSHIFTSuppress the shift/or operation that applies if the optional SHIFT and OR -fields are provided. Some RULEs use the SHIFT/OR fields for other purposes.
REGSETDefine a register mnemonic and associated bit field. See example below.
WORDADDRSSet word addressing mode (one word = 2 bytes)
-
    -
  • Any line whose first character is not a '.' and is not alphabetic is -considered to be a comment and is discarded.
  • -
  • Any line that has an alphabetic character as the first character is assumed -to be an instruction definition record and is parsed to build the internal -representation of the instruction set tables. Eight fields (separated by white -space) are expected, as follows: -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field Name Description
INSTRUCTION Instruction Mnemonic
ARGS Argument definition
OPCODE Opcode value
NBYTES Number of bytes
RULE Modifier operation
CLASS Instruction class
SHIFT Argument left shift count
OR Argument bitwise OR mask
-

The fields are further defined below:

-
-
INSTRUCTION
-
The INSTRUCTION field should contain the string to be used as the mnemonic -for this instruction. Upper case letters should be used (the source statements -are converted to upper case before comparison).
-
ARGS.
-
The ARGS field should contain a string describing the format of the operand -field. All characters are taken literally except the '*' which denotes the -presence of a valid TASM expression. Multiple '*'s can be used, but all but the -last one must be followed by a comma, '[', or ']'. If a single '*' appears in -the ARGS field, then the default action of TASM will be to determine the value -of the expression that matches the field and insert one or two bytes of it into -the object file depending on the NBYTES field. If multiple '*'s are used, then -special operators (RULE) must be used to take advantage of them (see the -examples below). An ARGS field of a pair of double quotes means that no -arguments are expected. -
-
OPCODE.
-
The OPCODE field should contain the opcode value (two to six hex digits) -for this instruction and address mode. Each pair of hex digits represent a -single byte of the opcode, ordered with the right most pair being placed in the -lowest memory location. -
-
NBYTES.
-
The NBYTES field should specify the number of bytes this instruction is to -occupy (a single decimal digit). This number includes both opcode bytes and -argument bytes, thus, the number of bytes of argument is computed by subtracting -the number of bytes of opcode (dictated by the length of the OPCODE field) from -NBYTES. -
-
RULE.
-
The RULE field determines if any special operations need to be performed -on the code generated for this instruction. For example, the zero-page -addressing mode of the 6502 is a special case of the absolute addressing mode, -and is handled by a special RULE code. See the Encoding Rules below. -
-
CLASS.
-
The CLASS field is used to specify whether this instruction is part of the -standard instruction set or a member of a set of extended instructions. Bit 0 of -this field should be set to denote a member of the standard instruction set. -Other bits can be used as needed to establish several classes (or sets) of -instructions that can be enabled or disabled via the '-x' command line option. - -
-
SHIFT (optional).
-
The SHIFT field is used to cause the first argument of the given -instruction to be shifted left the specified number of bits. (Except T1, TDMA, -TAR RULES as noted below). -
-
OR (optional).
-
The OR field is used to perform a bitwise OR with the first argument of the -given instruction. Specified as hex digits. (Except T1, TDMA, TAR RULES as -noted below). -
-

Note that the SHIFT/OR fields are used somewhat differently for T1, TDMA, -and TAR RULES. In those cases, the SHIFT and OR fields are used but the OR -field is really an AND mask and the result is OR'd with the opcode. -

-

Encoding Rules

-

The following encoding rules are available:

-
-
NOTOUCH or NOP
-
Do nothing to instruction or args
-
JMPPAGE
-
Put bits 8-10 of first arg into bits 5-7 of opcode (8048 JMP)
-
ZPAGE
-
If arg < 256 then use zero-page (6502)
-
R1
-
Make arg relative to PC (single byte)
-
R2
-
Make arg relative to PC (two byte)
-
CREL
-
Combine LS bytes of first two args making the second one relative to PC
-
SWAP
-
Swap bytes of first arg
-
COMBINE
-
Combine LS bytes of first two args into first arg (arg1 -> LSB, arg2 ->MSB).
-
CSWAP
-
Combine LS bytes of first two args into first arg and swap.
-
ZBIT
-
Z80 bit instructions.
-
ZIDX
-
Z80 Indexed Instructions (e.g. ADC A,(IX+x))
-
MBIT
-
Motorola (6805) bit instructions
-
MZERO
-
Motorola (6805) zero page (direct)
-
3ARG
-
Three args, one byte each.
-
3REL
-
Three args, one byte each, last one relative
-
T1
-
TMS320 instruction with one arg. Shift according to SHIFT and mask with OR -and OR into opcode. If a second arg exists assume it is an arp and OR intoLSB -of opcode.
-
TDMA
-
TMS320 instruction with first arg dma. Second arg gets shift/and/or -treatment as with T1.
-
TAR
-
TMS320 instruction with first arg ar. Second arg gets shift/and/or -treatment as with T1.
-
I1
-
I8096 Combine
-
I2
-
I8096 two far args
-
I3
-
I8096 three far args
-
I4
-
I8096 Jump with bit mask
-
I5
-
I8096 Relative
-
I6
-
I8096 Indirect
-
I7
-
I8096 One far arg
-
I8
-
I8096 Jump
-

Encoding Examples

-

Note that the reason for the combining of arguments (COMBINE and CSWAP) is -that TASM assumes that all object bytes to be inserted in the object file are -derived from a variable representing the value of the first argument (argval). -If two arguments are in the ARGS field, then one of the previously mentioned -RULE`s must be used. They have the effect of combining the low bytes of the -first two arguments into the variable (argval) from which the object code will -be generated. TASM`s argument parsing routine can handle a large number of -arguments, but the code that generates the object code is less capable. -

-

The following table shows possible instruction definition records, followed -by possible source statements that would match it, followed by the resulting -object code that would be generated (in hex): -

-
                                          EXAMPLE         EXAMPLE
-INSTRUCTION DEFINITION                    SOURCE          OBJECT
--------------------------------------------------------------------
-XYZ  *      FF   3  NOTOUCH 1             xyz 1234h       FF 34 12
-XYZ  *      FF   2  NOTOUCH 1             xyz 1234h       FF 34
-ZYX  *      FE   3  SWAP    1             zyx 1234h       FE 12 34
-ZYX  *      FE   3  R2      1             zyx $+4         FE 01 00
-ABC  *,*    FD   3  COMBINE 1             abc 45h,67h     FD 45 67
-ABC  *,*    FD   3  CSWAP   1             abc 45h,67h     FD 67 45
-ADD  A,#*   FC   2  NOTOUCH 1             add A,#'B'      FC 42
-RET  ""     FB   1  NOTOUCH 1             ret             FB
-LD   IX,*   21DD 4  NOTOUCH 1             ld  IX,1234h    DD 21 34 12
-LD   IX,*   21DD 4  NOTOUCH 1 1 0         ld  IX,1234h    DD 21 68 24
-LD   IX,*   21DD 4  NOTOUCH 1 0 1         ld  IX,1234h    DD 21 35 12
-LD   IX,*   21DD 4  NOTOUCH 1 1 1         ld  IX,1234h    DD 21 69 24
-LD   IX,*   21DD 4  NOTOUCH 1 8 12        ld  IX,34h      DD 21 12 34
-
-

The order of the entries for various addressing modes of a given instruction -is important. Since the wild card matches anything, it is important to specify -the ARGS for the addressing modes that have the most qualifying characters -first. For example, if an instruction had two addressing modes, one that -accepted any expression, and another that required a pound sign in front of an -expression, the pound sign entry should go first otherwise all occurrences of -the instruction would match the more general ARGS expression that it -encountered first. The following entries illustrate the proper sequencing: -

-
        ADD #*  12 3 NOTOUCH 1
-        ADD *   13 3 NOTOUCH 1
-
-

Table Lookup Method

-

The current version of TASM uses a very simple hashing method based on the -first character of the nmemonic. A search is begun at the first table entry -that starts with that letter. Thus, the table should be sorted alphabetically -for optimum lookup speed. If the table is not sorted in this way it will not -break anything, but just slow it down a bit.

-

REGSET Directive

-

For instruction sets that have a well defined set of registers that map to a -bit field in the opcode it may be convenient to use the REGSET directive. The -value field following each register definition is OR'd into the opcode when a -match is found. The '!' character is used to indicate the expected occurance of -a register. Consider the following example:

-
.REGSET R0  00 1
-.REGSET R1  01 1
-.REGSET R2  02 1
-.REGSET R3  03 1
-.REGSET R4  04 1
-.REGSET R5  05 1
-.REGSET R6  06 1
-.REGSET R7  07 1
-
-...
-INC !  E0  1 NOP
-...
-
-

A source instruction INC R3 would be encoded by ORing E0 with 03 -resulting in E3.

-
-

6502 INSTRUCTIONS AND ADDRESSING MODES

-

The acceptable 6502 opcode mnemonics for TASM are as follows: -

-
 ADC  AND  ASL  BCC  BCS  BEQ  BNE  BMI  BPL  BVC  BVS  BIT
- BRK  CLC  CLD  CLI  CLV  CMP  CPX  CPY  DEC  DEX  DEY  EOR
- INC  INX  INY  JMP  JSR  LDA  LDX  LDY  LSR  NOP  ORA  PHA
- PHP  PLA  PLP  ROL  ROR  RTI  RTS  SBC  SEC  SED  SEI  STA
- STX  STY  TAX  TAY  TSX  TXA  TXS  TYA
-
-

TASM also supports the following instructions that are part of the -Rockwell R65C02 and R65C00/21 microprocessor instruction sets. Those that - are marked as set A are applicable to the R65C02 and those marked as set B -are applicable to the R65C00/21 (A+B for both): -

-
        Mnemonic        Description                Address Mode  Set
-        ---------------------------------------------------------------
-        ADC             Add with carry             (IND)         A
-        AND             And memory with A          (IND)         A
-        BIT             Test memory bits with A    ABS,X         A
-        BIT             Test memory bits with A    ZP,X          A
-        BIT             Test memory bits with A    IMM           A
-        CMP             Compare memory with A      (IND)         A
-        DEC             Decrement A                A             A
-        EOR             Exclusive OR memory with A (IND)         A
-        INC             Increment A                A             A
-        JMP             Jump                       (ABS,X)       A
-        LDA             Load A with memory         (IND)         A
-        ORA             OR A with memory           (IND)         A
-        SBC             Subtract memory form A     (IND)         A
-        STA             Store A in memory          (IND)         A
-        STZ             Store zero                 ABS           A
-        STZ             Store zero                 ABS,X         A
-        STZ             Store zero                 ZP            A
-        STZ             Store zero                 ZP,X          A
-        TRB             Test and reset memory bit  ABS           A
-        TRB             Test and reset memory bit  ZP            A
-        TSB             Test and set memory bit    ABS           A
-        TSB             Test and set memory bit    ZP            A
-
-        BRA             Branch Always              REL           A+B
-
-        BBR0            Branch on Bit 0 Reset      ZP,REL        A+B
-        BBR1            Branch on Bit 1 Reset      ZP,REL        A+B
-        BBR2            Branch on Bit 2 Reset      ZP,REL        A+B
-        BBR3            Branch on Bit 3 Reset      ZP,REL        A+B
-        BBR4            Branch on Bit 4 Reset      ZP,REL        A+B
-        BBR5            Branch on Bit 5 Reset      ZP,REL        A+B
-        BBR6            Branch on Bit 6 Reset      ZP,REL        A+B
-        BBR7            Branch on Bit 7 Reset      ZP,REL        A+B
-
-        BBS0            Branch on Bit 0 Set        ZP,REL        A+B
-        BBS1            Branch on Bit 1 Set        ZP,REL        A+B
-        BBS2            Branch on Bit 2 Set        ZP,REL        A+B
-        BBS3            Branch on Bit 3 Set        ZP,REL        A+B
-        BBS4            Branch on Bit 4 Set        ZP,REL        A+B
-        BBS5            Branch on Bit 5 Set        ZP,REL        A+B
-        BBS6            Branch on Bit 6 Set        ZP,REL        A+B
-        BBS7            Branch on Bit 7 Set        ZP,REL        A+B
-
-        MUL             Multiply                   Implied       B
-
-        PHX             Push Index X               Implied       A+B
-        PHY             Push Index Y               Implied       A+B
-        PLX             Pull Index X               Implied       A+B
-        PLY             Pull Index Y               Implied       A+B
-
-        RMB0            Reset Memory Bit 0         ZP            A+B
-        RMB1            Reset Memory Bit 1         ZP            A+B
-        RMB2            Reset Memory Bit 2         ZP            A+B
-        RMB3            Reset Memory Bit 3         ZP            A+B
-        RMB4            Reset Memory Bit 4         ZP            A+B
-        RMB5            Reset Memory Bit 5         ZP            A+B
-        RMB6            Reset Memory Bit 6         ZP            A+B
-        RMB7            Reset Memory Bit 7         ZP            A+B
-
-        SMB0            Set   Memory Bit 0         ZP            A+B
-        SMB1            Set   Memory Bit 1         ZP            A+B
-        SMB2            Set   Memory Bit 2         ZP            A+B
-        SMB3            Set   Memory Bit 3         ZP            A+B
-        SMB4            Set   Memory Bit 4         ZP            A+B
-        SMB5            Set   Memory Bit 5         ZP            A+B
-        SMB6            Set   Memory Bit 6         ZP            A+B
-        SMB7            Set   Memory Bit 7         ZP            A+B
-
-

Addressing modes are denoted as follows: -

-
ABS               Absolute
-ZP                Zero Page
-ABS,X             Absolute X
-ZP,X              Zero Page X
-ABS,Y             Absolute Y
-ZP,Y              Zero Page Y
-A                 Accumulator
-(IND,X)           Indirect X
-(IND),Y           Indirect Y
-(IND)             Indirect
-#IMM              Immediate
-REL               Relative (Branch instructions only)
-ZP,REL            Zero Page, Relative
-Implied           Implied
-
-

Note that Zero Page addressing can not be explicitly requested. It is used -if the value of the operand is representable in a single byte for the -applicable statements. -

-

The '-x' command line option can be used to enable the extended -instructions. A '-x' with no digit following will enable the standard set plus -both extended sets. The 6502 version of TASM uses three bits in the instruction -class mask to determine whether a given instruction is enabled or not. Bit 0 -enables the basic set, bit 1 enables set A (R65C02) and bit 2 enables set B -(R65C00/21). The following table shows various options: -

-
Class Mask        Enabled Instructions
-                BASIC   R65C02  R65C00/21
---------------------------------------------
-1               yes     no      no
-2               no      yes     no
-3               yes     yes     no
-4               no      no      yes
-5               yes     no      yes
-6               no      yes     yes
-7               yes     yes     yes
-
-

Thus, to enable the basic set plus the R65C02 instructions, invoke the -'-x3' command line option. -

-

See manufacturer's data for a more complete description of the meaning of -the mnemonics and addressing modes. -

-
-

68xx INSTRUCTIONS AND ADDRESSING MODES -

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 6800/68HC11 version of TASM. Symbolic -fields are defined as follows: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr8_             Absolute address (8 bits)
-_addr16_            Absolute address (16 bits)
-                      Values that can fit in 8 bits can
-                      result in the DIRECT addressing mode.
-_addr16_no8_        Absolute address (16 bits)
-                      DIRECT addressing not applicable.
-_bmsk_              Bit mask (8 bits)
-_rel8_              Relative address (8 bit signed)
-_immed8_            Immediate data (8 bits)
-_immed16_           Immediate data (16 bits)
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-

The lines that are marked with an 'a' or 'b' are extended instructions that -are available only if a -x option has been invoked on the command line. The -classes of instructions (and their bit assignment in the class mask) are shown -below: -

-
BIT     PROCESSOR      EXT LABEL     COMMAND LINE OPTION
---------------------------------------------------------
-0       6800
-1       6801/6803       a            -x3
-2       68HC11          b            -x7
-
-

Thus, to enable the 68HC11 instructions, a -x7 could be used on the command -line. -

-

TASM deviates from standard Motorola syntax for the BSET, BRSET, BCLR, -and BRCLR instructions. TASM requires commas separating all arguments. -Motorola assemblers use white space to separate the last one or two -arguments for these instructions. Here are examples of each applicable -instruction: -

-
TASM                                MOTOROLA
-----------------------              --------------------
-BCLR    _addr8_,Y,_bmsk_            BCLR    _addr8_,Y _bmsk_
-BCLR    _addr8_,X,_bmsk_            BCLR    _addr8_,X _bmsk_
-BCLR    _addr8_  ,_bmsk_            BCLR    _addr8_   _bmsk_
-BSET    _addr8_,Y,_bmsk_            BSET    _addr8_,Y _bmsk_
-BSET    _addr8_,X,_bmsk_            BSET    _addr8_,X _bmsk_
-BSET    _addr8_  ,_bmsk_            BSET    _addr8_   _bmsk_
-BRCLR   _addr8_,Y,_bmsk_,_rel8_     BRCLR   _addr8_,Y _bmsk_ _rel8_
-BRCLR   _addr8_,X,_bmsk_,_rel8_     BRCLR   _addr8_,X _bmsk_ _rel8_
-BRCLR   _addr8_  ,_bmsk_,_rel8_     BRCLR   _addr8_   _bmsk_ _rel8_
-BRSET   _addr8_,Y,_bmsk_,_rel8_     BRSET   _addr8_,Y _bmsk_ _rel8_
-BRSET   _addr8_,X,_bmsk_,_rel8_     BRSET   _addr8_,X _bmsk_ _rel8_
-BRSET   _addr8_  ,_bmsk_,_rel8_     BRSET   _addr8_   _bmsk_ _rel8_
-
-
OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-ABA                          Add Accumulator B to Accumulator A
-ABX                     a    Add Accumulator B to Index Reg X
-ABY                     b    Add Accumulator B to Index reg Y
-
-ADCA    #_immed8_            Add with carry immediate  to Reg A
-ADCA    _addr8_,X            Add with carry indirect,X to Reg A
-ADCA    _addr8_,Y       b    Add with carry indirect,Y to Reg A
-ADCA    _addr16_             Add with carry extended   to Reg A
-
-ADCB    #_immed8_            Add with carry immediate  to Reg B
-ADCB    _addr8_,X            Add with carry indirect,X to Reg B
-ADCB    _addr8_,Y       b    Add with carry indirect,Y to Reg B
-ADCB    _addr16_             Add with carry extended   to Reg B
-
-ADDA    #_immed8_            Add w/o  carry immediate  to Reg A
-ADDA    _addr8_,X            Add w/o  carry indirect,X to Reg A
-ADDA    _addr8_,Y       b    Add w/o  carry indirect,Y to Reg A
-ADDA    _addr16_             Add w/o  carry extended   to Reg A
-
-ADDB    #_immed8_            Add w/o  carry immediate  to Reg B
-ADDB    _addr8_,X            Add w/o  carry indirect,X to Reg B
-ADDB    _addr8_,Y       b    Add w/o  carry indirect,Y to Reg B
-ADDB    _addr16_             Add w/o  carry extended   to Reg B
-
-ADDD    #_immed8_       a    Add double immediate  to Reg D
-ADDD    _addr8_,X       a    Add double indirect,X to Reg D
-ADDD    _addr8_,Y       b    Add double indirect,Y to Reg D
-ADDD    _addr16_        a    Add double extended   to Reg D
-
-ANDA    #_immed8_            AND immediate  to Reg A
-ANDA    _addr8_,X            AND indirect,X to Reg A
-ANDA    _addr8_,Y       b    AND indirect,Y to Reg A
-ANDA    _addr16_             AND extended   to Reg A
-
-ANDB    #_immed8_            AND immediate  to Reg B
-ANDB    _addr8_,X            AND indirect,X to Reg B
-ANDB    _addr8_,Y       b    AND indirect,Y to Reg B
-ANDB    _addr16_             AND extended   to Reg B
-
-ASL     _addr8_,X            Arithmetic shift left indirect,X
-ASL     _addr8_,Y       b    Arithmetic shift left indirect,Y
-ASL     _addr16_             Arithmetic shift left extended
-ASLA                         Arithmetic shift left Reg A
-ASLB                         Arithmetic shift left Reg B
-ASLD                    a    Arithmetic shift left double Reg D
-
-ASR     _addr8_,X            Arithmetic shift right indirect,X
-ASR     _addr8_,Y       b    Arithmetic shift right indirect,Y
-ASR     _addr16_             Arithmetic shift right extended
-ASRA                         Arithmetic shift right Reg A
-ASRB                         Arithmetic shift right Reg B
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-BCC     _rel8_               Branch if carry clear
-BCS     _rel8_               Branch if carry set
-BEQ     _rel8_               Branch if equal
-BGE     _rel8_               Branch if greater or equal
-BGT     _rel8_               Branch if greater
-BHI     _rel8_               Branch if higher
-BHS     _rel8_               Branch if higher or same
-BRA     _rel8_               Branch always
-
-BITA    #_immed8_            AND immediate  with Reg A (set condition codes)
-BITA    _addr8_,X            AND indirect,X with Reg A (set condition codes)
-BITA    _addr8_,Y       b    AND indirect,Y with Reg A (set condition codes)
-BITA    _addr16_             AND extended   with Reg A (set condition codes)
-
-BITB    #_immed8_            AND immediate  with Reg B (set condition codes)
-BITB    _addr8_,X            AND indirect,X with Reg B (set condition codes)
-BITB    _addr8_,Y       b    AND indirect,Y with Reg B (set condition codes)
-BITB    _addr16_             AND extended   with Reg B (set condition codes)
-
-BLE     _rel8_               Branch if less than or equal
-BLO     _rel8_               Branch if lower (same as BCS)
-BLS     _rel8_               Branch if lower or same
-BLT     _rel8_               Branch if less than zero
-BMI     _rel8_               Branch if minus
-BNE     _rel8_               Branch if not equal
-BPL     _rel8_               Branch if plus
-BRA     _rel8_               Branch always
-
-BRCLR _addr8_,X,_bmsk_,_rel8_  b Branch if bits clear indirect X
-BRCLR _addr8_,Y,_bmsk_,_rel8_  b Branch if bits clear indirect Y
-BRCLR _addr8_,_bmsk_,  _rel8_  b Branch if bits clear direct
-
-BRN     _rel8_               Branch never
-
-BRSET _addr8_,X,_bmsk_,_rel8_  b Branch if bits set indirect X
-BRSET _addr8_,Y,_bmsk_,_rel8_  b Branch if bits set indirect Y
-BRSET _addr8_,_bmsk_,  _rel8_  b Branch if bits set direct
-
-BSET    _addr8_,X,_bmsk_ b   Bit set indirect X
-BSET    _addr8_,Y,_bmsk_ b   Bit set indirect Y
-BSET    _addr8_,_bmsk_   b   Bit set direct
-BSET    _addr8_,#_bmsk_  b   Bit set direct (alternate form)
-
-BSR     _rel8_               Branch subroutine
-BVC     _rel8_               Branch if overflow clear
-BVS     _rel8_               Branch if overflow set
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-CBA                          Compare registers A & B
-CLC                          Clear Carry
-CLI                          Clear Interrupt Mask
-
-CLR     _addr8_,X            Arithmetic shift right indirect,X
-CLR     _addr8_,Y       b    Arithmetic shift right indirect,Y
-CLR     _addr16_             Arithmetic shift right extended
-CLRA                         Arithmetic shift right Reg A
-CLRB                         Arithmetic shift right Reg B
-
-CLV                          Clear Overflow Bit
-
-CMPA    #_immed8_            Compare immediate  with Reg A
-CMPA    _addr8_,X            Compare indirect,X with Reg A
-CMPA    _addr8_,Y       b    Compare indirect,Y with Reg A
-CMPA    _addr16_             Compare extended   with Reg A
-
-CMPB    #_immed8_            Compare immediate  with Reg B
-CMPB    _addr8_,X            Compare indirect,X with Reg B
-CMPB    _addr8_,Y       b    Compare indirect,Y with Reg B
-CMPB    _addr16_             Compare extended   with Reg B
-
-COM     _addr8_,X            Complement indirect,X
-COM     _addr8_,Y       b    Complement indirect,Y
-COM     _addr16_             Complement extended
-COMA                         Complement Reg A
-COMB                         Complement Reg B
-
-CPD     #_immed16_      b    Compare double immediate  to Reg D
-CPD     _addr8_,X       b    Compare double indirect,X to Reg D
-CPD     _addr8_,Y       b    Compare double indirect,Y to Reg D
-CPD     _addr16_        b    Compare double extended   to Reg D
-
-CPX     #_immed8_            Compare double immediate  to Reg X
-CPX     _addr8_,X            Compare double indirect,X to Reg X
-CPX     _addr8_,Y       b    Compare double indirect,Y to Reg X
-CPX     _addr16_             Compare double extended   to Reg X
-
-CPY     #_immed8_       b    Compare double immediate  to Reg Y
-CPY     _addr8_,X       b    Compare double indirect,X to Reg Y
-CPY     _addr8_,Y       b    Compare double indirect,Y to Reg Y
-CPY     _addr16_        b    Compare double extended   to Reg Y
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-DAA                          Decimal Adjust Reg A
-
-DEC     _addr8_,X            Decrement indirect,X
-DEC     _addr8_,Y            Decrement indirect,Y
-DEC     _addr16_no8_         Decrement extended
-DECA                         Decrement Reg A
-DECB                         Decrement Reg B
-DES                          Decrement stack pointer
-DEX                          Decrement Reg X
-DEY                     b    Decrement Reg Y
-
-EORA    #_immed8_            Exclusive OR immediate  with Reg A
-EORA    _addr8_,X            Exclusive OR indirect,X with Reg A
-EORA    _addr8_,Y       b    Exclusive OR indirect,Y with Reg A
-EORA    _addr16_             Exclusive OR extended   with Reg A
-
-EORB    #_immed8_            Exclusive OR immediate  with Reg B
-EORB    _addr8_,X            Exclusive OR indirect,X with Reg B
-EORB    _addr8_,Y       b    Exclusive OR indirect,Y with Reg B
-EORB    _addr16_             Exclusive OR extended   with Reg B
-
-FDIV                    b    Fractional Divide (ACCD/IX)
-IDIV                    b    Integer Divide (ACCD/IX)
-
-INC     _addr8_,X            Increment indirect,X
-INC     _addr8_,Y            Increment indirect,Y
-INC     _addr16_no8_         Increment extended
-INCA                         Increment Reg A
-INCB                         Increment Reg B
-INS                          Increment stack pointer
-INX                          Increment Reg X
-INY                     b    Increment Reg Y
-
-JMP     _addr8_,X            Jump indirect,X
-JMP     _addr8_,Y       b    Jump indirect,Y
-JMP     _addr16_no8_         Jump extended
-
-JSR     _addr8_,X            Jump Subroutine indirect,X
-JSR     _addr8_,Y       b    Jump Subroutine indirect,Y
-JSR     _addr16_             Jump Subroutine extended
-
-LDAA    #_immed8_            Load Accumulator immediate  with Reg A
-LDAA    _addr8_,X            Load Accumulator indirect,X with Reg A
-LDAA    _addr8_,Y       b    Load Accumulator indirect,Y with Reg A
-LDAA    _addr16_             Load Accumulator extended   with Reg A
-
-LDAB    #_immed8_            Load Accumulator immediate  with Reg B
-LDAB    _addr8_,X            Load Accumulator indirect,X with Reg B
-LDAB    _addr8_,Y       b    Load Accumulator indirect,Y with Reg B
-LDAB    _addr16_             Load Accumulator extended   with Reg B
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-LDD     #_immed16_      a    Load double immediate  to Reg D
-LDD     _addr8_,X       a    Load double indirect,X to Reg D
-LDD     _addr8_,Y       b    Load double indirect,Y to Reg D
-LDD     _addr16_        a    Load double extended   to Reg D
-
-LDS     #_immed16_           Load double immediate  to Reg D
-LDS     _addr8_,X            Load double indirect,X to Reg D
-LDS     _addr8_,Y       b    Load double indirect,Y to Reg D
-LDS     _addr16_             Load double extended   to Reg D
-
-LDX     #_immed16_           Load immediate  to Reg X
-LDX     _addr8_,X            Load indirect,X to Reg X
-LDX     _addr8_,Y       b    Load indirect,Y to Reg X
-LDX     _addr16_             Load extended   to Reg X
-
-LDY     #_immed16_      b    Load immediate  to Reg Y
-LDY     _addr8_,X       b    Load indirect,X to Reg Y
-LDY     _addr8_,Y       b    Load indirect,Y to Reg Y
-LDY     _addr16_        b    Load extended   to Reg Y
-
-LSL     _addr8_,X            Logical Shift Left indirect,X
-LSL     _addr8_,Y       b    Logical Shift Left indirect,Y
-LSL     _addr16_no8_         Logical Shift Left extended
-LSLA                         Logical Shift Left Reg A
-LSLB                         Logical Shift Left Reg B
-LSLD                         Logical Shift Left Double Reg D
-
-LSR     _addr8_,X            Logical Shift Right indirect,X
-LSR     _addr8_,Y       b    Logical Shift Right indirect,Y
-LSR     _addr16_no8_         Logical Shift Right extended
-LSRA                         Logical Shift Right Reg A
-LSRB                         Logical Shift Right Reg B
-LSRD                         Logical Shift Right Double Reg D
-
-MUL                          Multiply Unsigned
-
-NEG     _addr8_,X            Negate indirect,X
-NEG     _addr8_,Y       b    Negate indirect,Y
-NEG     _addr16_no8_         Negate extended
-NEGA                         Negate Reg A
-NEGB                         Negate Reg B
-
-NOP                          No Operation
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-ORAA    #_immed8_            Inclusive OR immediate  with Reg A
-ORAA    _addr8_,X            Inclusive OR indirect,X with Reg A
-ORAA    _addr8_,Y       b    Inclusive OR indirect,Y with Reg A
-ORAA    _addr16_             Inclusive OR extended   with Reg A
-
-ORAB    #_immed8_            Inclusive OR immediate  with Reg B
-ORAB    _addr8_,X            Inclusive OR indirect,X with Reg B
-ORAB    _addr8_,Y       b    Inclusive OR indirect,Y with Reg B
-ORAB    _addr16_             Inclusive OR extended   with Reg B
-
-PSHA                         Push Reg A onto stack
-PSHB                         Push Reg B onto stack
-PSHX                         Push Reg X onto stack
-PSHY                         Push Reg Y onto stack
-
-PULA                         Pull Reg A from stack
-PULB                         Pull Reg B from stack
-PULX                         Pull Reg X from stack
-PULY                         Pull Reg Y from stack
-
-ROL     _addr8_,X            Rotate Left indirect,X
-ROL     _addr8_,Y            Rotate Left indirect,Y
-ROL     _addr16_no8_         Rotate Left extended
-ROLA                         Rotate Left Reg A
-ROLB                         Rotate Left Reg B
-
-ROR     _addr8_,X            Rotate Right indirect,X
-ROR     _addr8_,Y            Rotate Right indirect,Y
-ROR     _addr16_no8_         Rotate Right extended
-RORA                         Rotate Right Reg A
-RORB                         Rotate Right Reg B
-RTI                          Return from Interrupt
-RTS                          Return from subroutine
-
-SBA                          Subtract Accumulators
-SBCA    #_immed8_            Subtract with Carry immediate  with Reg A
-SBCA    _addr8_,X            Subtract with Carry indirect,X with Reg A
-SBCA    _addr8_,Y       b    Subtract with Carry indirect,Y with Reg A
-SBCA    _addr16_             Subtract with Carry extended   with Reg A
-SBCB    #_immed8_            Subtract with Carry immediate  with Reg B
-SBCB    _addr8_,X            Subtract with Carry indirect,X with Reg B
-SBCB    _addr8_,Y       b    Subtract with Carry indirect,Y with Reg B
-SBCB    _addr16_             Subtract with Carry extended   with Reg B
-SEC                          Set Carry
-SEI                          Set Interrupt Mask
-SEV                          Set Twos Complement Overflow Bit
-STAA    _addr8_,X            Store Reg A indirect,X
-STAA    _addr8_,Y       b    Store Reg A indirect,Y
-STAA    _addr16_             Store Reg A extended
-
-STAB    _addr8_,X            Store Reg B indirect,X
-STAB    _addr8_,Y       b    Store Reg B indirect,Y
-STAB    _addr16_             Store Reg B extended
-
-OPCODE  OPERANDS       EXT   DESCRIPTION
---------------------------------------------------------------
-STD     _addr8_,X            Store Double Acc indirect,X to Reg B
-STD     _addr8_,Y       b    Store Double Acc indirect,Y to Reg B
-STD     _addr16_             Store Double Acc extended   to Reg B
-
-STOP                         Stop Processing
-
-STS     _addr8_,X            Store Accumulator indirect,X
-STS     _addr8_,Y       b    Store Accumulator indirect,Y
-STS     _addr16_             Store Accumulator extended
-
-STX     _addr8_,X            Store Index Reg X indirect,X
-STX     _addr8_,Y       b    Store Index Reg X indirect,Y
-STX     _addr16_             Store Index Reg X extended
-
-STY     _addr8_,X       b    Store Index Reg Y indirect,X
-STY     _addr8_,Y       b    Store Index Reg Y indirect,Y
-STY     _addr16_        b    Store Index Reg Y extended
-
-SUBA    #_immed8_            Subtract immediate  from Reg A
-SUBA    _addr8_,X            Subtract indirect,X from Reg A
-SUBA    _addr8_,Y       b    Subtract indirect,Y from Reg A
-SUBA    _addr16_             Subtract extended   from Reg A
-
-SUBB    #_immed8_            Subtract immediate  from Reg B
-SUBB    _addr8_,X            Subtract indirect,X from Reg B
-SUBB    _addr8_,Y       b    Subtract indirect,Y from Reg B
-SUBB    _addr16_             Subtract extended   from Reg B
-
-SUBD    #_immed16_      b    Subtract double immediate  from Reg D
-SUBD    _addr8_,X       b    Subtract double indirect,X from Reg D
-SUBD    _addr8_,Y       b    Subtract double indirect,Y from Reg D
-SUBD    _addr16_        b    Subtract double extended   from Reg D
-
-SWI                          Software Interrupt
-
-TAB                          Transfer Reg A to Reg B
-TAP                          Transfer Reg A to Condition Code Reg
-TPA                          Transfer Condition Code Reg to Reg A
-TBA                          Transfer Reg B to Reg A
-
-TST     _addr8_,X            Test indirect,X
-TST     _addr8_,Y            Test indirect,Y
-TST     _addr16_no8_         Test extended
-TSTA                         Test Reg A
-TSTB                         Test Reg B
-
-TSX                          Transfer Stack Pointer to Reg X
-TSY                     b    Transfer Stack Pointer to Reg Y
-TXS                          Transfer Reg X to Stack Pointer
-TYS                     b    Transfer Reg Y to Stack Pointer
-
-WAI                          Wait for Interrupt
-XGDX                    b    Exchange Double Reg D and Reg X
-XGDY                    b    Exchange Double Reg D and Reg Y
-
-
-
-

8048 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 8048 version of TASM. Where 'Rn' is seen, -R0 through R7 may be substituted. Other symbolic fields are as follows: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr8_             Absolute address (8 bits)
-_addr11_            Absolute address (11 bits)
-_immed_             Immediate data
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-

The lines that are marked with an (8041), (8022), or (8021) on the far -right are extended instructions that are available only if a -x option has been -invoked on the command line. The classes of instructions (and their bit -assignment in the class mask) are shown below: -

-
BIT     PROCESSOR
--------------------------------
-0       8X48, 8035, 8039, 8049
-1       8X41A
-2       8022
-3       8021
-
-

Thus, to enable the basic 8048 set plus the 8022 set, a -x5 could be used on -the command line. -

-

Note that some of the base instructions should be disabled for the 8041, -8022, and 8021, but are not. -

-
OPCODE  OPERANDS        DESCRIPTION
--------------------------------------------------------------------
-ADD     A,Rn            Add Register to Acc
-ADD     A,@R0           Add Indirect RAM to Acc
-ADD     A,@R1           Add Indirect RAM to Acc
-ADD     A,#_immed_      Add Immediate data to Acc
-
-ADDC    A,Rn            Add Register to Acc with carry
-ADDC    A,@R0           Add Indirect RAM to Acc with carry
-ADDC    A,@R1           Add Indirect RAM to Acc with carry
-ADDC    A,#_immed_      Add Immediate data to Acc with carry
-
-ANL     A,Rn            AND Register to Acc
-ANL     A,@R0           AND Indirect RAM to Acc
-ANL     A,@R1           AND Indirect RAM to Acc
-ANL     A,#_immed_      AND Immediate data to Acc
-ANL     BUS,#_immed_    AND Immediate data to BUS
-ANL     P1,#_immed_     AND Immediate data to port P1
-ANL     P2,#_immed_     AND Immediate data to port P2
-
-ANLD    P4,A            AND Acc to Expander port P4
-ANLD    P5,A            AND Acc to Expander port P5
-ANLD    P6,A            AND Acc to Expander port P6
-ANLD    P7,A            AND Acc to Expander port P7
-
-CALL    _addr11_        Call subroutine
-
-CLR     A               Clear Acc
-CLR     C               Clear Carry
-CLR     F0              Clear Flag 0
-CLR     F1              Clear Flag 1
-
-CPL     A               Complement Acc
-CPL     C               Complement Carry
-CPL     F0              Complement Flag F0
-CPL     F1              Complement Flag F1
-
-DA      A               Decimal adjust Acc
-
-DEC     A               Decrement Acc
-DEC     Rn              Decrement Register
-
-DIS     I               Disable Interrupts
-DIS     TCNTI           Disable Timer/Counter Interrupt
-
-DJNZ    Rn,_addr8_      Decrement Register and Jump if nonzero
-
-EN      DMA             Enable DMA                           (8041)
-EN      FLAGS           Enable Flags                         (8041)
-EN      I               Enable External Interrupt
-EN      TCNTI           Enable Timer/Counter Interrupt
-ENT0    CLK             Enable Clock Output
-
-IN      A,DBB           Input Data Bus to Acc                (8041)
-IN      A,P0            Input Port 0 to Acc                  (8021)
-IN      A,P1            Input Port 1 to Acc
-IN      A,P2            Input Port 2 to Acc
-
-INC     A               Increment Acc
-INC     Rn              Increment Register
-INC     @R0             Increment Indirect RAM
-INC     @R1             Increment Indirect RAM
-
-INS     A,BUS           Strobed Input of Bus to Acc
-
-JB0     _addr8_         Jump if Acc bit 0 is set
-JB1     _addr8_         Jump if Acc bit 1 is set
-JB2     _addr8_         Jump if Acc bit 2 is set
-JB3     _addr8_         Jump if Acc bit 3 is set
-JB4     _addr8_         Jump if Acc bit 4 is set
-JB5     _addr8_         Jump if Acc bit 5 is set
-JB6     _addr8_         Jump if Acc bit 6 is set
-JB7     _addr8_         Jump if Acc bit 7 is set
-JMP     _addr11_        Jump
-JC      _addr8_         Jump if Carry is set
-JF0     _addr8_         Jump if Flag F0 is set
-JF1     _addr8_         Jump if Flag F1 is set
-JNC     _addr8_         Jump if Carry is clear
-JNI     _addr8_         Jump if Interrupt input is clear
-JNIBF   _addr8_         Jump if IBF is clear                 (8041)
-JNT0    _addr8_         Jump if T0 is clear
-JNT1    _addr8_         Jump if T1 is clear
-JNZ     _addr8_         Jump if Acc is not zero
-JOBF    _addr8_         Jump if OBF is set                   (8041)
-JTF     _addr8_         Jump if Timer Flag is set
-JT0     _addr8_         Jump if T0 pin is high
-JT1     _addr8_         Jump if T1 pin is high
-JZ      _addr8_         Jump if Acc is zero
-JMPP    @A              Jump Indirect (current page)
-
-MOV     A,PSW           Move PSW to Acc
-MOV     A,Rn            Move Register to Acc
-MOV     A,T             Move Timer/Counter to Acc
-MOV     A,@R0           Move Indirect RAM to Acc
-MOV     A,@R1           Move Indirect RAM to Acc
-MOV     A,#_immed_      Move Immediate data to Acc
-MOV     PSW,A           Move Acc to PSW
-MOV     Rn,A            Move Acc to Register
-MOV     Rn,#_immed_     Move Immediate data to Register
-MOV     STS,A           Move Acc to STS                      (8041)
-MOV     T,A             Move Acc to Timer/Counter
-MOV     @R0,A           Move Acc to Indirect RAM
-MOV     @R1,A           Move Acc to Indirect RAM
-MOV     @R0,#_immed_    Move Immediate data to Indirect RAM
-MOV     @R1,#_immed_    Move Immediate data to Indirect RAM
-
-MOVD    A,P4            Move half-byte Port 4 to Acc (lower nibble)
-MOVD    A,P5            Move half-byte Port 5 to Acc (lower nibble)
-MOVD    A,P6            Move half-byte Port 6 to Acc (lower nibble)
-MOVD    A,P7            Move half-byte Port 7 to Acc (lower nibble)
-MOVD    P4,A            Move lower nibble of Acc to Port 4
-MOVD    P5,A            Move lower nibble of Acc to Port 5
-MOVD    P6,A            Move lower nibble of Acc to Port 6
-MOVD    P7,A            Move lower nibble of Acc to Port 7
-
-MOVP    A,@A            Move Indirect Program data to Acc
-MOVP3   A,@A            Move Indirect Program data to Acc (page 3)
-
-MOVX    A,@R0           Move Indirect External RAM to Acc
-MOVX    A,@R1           Move Indirect External RAM to Acc
-MOVX    @R0,A           Move Acc to Indirect External RAM
-MOVX    @R1,A           Move Acc to Indirect External RAM
-
-NOP                     No operation
-
-ORL     A,Rn            OR Register to Acc
-ORL     A,@R0           OR Indirect RAM to Acc
-ORL     A,@R1           OR Indirect RAM to Acc
-ORL     A,#_immed_      OR Immediate data to Acc
-ORL     BUS,#_immed_    OR Immediate data to BUS
-ORL     P1,#_immed_     OR Immediate data to port P1
-ORL     P2,#_immed_     OR Immediate data to port P2
-
-ORLD    P4,A            OR lower nibble of Acc with P4
-ORLD    P5,A            OR lower nibble of Acc with P5
-ORLD    P6,A            OR lower nibble of Acc with P6
-ORLD    P7,A            OR lower nibble of Acc with P7
-
-OUTL    BUS,A           Output Acc to Bus
-OUT     DBB,A           Output Acc to DBB                    (8041)
-OUTL    P0,A            Output Acc to Port P0                (8021)
-OUTL    P1,A            Output Acc to Port P1
-OUTL    P2,A            Output Acc to Port P2
-
-RAD                     Move A/D Converter to Acc            (8022)
-
-RET                     Return from subroutine
-RETI                    Return from Interrupt w/o PSW restore(8022)
-RETR                    Return from Interrupt w/  PSW restore
-
-RL      A               Rotate Acc Left
-RLC     A               Rotate Acc Left through Carry
-RR      A               Rotate Acc Right
-RRC     A               Rotate Acc Right through Carry
-
-SEL     AN0             Select Analog Input 0                (8022)
-SEL     AN1             Select Analog Input 1                (8022)
-SEL     MB0             Select Memory Bank 0
-SEL     MB1             Select Memory Bank 1
-SEL     RB0             Select Register Bank 0
-SEL     RB1             Select Register Bank 1
-
-STOP    TCNT            Stop Timer/Counter
-STRT    CNT             Start Counter
-STRT    T               Start Timer
-
-SWAP    A               Swap nibbles of Acc
-
-XCH     A,Rn            Exchange Register with Acc
-XCH     A,@R0           Exchange Indirect RAM with Acc
-XCH     A,@R1           Exchange Indirect RAM with Acc
-
-XCHD    A,@R0           Exchange lower nibble of Indirect RAM w/ Acc
-XCHD    A,@R1           Exchange lower nibble of Indirect RAM w/ Acc
-
-XRL     A,Rn            Exclusive OR Register to Acc
-XRL     A,@R0           Exclusive OR Indirect RAM to Acc
-XRL     A,@R1           Exclusive OR Indirect RAM to Acc
-XRL     A,#_immed_      Exclusive OR Immediate data to Acc
-
-

See manufacturer's data for a more complete description of the meaning of -the mnemonics and addressing modes. -

-
-

8051 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 8051 version of TASM. Where 'Rn' is -seen, R0 through R7 may be substituted. Other symbolic fields are as -follows: -

-
        
-SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr11_            Absolute address (11 bits)
-_addr16_            Absolute address (16 bits)
-_bit_               Bit address
-_immed_             Immediate data
-_direct_            Direct RAM address
-_rel_               Relative address
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-
OPCODE  OPERAND             DESCRIPTION
---------------------------------------------------------------------
-ACALL   _addr11_            Absolute Call
-ADD     A,Rn                Add Register to Acc
-ADD     A,@R0               Add Indirect RAM to Acc
-ADD     A,@R1               Add Indirect RAM to Acc
-ADD     A,#_immed_          Add Immediate data to Acc
-ADD     A,_direct_          Add Direct RAM to Acc
-ADDC    A,Rn                Add Register to Acc with carry
-ADDC    A,@R0               Add Indirect RAM to Acc with carry
-ADDC    A,@R1               Add Indirect RAM to Acc with carry
-ADDC    A,#_immed_          Add Immediate data to Acc with carry
-ADDC    A,_direct_          Add Direct RAM to Acc with carry
-
-AJMP    _addr11_            Absolute Jump
-
-ANL     A,Rn                AND Register and Acc
-ANL     A,@R0               AND Indirect RAM and Acc
-ANL     A,@R1               AND Indirect RAM and Acc
-ANL     A,#_immed_          AND Immediate data and Acc
-ANL     A,_direct_          AND Direct RAM and Acc
-ANL     C,/_bit_            AND Complement of direct bit to Carry
-ANL     C,bit>              AND direct bit to Carry
-ANL     _direct_,A          AND Acc to direct RAM
-ANL     _direct_,#_immed_   AND Immediate data and direct RAM
-
-CJNE    A,#_immed_,_rel_    Compare Immediate to Acc   and JNE
-CJNE    A,_direct_,_rel_    Compare direct RAM to Acc and JNE
-CJNE    Rn,#_immed_,_rel_   Compare Immediate to Register and JNE
-CJNE    @R0,#_immed_,_rel_  Compare Immediate to Indirect RAM and JNE
-CJNE    @R1,#_immed_,_rel_  Compare Immediate to Indirect RAM and JNE
-
-CLR     A                   Clear Accumulator
-CLR     C                   Clear Carry
-CLR     _bit_               Clear Bit
-
-CPL     A                   Complement Accumulator
-CPL     C                   Complement Carry
-CPL     _bit_               Complement Bit
-
-DA      A                   Decimal Adjust Accumulator
-DEC     A                   Decrement Acc
-DEC     Rn                  Decrement Register
-DEC     @R0                 Decrement Indirect RAM
-DEC     @R1                 Decrement Indirect RAM
-DEC     _direct_            Decrement Direct RAM
-
-DIV     AB                  Divide Acc by B
-
-DJNZ    Rn,_rel_            Decrement Register and JNZ
-DJNZ    _direct_,_rel_      Decrement Direct RAM and JNZ
-
-INC     A                   Increment Acc
-INC     Rn                  Increment Register
-INC     @R0                 Increment Indirect RAM
-INC     @R1                 Increment Indirect RAM
-INC     DPTR                Increment Data Pointer
-INC     _direct_            Increment Direct RAM
-
-JB      _bit_,_rel_         Jump if Bit is set
-JBC     _bit_,_rel_         Jump if Bit is set & clear Bit
-JC      _rel_               Jump if Carry is set
-JMP     @A+DPTR             Jump indirect relative to Data Pointer
-JNB     _bit_,_rel_         Jump if Bit is clear
-JNC     _rel_               Jump if Carry is clear
-JNZ     _rel_               Jump if Acc is not zero
-JZ      _rel_               Jump if Acc is zero
-
-LCALL   _addr16_            Long Subroutine Call
-LJMP    _addr16_            Long Jump
-
-MOV     A,Rn                Move Register to Acc
-MOV     A,@R0               Move Indirect RAM to Acc
-MOV     A,@R1               Move Indirect RAM to Acc
-MOV     A,#_immed_          Move Immediate data to Acc
-MOV     A,_direct_          Move direct RAM to Acc
-MOV     C,_bit_             Move bit to Acc
-MOV     DPTR,#_immed_       Move immediate data to Data Pointer
-MOV     Rn,A                Move Acc to Register
-MOV     Rn,#_immed_         Move Immediate data to Register
-MOV     Rn,_direct_         Move Direct RAM to Register
-MOV     @R0,A               Move Acc to Indirect RAM
-MOV     @R1,A               Move Acc to Indirect RAM
-MOV     @R0,#_immed_        Move Immediate data to Indirect RAM
-MOV     @R1,#_immed_        Move Immediate data to Indirect RAM
-MOV     @R0,_direct_        Move Direct RAM to Indirect RAM
-MOV     @R1,_direct_        Move Direct RAM to Indirect RAM
-MOV     _direct_,A          Move Acc to Direct RAM
-MOV     _bit_,C             Move Carry to Bit
-MOV     _direct_,Rn         Move Register to Direct RAM
-MOV     _direct_,@R0        Move Indirect RAM to Direct RAM
-MOV     _direct_,@R1        Move Indirect RAM to Direct RAM
-MOV     _direct_,#_immed_   Move Immediate data to Direct RAM
-MOV     _direct_,_direct_   Move Direct RAM to Direct RAM
-MOVC    A,@A+DPTR           Move code byte relative to DPTR to Acc
-MOVC    A,@A+PC             Move code byte relative to PC to Acc
-
-MOVX    A,@R0               Move external RAM to Acc
-MOVX    A,@R1               Move external RAM to Acc
-MOVX    A,@DPTR             Move external RAM to Acc (16 bit addr)
-MOVX    @R0,A               Move Acc to external RAM
-MOVX    @R1,A               Move Acc to external RAM
-MOVX    @DPTR,A             Move Acc to external RAM (16 bit addr)
-
-MUL     AB                  Multiply Acc by B
-
-NOP                         No operation
-
-ORL     A,Rn                OR Register and Acc
-ORL     A,@R0               OR Indirect RAM and Acc
-ORL     A,@R1               OR Indirect RAM and Acc
-ORL     A,#_immed_          OR Immediate data and Acc
-ORL     A,_direct_          OR Direct RAM and Acc
-ORL     C,/_bit_            OR Complement of direct bit to Carry
-ORL     C,_bit_             OR direct bit to Carry
-ORL     _direct_,A          OR Acc to direct RAM
-ORL     _direct_,#_immed_   OR Immediate data and direct RAM
-
-POP     _direct_            Pop  from Stack and put in Direct RAM
-PUSH    _direct_            Push from Direct RAM to Stack
-
-RET                         Return from subroutine
-RETI                        Return from Interrupt
-
-RL      A                   Rotate Acc left
-RLC     A                   Rotate Acc left through Carry
-RR      A                   Rotate Acc right
-RRC     A                   Rotate Acc right through Carry
-
-SETB    C                   Set the Carry Bit
-SETB    _bit_               Set Direct Bit
-
-SJMP    _rel_               Short jump
-
-SUBB    A,Rn                Subtract Register from Acc with Borrow
-SUBB    A,@R0               Subtract Indirect RAM from Acc w/ Borrow
-SUBB    A,@R1               Subtract Indirect RAM from Acc w/ Borrow
-SUBB    A,#_immed_          Subtract Immediate data from Acc w/ Borrow
-SUBB    A,_direct_          Subtract Direct RAM from Acc w/ Borrow
-
-SWAP    A                   Swap nibbles of Acc
-
-XCH     A,Rn                Exchange Acc with Register
-XCH     A,@R0               Exchange Acc with Indirect RAM
-XCH     A,@R1               Exchange Acc with Indirect RAM
-XCH     A,_direct_          Exchange Acc with Direct RAM
-
-XCHD    A,@R0               Exchange Digit in Acc with Indirect RAM
-XCHD    A,@R1               Exchange Digit in Acc with Indirect RAM
-
-XRL     A,Rn                Exclusive OR Register and Acc
-XRL     A,@R0               Exclusive OR Indirect RAM and Acc
-XRL     A,@R1               Exclusive OR Indirect RAM and Acc
-XRL     A,#_immed_          Exclusive OR Immediate data and Acc
-XRL     A,_direct_          Exclusive OR Direct RAM and Acc
-XRL     _direct_,A          Exclusive OR Acc to direct RAM
-XRL     _direct_,#_immed_   Exclusive OR Immediate data and direct RAM
-
-

Note that the above tables do not automatically define the various -mnemonics that may be used for addressing the special function registers -of the 8051. The user may wish to set up a file of equates (EQU's) that -can be included in the source file for this purpose. The following -illustrates some of the appropriate equates: -

-
P0      .equ    080H    ;Port 0
-SP      .equ    081H    ;Stack pointer
-DPL     .equ    082H
-DPH     .equ    083H
-PCON    .equ    087H
-TCON    .equ    088H
-TMOD    .equ    089H
-TL0     .equ    08AH
-TL1     .equ    08BH
-TH0     .equ    08CH
-TH1     .equ    08DH
-P1      .equ    090H    ;Port 1
-SCON    .equ    098H
-SBUF    .equ    099H
-P2      .equ    0A0H    ;Port 2
-IEC     .equ    0A8H
-P3      .equ    0B0H    ;Port 3
-IPC     .equ    0B8H
-PSW     .equ    0D0H
-ACC     .equ    0E0H    ;Accumulator
-B       .equ    0F0H    ;Secondary Accumulator
-;Now some bit addresses
-P0.0    .equ    080H    ;Port 0 bit 0
-P0.1    .equ    081H    ;Port 0 bit 1
-P0.2    .equ    082H    ;Port 0 bit 2
-P0.3    .equ    083H    ;Port 0 bit 3
-P0.4    .equ    084H    ;Port 0 bit 4
-P0.5    .equ    085H    ;Port 0 bit 5
-P0.6    .equ    086H    ;Port 0 bit 6
-P0.7    .equ    087H    ;Port 0 bit 7
-ACC.0   .equ    0E0H    ;Acc bit 0
-ACC.1   .equ    0E1H    ;Acc bit 1
-ACC.2   .equ    0E2H    ;Acc bit 2
-ACC.3   .equ    0E3H    ;Acc bit 3
-ACC.4   .equ    0E4H    ;Acc bit 4
-ACC.5   .equ    0E5H    ;Acc bit 5
-ACC.6   .equ    0E6H    ;Acc bit 6
-ACC.7   .equ    0E7H    ;Acc bit 7
-
-

See the manufacturer's data sheets for more information. -

-
-

8085 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 8085 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr_              Absolute address (16 bits)
-_data_              Immediate data (8 bits)
-_data16_            Immediate data (16 bits)
-_reg_               Register (A,B,C,D,E,H,L)
-_rp_                Register pair (B,D,H,SP)
-_port_              Port address (0-255)
-_int_               Interrupt level (0 - 7)
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics except _reg_, _rp_ and _int_. -

-
OPCODE  OPERAND        DESCRIPTION
---------------------------------------------------------------------
-ACI      _data_         Add immediate to A with carry
-ADC      _reg_          Add _reg_ to A with carry
-ADC      M              Add indirect memory (HL) with carry
-ADD      _reg_          Add _reg_ to A
-ADD      M              Add indirect memory (HL) to A
-ADI      _data_         Add immediate to A
-
-ANA      _reg_          And register with A
-ANA      M              And indirect memory (HL) to A
-ANI      _data_         And immediate to A
-
-CALL     _addr_         Call subroutine at _addr_
-CC       _addr_         Call subroutine if carry set
-CNC      _addr_         Call subroutine if carry clear
-CZ       _addr_         Call subroutine if zero
-CNZ      _addr_         Call subroutine if non zero
-CP       _addr_         Call subroutine if positive
-CM       _addr_         Call subroutine if negative
-CPE      _addr_         Call subroutine if even parity
-CPO      _addr_         Call subroutine if odd  parity
-CMA                     Complement A
-CMC                     Complemennt carry
-CMP      _reg_          Compare register with A
-CMP      M              Compare indirect memory (HL) with A
-CPI      _data_         Compare immediate data with A
-
-DAA                     Decimal adjust A
-DAD      _rp_           Add register pair to HL
-DCR      _reg_          Decrement register
-DCR      M              Decrement indirect memory (HL)
-DCX      _rp_           Decrement register pair
-
-DI                      Disable interrupts
-EI                      Enable interrupts
-HLT                     Halt
-
-IN       _port_         Input on port
-INR      _reg_          Increment register
-INR      M              Increment indirect memory (HL)
-INX      _rp_           Increment register pair
-
-JMP      _addr_         Jump
-JC       _addr_         Jump if carry set
-JNC      _addr_         Jump if carry clear
-JZ       _addr_         Jump if zero
-JNZ      _addr_         Jump if not zero
-JM       _addr_         Jump if minus
-JP       _addr_         Jump if plus
-JPE      _addr_         Jump if parity even
-JPO      _addr_         Jump if parity odd
-
-LDA      _addr_         Load A direct from memory
-LDAX     B              Load A indirect from memory using BC
-LDAX     D              Load A indirect from memory using DE
-LHLD     _addr_         Load HL direct from memory
-LXI      _rp_,_data16_  Load register pair with immediate data
-
-MOV      _reg_,_reg_    Move register to register
-MOV      _reg_,M        Move indirect memory (HL) to register
-MVI      _reg_,_data_   Move immediate data to register
-
-NOP                     No operation
-
-ORA      _reg_          Or register with A
-ORA      M              Or indirect memory (HL) with A
-ORI      _data_         Or immediate data to A
-OUT      _port_         Ouput to port
-
-PCHL                    Jump to instruction at (HL)
-POP      _rp_           Pop  register pair (excluding SP) from stack
-PUSH     _rp_           Push register pair (excluding SP) onto stack
-POP      PSW            Pop  PSW from stack
-PUSH     PSW            Pop  PSW onto stack
-
-RAL                     Rotate A left  with carry
-RAR                     Rotate A right with carry
-RLC                     Rotate A left  with branch carry
-RRC                     Rotate A right with branch carry
-
-RET                     Return from subroutine
-RZ                      Return if zero
-RNZ                     Return if non zero
-RC                      Return if carry set
-RNC                     Return if carry clear
-RM                      Return if minus
-RP                      Return if plus
-RPE                     Return if parity even
-RPO                     Return if parity odd
-
-RIM                     Read interrupt mask
-RST      _int_          Restart at vector _int_
-
-SBB      _reg_          Subtract _reg_ from A         with borrow
-SBB      M              Subtract indirect memory (HL) with borrow
-SBI      _data_         Subtract immediate from A     with borrow
-SUB      _reg_          Subtract _reg_ from A
-SUB      M              Subtract indirect memory (HL) from A
-SUI      _data_         Subtract immediate from A
-
-SHLD     _addr_         Store HL
-SIM                     Store Interrupt mask
-SPHL                    Exchange SP with HL
-
-STA      _addr_         Store A direct memory
-STAX     B              Store A indirect using BC
-STAX     D              Store A indirect using DE
-
-STC                     Set carry
-
-XRA      _reg_          Exclusive OR A with register
-XRA      M              Exclusive Or A with indirect memory (HL)
-XRI      _data_         Exclusive Or A with immediate data
-XCHG                    Exchange DE with HL
-XTHL                    Exchange HL with top of stack
-
-
-

See the manufacturer's data sheets for more information. -

-
-

Z80 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the Z80 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr_              Absolute address (16 bits)
-_bit_               Bit address
-_data_              Immediate data (8 bits)
-_data16_            Immediate data (16 bits)
-_disp_              Relative address
-_reg_               Register (A, B, C, D, E, H, or L)
-_rp_                Register pair (BC, DE, HL, or SP)
-_port_              Port (0 - 255)
-_cond_              Condition
-			NZ - not zero
-			Z  - zero
-			NC - not carry
-			C  - carry
-			PO - parity odd
-			PE - parity even
-			P  - positive
-			M  - minus
-
-
-

Any valid TASM expression can appear in the place of the _addr_, _bit_, -_data_, _data16_, or _disp_ symbolics. -

-
OPCODE  OPERAND         DESCRIPTION
---------------------------------------------------------------------
-ADC  A,_data_           Add immediate with carry to accumulator
-ADC  A,_reg_            Add register with carry to accumulator
-ADC  A,(HL)             Add indirect memory with carry to accumulator
-ADC  A,(IX+_disp_)      Add indirect memory with carry to accumulator
-ADC  A,(IY+_disp_)      Add indirect memory with carry to accumulator
-ADC  HL,_rp_            Add register pair with carry to HL
-
-ADD  A,_data_           Add immediate to accumulator
-ADD  A,_reg_            Add register to accumulator
-ADD  A,(HL)             Add indirect memory to accumulator
-ADD  A,(IX+_disp_)      Add indirect memory to accumulator
-ADD  A,(IY+_disp_)      Add indirect memory to accumulator
-ADD  HL,_rp_            Add register pair to HL
-ADD  IX,_rp_            Add register pair to index register
-ADD  IY,_rp_            Add register pair to index register
-
-AND  _data_             And immediate with accumulator
-AND  _reg_              And register  with accumulator
-AND  (HL)               And memory with accumulator
-AND  (IX+_disp_)        And memory with accumulator
-AND  (IY+_disp_)        And memory with accumulator
-
-BIT  _bit_,_reg_        Test _bit_ in register
-BIT  _bit_,(HL)         Test _bit_ in indirect memory
-BIT  _bit_,(IY+_disp_)  Test _bit_ in indirect memory
-BIT  _bit_,(IX+_disp_)  Test _bit_ in indirect memory
-
-CALL _addr_             Call the routine at _addr_
-CALL _cond_,_addr_      Call the routine if _cond_ is satisfied
-
-CCF                     Complement carry flag
-
-CP   _data_             Compare immediate data with accumulator
-CP   _reg_              Compare register with accumulator
-CP   (HL)               Compare indirect memory with accumulator
-CP   (IX+_disp_)        Compare indirect memory with accumulator
-CP   (IY+_disp_)        Compare indirect memory with accumulator
-CPD                     Compare accumulator with memory and
-                            decrement address and byte counters
-CPDR                    Compare accumulator with memory and
-                            decrement address and byte counter,
-                            continue until match is found or
-                            byte counter is zero
-
-CPI                     Compare accumulator with memory and
-                            increment address and byte counters
-CPIR                    Compare accumulator with memory and
-                            increment address and byte counter,
-                            continue until match is found or
-                            byte counter is zero
-CPL                     Complement the accumulator
-DAA                     Decimal adjust accumulator
-DEC  _reg_              Decrement register contents
-DI                      Disable interrupts
-DJNZ _disp_             Decrement reg B and jump relative if zero
-EI                      Enable interrupts
-EX   AF,AF'             Exchange program status and alt program stat
-EX   DE,HL              Exchange DE and HL contents
-EX   (SP),HL            Exchange contents of HL and top of stack
-EX   (SP),IX            Exchange contents of IX and top of stack
-EX   (SP),IY            Exchange contents of IY and top of stack
-EXX                     Exchange register pairs and alt reg pairs
-HALT                    Program execution stops
-IM   0                  Interrupt mode 0
-IM   1                  Interrupt mode 1
-IM   2                  Interrupt mode 2
-IN   A,_port_           Input port to accumulator
-INC  _reg_              Increment contents of register
-INC  _rp_               Increment contents of register pair
-INC  IX                 Increment IX
-INC  IY                 Increment IY
-INC  (HL)               Increment indirect memory
-INC  (IX+_disp_)        Increment indirect memory
-INC  (IY+_disp_)        Increment indirect memory
-IND                     Input to memory and decrement pointer
-INDR                    Input to memory and decrement pointer until
-                            byte counter is zero
-INI                     Input to memory and increment pointer
-INIR                    Input to memory and increment pointer until
-                            byte counter is zero
-IN   _reg_,(C)          Input to register
-
-JP   _addr_             Jump to location
-JP   _cond_,_addr_      Jump to location if condition satisifed
-JP   (HL)               Jump to location pointed to by HL
-JP   (IX)               Jump to location pointed to by IX
-JP   (IY)               Jump to location pointed to by IY
-
-JR   _disp_             Jump relative
-JR   C,_disp_           Jump relative if carry is set
-JR   NC,_disp_          Jump relative if carry bit is reset
-JR   NZ,_disp_          Jump relative if zero flag is reset
-JR   Z,_disp_           Jump relative if zero flag is set
-
-LD   A,I                Move interrupt vector contents to accumulator
-LD   A,R                Move refresh reg contents to accumulator
-LD   A,(_addr_)         Load accumulator indirect from memory
-LD   A,(_rp_)           Load accumulator indirect from memory by _rp_
-LD   _reg_,_reg_        Load source register to destination register
-LD   _rp_,(_addr_)      Load register pair indirect from memory
-LD   IX,(_addr_)        Load IX indirect from memory
-LD   IY,(_addr_)        Load IY indirect from memory
-LD   I,A                Load interrup vector from accumulator
-LD   R,A                Load refresh register from accumulator
-LD   _reg_,_data_       Load register with immediate data
-LD   _rp_,_data16_      Load register pair with immediate data
-LD   IX,_data16_        Load  IX  with immediate data
-LD   IY,_data16_        Load  IY  with immediate data
-LD   _reg_,(HL)         Load register indirect from memory
-LD   _reg_,(IX+_disp_)  Load register indirect from memory
-LD   _reg_,(IY+_disp_)  Load register indirect from memory
-LD   SP,HL              Load contents of HL to stack pointer
-LD   SP,IX              Load contents of IX to stack pointer
-LD   SP,IY              Load contents of IY to stack pointer
-LD   (addr),A           Load contents of A to memory
-LD   (_addr_),HL        Load contents of HL to memory
-LD   (_addr_),_rp_      Load contents of register pair to memory
-LD   (_addr_),IX        Load contents of IX to memory
-LD   (_addr_),IY        Load contents of IY to memory
-LD   (HL),_data_        Load immediate into indirect memory
-LD   (IX+_disp_),_data_ Load immediate into indirect memory
-LD   (IY+_disp_),_data_ Load immediate into indirect memory
-LD   (HL),_reg_         Load register  into indirect memory
-LD   (IX+_disp_),_reg_  Load register  into indirect memory
-LD   (IY+_disp_),_reg_  Load register  into indirect memory
-LD   (_rp_),A           Load accumulator into indirect memory
-LDD                     Transfer data between memory and decrement
-                            destination and source addresses
-LDDR                    Transfer data between memory until byte
-                            counter is zero, decrement destintation
-                            and source addresses
-LDI                     Transfer data between memory and increment
-                            destination and source addresses
-LDIR                    Transfer data between memory until byte
-                            counter is zero, increment destination
-                            and source addresses
-NEG                     Negate contents of accumulator
-NOP                     No operation
-OR   _data_             Or immediate with accumulator
-OR   _reg_              Or register with accumulator
-OR   (HL)               Or indirect memory with accumulator
-OR   (IX+_disp_)        Or indirect memory with accumulator
-OR   (IY+_disp_)        Or indirect memory with accumulator
-OUT  (C),_reg_          Output from registor
-OUTD                    Output from memory, decrement address
-OTDR                    Output from memory, decrement address
-                            continue until reg B is zero
-OUTI                    Output from memory, increment address
-OTIR                    Output from memory, increment address
-                            continue until reg B is zero
-OUT  _port_,A           Output from accumulator
-POP  _rp_               Load register pair from top of stack
-POP  IX                 Load IX from top of stack
-POP  IY                 Load IY from top of stack
-PUSH _rp_               Store resister pair on top of stack
-PUSH IX                 Store IX on top of stack
-PUSH IY                 Store IY on top of stack
-RES  _bit_,_reg_        Reset register bit
-RES  _bit_,(HL)         Reset bit at indirect memory location
-RES  _bit_,(IX+disp)    Reset bit at indirect memory location
-RES  _bit_,(IY+_disp_)  Reset bit at indirect memory location
-RET                     Return from subroutine
-RET  _cond_             Return from subroutine if condition true
-RETI                    Return from interrupt
-RETN                    Return from non-maskable interrupt
-RL   _reg_              Rotate left through carry register contents
-RL   (HL)               Rotate left through carry indirect memory
-RL   (IX+_disp_)        Rotate left through carry indirect memory
-RL   (IY+_disp_)        Rotate left through carry indirect memory
-RLA                     Rotate left through carry accumulator
-RLC  _reg_              Rotate left branch  carry register contents
-RLC  (HL)               Rotate left branch  carry indirect memory
-RLC  (IX+_disp_)        Rotate left branch  carry indirect memory
-RLC  (IY+_disp_)        Rotate left branch  carry indirect memory
-RLCA                    Rotate left accumulator
-RLD                     Rotate one BCD digit left between the
-                            accumulator and memory
-RR   _reg_              Rotate right through carry register contents
-RR   (HL)               Rotate right through carry indirect memory
-RR   (IX+_disp_)        Rotate right through carry indirect memory
-RR   (IY+_disp_)        Rotate right through carry indirect memory
-RRA                     Rotate right through carry accumulator
-RRC  _reg_              Rotate right branch  carry register contents
-RRC  (HL)               Rotate right branch  carry indirect memory
-RRC  (IX+_disp_)        Rotate right branch  carry indirect memory
-RRC  (IY+_disp_)        Rotate right branch  carry indirect memory
-RRCA                    Rotate right branch  carry accumulator
-RRD                     Rotate one BCD digit right between the
-                            accumulator and memory
-RST                     Restart
-SBC  A,_data_           Subtract data            from A with borrow
-SBC  A,_reg_            Subtract register        from A with borrow
-SBC  A,(HL)             Subtract indirect memory from A with borrow
-SBC  A,(IX+_disp_)      Subtract indirect memory from A with borrow
-SBC  A,(IY+_disp_)      Subtract indirect memory from A with borrow
-SBC  HL,_rp_            Subtract register pair from HL with borrow
-SCF                     Set carry flag
-SET  _bit_,_reg_        Set register bit
-SET  _bit_,(HL)         Set indirect memory bit
-SET  _bit_,(IX+_disp_)  Set indirect memory bit
-SET  _bit_,(IY+_disp_)  Set indirect memory bit
-SLA  _reg_              Shift register left arithmetic
-SLA  (HL)               Shift indirect memory left arithmetic
-SLA  (IX+_disp_)        Shift indirect memory left arithmetic
-SLA  (IY+_disp_)        Shift indirect memory left arithmetic
-SRA  _reg_              Shift register right arithmetic
-SRA  (HL)               Shift indirect memory right arithmetic
-SRA  (IX+_disp_)        Shift indirect memory right arithmetic
-SRA  (IY+_disp_)        Shift indirect memory right arithmetic
-SRL  _reg_              Shift register right logical
-SRL  (HL)               Shift indirect memory right logical
-SRL  (IX+_disp_)        Shift indirect memory right logical
-SRL  (IY+_disp_)        Shift indirect memory right logical
-SUB  _data_             Subtract immediate from accumulator
-SUB  _reg_              Subtract register from accumulator
-SUB  (HL)               Subtract indirect memory from accumulator
-SUB  (IX+_disp_)        Subtract indirect memory from accumulator
-SUB  (IY+_disp_)        Subtract indirect memory from accumulator
-XOR  _data_             Exclusive or immediate with accumulator
-XOR  _reg_              Exclusive or register with accumulator
-XOR  (HL)               Exclusive or indirect memory with accumulator
-XOR  (IX+_disp_)        Exclusive or indirect memory with accumulator
-XOR  (IY+_disp_)        Exclusive or indirect memory with accumulator
-
-

See the manufacturer's data sheets for more information. -

-
-

6805 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the 6805 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_addr_              Absolute address (16 bits)
-_addr8_             Absolute address (8 bits)
-_bit_               Bit address
-_data_              Immediate data (8 bits)
-_rel_               Relative address
-
-
-

Any valid TASM expression can appear in the place of the _addr_, _addr8_, -_bit_, _data_, or _rel_ symbolics. -

-
OPCODE  OPERAND         DESCRIPTION
---------------------------------------------------------------
-ADC     #_data_         Add with carry, immediate
-ADC     ,X              Add with carry, indexed, no offset
-ADC     _addr8_,X       Add with carry, indexed, 1 byte offset
-ADC     _addr_,X        Add with carry, indexed, 2 byte offset
-ADC     _addr8_         Add with carry, direct
-ADC     _addr_          Add with carry, extended
-
-ADD     #_data_         Add, immediate
-ADD     ,X              Add, indexed, no offset
-ADD     _addr8_,X       Add, indexed, 1 byte offset
-ADD     _addr_,X        Add, indexed, 2 byte offset
-ADD     _addr8_         Add, direct
-ADD     _addr_          Add, extended
-
-AND     #_data_         And, immediate
-AND     ,X              And, indexed, no offset
-AND     _addr8_,X       And, indexed, 1 byte offset
-AND     _addr_,X        And, indexed, 2 byte offset
-AND     _addr8_         And, direct
-AND     _addr_          And, extended
-
-ASLA                    Arithmetic Shift Left, accumulator
-ASLX                    Arithmetic Shift Left, index register
-ASL     _addr8_         Arithmetic Shift Left, direct
-ASL     ,X              Arithmetic Shift Left, indexed, no offset
-ASL     _addr8_,X       Arithmetic Shift Left, indexed, 1 byte offset
-
-ASRA                    Arithmetic Shift Right, accumulator
-ASRX                    Arithmetic Shift Right, index register
-ASR     _addr8_         Arithmetic Shift Right, direct
-ASR     ,X              Arithmetic Shift Right, indexed, no offset
-ASR     _addr8_,X       Arithmetic Shift Right, indexed, 1 byte offset
-
-BCC     _rel_           Branch if carry clear
-BCLR    _bit_,_addr8_   Bit Clear in memory
-BCS     _rel_           Branch if carry set
-BEQ     _rel_           Branch if equal
-BHCC    _rel_           Branch if half carry clear
-BHCS    _rel_           Branch if half carry set
-BHI     _rel_           Branch if higher
-BHS     _rel_           Branch if higher or same
-BIH     _rel_           Branch if interrupt line is high
-BIL     _rel_           Branch if interrupt is low
-
-BIT     #_data_         Bit test, immediate
-BIT     ,X              Bit test, indexed, no offset
-BIT     _addr8_,X       Bit test, indexed, 1 byte offset
-BIT     _addr_,X        Bit test, indexed, 2 byte offset
-BIT     _addr8_         Bit test, direct
-BIT     _addr_          Bit test, extended
-
-BLO     _rel_           Branch if lower
-BLS     _rel_           Branch if lower or same
-BMC     _rel_           Branch if interrupt mask is clear
-BMI     _rel_           Branch if minus
-BMS     _rel_           Branch if interuupt mask bit is set
-BNE     _rel_           Branch if not equal
-BPL     _rel_           Branch if plus
-BRA     _rel_           Branch always
-BRCLR   _bit_,_addr8_,_rel_     Branch if bit is clear
-BRN     _rel_           Branch never
-BRSET   _bit_,_addr8_,_rel_     Branch if bit is set
-BSET    _bit_,_addr8_   Bit set in memory
-BSR     _rel_           Branch to subroutine
-
-CLC                     Clear carry bit
-CLI                     Clear interuupt mask bit
-
-CLRA                    Clear, accumulator
-CLRX                    Clear, index register
-CLR     _addr8_         Clear, direct
-CLR     ,X              Clear, indexed, no offset
-CLR     _addr8_,X       Clear, indexed, 1 byte offset
-
-CMP     #_data_         Compare Acc, immediate
-CMP     ,X              Compare Acc, indexed, no offset
-CMP     _addr8_,X       Compare Acc, indexed, 1 byte offset
-CMP     _addr_,X        Compare Acc, indexed, 2 byte offset
-CMP     _addr8_         Compare Acc, direct
-CMP     _addr_          Compare Acc, extended
-
-COMA                    Complement, accumulator
-COMX                    Complement, index register
-COM     _addr8_         Complement, direct
-COM     ,X              Complement, indexed, no offset
-COM     _addr8_,X       Complement, indexed, 1 byte offset
-
-CPX     #_data_         Compare Index, immediate
-CPX     ,X              Compare Index, indexed, no offset
-CPX     _addr8_,X       Compare Index, indexed, 1 byte offset
-CPX     _addr_,X        Compare Index, indexed, 2 byte offset
-CPX     _addr8_         Compare Index, direct
-CPX     _addr_          Compare Index, extended
-
-DECA                    Decrement, accumulator
-DECX                    Decrement, index register
-DEX                     Decrement, index register (alternate of DECX)
-DEC     _addr8_         Decrement, direct
-DEC     ,X              Decrement, indexed, no offset
-DEC     _addr8_,X       Decrement, indexed, 1 byte offset
-
-EOR     #_data_         Exclusive OR, immediate
-EOR     ,X              Exclusive OR, indexed, no offset
-EOR     _addr8_,X       Exclusive OR, indexed, 1 byte offset
-EOR     _addr_,X        Exclusive OR, indexed, 2 byte offset
-EOR     _addr8_         Exclusive OR, direct
-EOR     _addr_          Exclusive OR, extended
-
-INCA                    Increment, accumulator
-INCX                    Increment, index register
-INX                     Increment, index register (alternate of INCX)
-INC     _addr8_         Increment, direct
-INC     ,X              Increment, indexed, no offset
-INC     _addr8_,X       Increment, indexed, 1 byte offset
-
-JMP     ,X              Jump, indexed, no offset
-JMP     _addr8_,X       Jump, indexed, 1 byte offset
-JMP     _addr_,X        Jump, indexed, 2 byte offset
-JMP     _addr8_         Jump, direct
-JMP     _addr_          Jump, extended
-
-JSR     ,X              Jump Subroutine, indexed, no offset
-JSR     _addr8_,X       Jump Subroutine, indexed, 1 byte offset
-JSR     _addr_,X        Jump Subroutine, indexed, 2 byte offset
-JSR     _addr8_         Jump Subroutine, direct
-JSR     _addr_          Jump Subroutine, extended
-
-LDA     #_data_         Load Acc, immediate
-LDA     ,X              Load Acc, indexed, no offset
-LDA     _addr8_,X       Load Acc, indexed, 1 byte offset
-LDA     _addr_,X        Load Acc, indexed, 2 byte offset
-LDA     _addr8_         Load Acc, direct
-LDA     _addr_          Load Acc, extended
-
-LDX     #_data_         Load Index, immediate
-LDX     ,X              Load Index, indexed, no offset
-LDX     _addr8_,X       Load Index, indexed, 1 byte offset
-LDX     _addr_,X        Load Index, indexed, 2 byte offset
-LDX     _addr8_         Load Index, direct
-LDX     _addr_          Load Index, extended
-
-LSLA                    Logical Shift Left, accumulator
-LSLX                    Logical Shift Left, index register
-LSL     _addr8_         Logical Shift Left, direct
-LSL     ,X              Logical Shift Left, indexed, no offset
-LSL     _addr8_,X       Logical Shift Left, indexed, 1 byte offset
-
-LSRA                    Logical Shift Right, accumulator
-LSRX                    Logical Shift Right, index register
-LSR     _addr8_         Logical Shift Right, direct
-LSR     ,X              Logical Shift Right, indexed, no offset
-LSR     _addr8_,X       Logical Shift Right, indexed, 1 byte offset
-
-NEGA                    Negate, accumulator
-NEGX                    Negate, index register
-NEG     _addr8_         Negate, direct
-NEG     ,X              Negate, indexed, no offset
-NEG     _addr8_,X       Negate, indexed, 1 byte offset
-
-NOP                     No Operation
-
-ORA     #_data_         Inclusive OR Acc, immediate
-ORA     ,X              Inclusive OR Acc, indexed, no offset
-ORA     _addr8_,X       Inclusive OR Acc, indexed, 1 byte offset
-ORA     _addr_,X        Inclusive OR Acc, indexed, 2 byte offset
-ORA     _addr8_         Inclusive OR Acc, direct
-ORA     _addr_          Inclusive OR Acc, extended
-
-ROLA                    Rotate Left thru Carry, accumulator
-ROLX                    Rotate Left thru Carry, index register
-ROL     _addr8_         Rotate Left thru Carry, direct
-ROL     ,X              Rotate Left thru Carry, indexed, no offset
-ROL     _addr8_,X       Rotate Left thru Carry, indexed, 1 byte offset
-
-RORA                    Rotate Right thru Carry, accumulator
-RORX                    Rotate Right thru Carry, index register
-ROR     _addr8_         Rotate Right thru Carry, direct
-ROR     ,X              Rotate Right thru Carry, indexed, no offset
-ROR     _addr8_,X       Rotate Right thru Carry, indexed, 1 byte offset
-
-RSP                     Reset Stack Pointer
-RTI                     Return from Interrupt
-RTS                     Return from Subroutine
-
-SBC     #_data_         Subtract with Carry, immediate
-SBC     ,X              Subtract with Carry, indexed, no offset
-SBC     _addr8_,X       Subtract with Carry, indexed, 1 byte offset
-SBC     _addr_,X        Subtract with Carry, indexed, 2 byte offset
-SBC     _addr8_         Subtract with Carry, direct
-SBC     _addr_          Subtract with Carry, extended
-
-SEC                     Set carry bit
-SEI                     Set interrupt Mask bit
-
-STA     #_data_         Store Acc, immediate
-STA     ,X              Store Acc, indexed, no offset
-STA     _addr8_,X       Store Acc, indexed, 1 byte offset
-STA     _addr_,X        Store Acc, indexed, 2 byte offset
-STA     _addr8_         Store Acc, direct
-STA     _addr_          Store Acc, extended
-
-STOP                    Enable IRQ, Stop Oscillator
-
-STX     #_data_         Store Index, immediate
-STX     ,X              Store Index, indexed, no offset
-STX     _addr8_,X       Store Index, indexed, 1 byte offset
-STX     _addr_,X        Store Index, indexed, 2 byte offset
-STX     _addr8_         Store Index, direct
-STX     _addr_          Store Index, extended
-
-SUB     #_data_         Subtract, immediate
-SUB     ,X              Subtract, indexed, no offset
-SUB     _addr8_,X       Subtract, indexed, 1 byte offset
-SUB     _addr_,X        Subtract, indexed, 2 byte offset
-SUB     _addr8_         Subtract, direct
-SUB     _addr_          Subtract, extended
-
-SWI                     Software Interrupt
-
-TAX                     Transfer Acc to Index
-
-TSTA                    Test for neg or zero, accumulator
-TSTX                    Test for neg or zero, index register
-TST     _addr8_         Test for neg or zero, direct
-TST     ,X              Test for neg or zero, indexed, no offset
-TST     _addr8_,X       Test for neg or zero, indexed, 1 byte offset
-
-TXA                     Transfer Index to Acc
-
-WAIT                    Enable Interrupt, Stop Processor
-
-
-

See the manufacturer's data sheets for more information. -

-
-

TMS32010 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the TMS32010 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_ar_                Auxiliary register (AR0, AR1)
-_arp_               Auxiliary register pointer
-_dma_               Direct memory address
-_pma_               Program memory address
-_port_              Port address (0 - 7)
-_shift_             Shift count  (0 - 15)
-_const1_            Constant (1 bit)
-_const8_            Constant (8 bit)
-_const13_           Constant (13 bit)
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-
OPCODE   OPERAND            DESCRIPTION
---------------------------------------------------------------------
-ABS                         Absolute value of ACC
-
-ADD      *+,_shift_,_arp_   Add to ACC with shift
-ADD      *-,_shift_,_arp_
-ADD      *, _shift_,_arp_
-ADD      *+,_shift_
-ADD      *-,_shift_
-ADD      *, _shift_
-ADD      *+
-ADD      *-
-ADD      *
-ADD      _dma_,_shift_
-ADD      _dma_
-
-ADDH     *+,_arp_           Add to high-order ACC bits
-ADDH     *-,_arp_
-ADDH     *, _arp_
-ADDH     *+
-ADDH     *-
-ADDH     *
-ADDH     _dma_
-
-ADDS     *+,_arp_           Add to ACC with no sign extension
-ADDS     *-,_arp_
-ADDS     *, _arp_
-ADDS     *+
-ADDS     *-
-ADDS     *
-ADDS     _dma_
-
-AND      *+,_arp_           AND with ACC
-AND      *-,_arp_
-AND      *, _arp_
-AND      *+
-AND      *-
-AND      *
-AND      _dma_
-
-APAC                        Add P register to ACC
-
-B        _pma_              Branch unconditionally
-BANZ     _pma_              Branch on auxiliary register not zero
-BGEZ     _pma_              Branch if ACC >= 0
-BGZ      _pma_              Branch if ACC >  0
-BIOZ     _pma_              Branch on BIO- = 0
-BLEZ     _pma_              Branch if ACC <= 0
-BLZ      _pma_              Branch if ACC <  0
-BNZ      _pma_              Branch if ACC 
-
 0
-BV       _pma_              Branch on overflow
-BZ       _pma_              Branch if ACC =  0
-
-CALA                        Call subroutine from ACC
-CALL     _pma_              Call subroutine at _pma_
-
-DINT                        Disable interrupt
-
-DMOV     *+,_arp_           Data move in memory
-DMOV     *-,_arp_
-DMOV     *, _arp_
-DMOV     *+
-DMOV     *-
-DMOV     *
-DMOV     _dma_
-
-EINT                        Enable Interrupt
-
-IN       *+,_port_ ,_arp_   Input data from port
-IN       *-,_port_ ,_arp_
-IN       * ,_port_ ,_arp_
-IN       *+,_port_
-IN       *-,_port_
-IN       * ,_port_
-IN       _dma_,_port_
-
-LAC      *+,_shift_,_arp_   Load ACC with shift
-LAC      *-,_shift_,_arp_
-LAC      *, _shift_,_arp_
-LAC      *+,_shift_
-LAC      *-,_shift_
-LAC      *, _shift_
-LAC      *+
-LAC      *-
-LAC      *
-LAC      _dma_,_shift_
-LAC      _dma_
-
-LACK     _const8_                   Load ACC with 8 bit constant
-
-LAR      _ar_,*+,_arp_              Load auxiliary Register
-LAR      _ar_,*-,_arp_
-LAR      _ar_,*, _arp_
-LAR      _ar_,*+
-LAR      _ar_,*-
-LAR      _ar_,*
-LAR      _ar_,_dma_
-
-LARK     _ar_,_const8_              Load aux register with constant
-LARP     _const1_                   Load aux register pointer immed
-
-LDP      *+,_arp_                   Load data memory page pointer
-LDP      *-,_arp_
-LDP      *, _arp_
-LDP      *+
-LDP      *-
-LDP      *
-LDP      _dma_
-
-LDPK     _const1_                   Load data page pointer immediate
-
-LST      *+,_arp_                   Load status from data memory
-LST      *-,_arp_
-LST      *, _arp_
-LST      *+
-LST      *-
-LST      *
-LST      _dma_
-
-LT       *+,_arp_                   Load T register
-LT       *-,_arp_
-LT       *, _arp_
-LT       *+
-LT       *-
-LT       *
-LT       _dma_
-
-LTA      *+,_arp_                   Load T register and accumulate
-LTA      *-,_arp_                     product
-LTA      *, _arp_
-LTA      *+
-LTA      *-
-LTA      *
-LTA      _dma_
-
-LTD      *+,_arp_                   Load T reg, accumulate product,
-LTD      *-,_arp_                     and move
-LTD      *, _arp_
-LTD      *+
-LTD      *-
-LTD      *
-LTD      _dma_
-
-MAR      *+,_arp_                   Modify auxiliary register
-MAR      *-,_arp_
-MAR      *, _arp_
-MAR      *+
-MAR      *-
-MAR      *
-MAR      _dma_
-
-MPY      *+,_arp_                   Multiply
-MPY      *-,_arp_
-MPY      *, _arp_
-MPY      *+
-MPY      *-
-MPY      *
-MPY      _dma_
-
-MPYK     _const13_                  Multiply immediate
-
-NOP                                 No Operation
-
-OR       *+,_arp_                   OR  with low order bits of ACC
-OR       *-,_arp_
-OR       *, _arp_
-OR       *+
-OR       *-
-OR       *
-OR       _dma_
-
-OUT      *+,_port_,_arp_            Output data to port
-OUT      *-,_port_,_arp_
-OUT      *, _port_,_arp_
-OUT      *+,_port_
-OUT      *-,_port_
-OUT      *, _port_
-OUT      _dma_,_port_
-
-PAC                                 Load ACC with P register
-POP                                 Pop top of stack to ACC
-PUSH                                Push ACC onto stack
-RET                                 Return from subroutine
-ROVM                                Reset overflow mode register
-
-SACH     *+,_shift_,_arp_           Store ACC high with shift
-SACH     *-,_shift_,_arp_             Note: shift can only be 0, 1,
-SACH     *, _shift_,_arp_                   or 4
-SACH     *+,_shift_
-SACH     *-,_shift_
-SACH     *, _shift_
-SACH     *+
-SACH     *-
-SACH     *
-SACH     _dma_,_shift_
-SACH     _dma_
-
-SACL     *+,_arp_                   Store ACC low
-SACL     *-,_arp_
-SACL     *, _arp_
-SACL     *+
-SACL     *-
-SACL     *
-SACL     _dma_
-
-SAR      _ar_,*+,_arp_              Store auxiliary Register
-SAR      _ar_,*-,_arp_
-SAR      _ar_,*, _arp_
-SAR      _ar_,*+
-SAR      _ar_,*-
-SAR      _ar_,*
-SAR      _ar_,_dma_
-
-SOVM                                Set overflow mode register
-SPAC                                Subtract P register from ACC
-
-SST      *+,_arp_                   Store status
-SST      *-,_arp_
-SST      *, _arp_
-SST      *+
-SST      *-
-SST      *
-SST      _dma_
-
-SUB      *+,_shift_,_arp_           Subtract from ACC with shift
-SUB      *-,_shift_,_arp_
-SUB      *, _shift_,_arp_
-SUB      *+,_shift_
-SUB      *-,_shift_
-SUB      *, _shift_
-SUB      *+
-SUB      *-
-SUB      *
-SUB      _dma_,_shift_
-SUB      _dma_
-
-SUBC     *+,_arp_                   Conditional subtract
-SUBC     *-,_arp_
-SUBC     *, _arp_
-SUBC     *+
-SUBC     *-
-SUBC     *
-SUBC     _dma_
-
-SUBH     *+,_arp_                   Subtract from high-order ACC
-SUBH     *-,_arp_
-SUBH     *, _arp_
-SUBH     *+
-SUBH     *-
-SUBH     *
-SUBH     _dma_
-
-SUBS     *+,_arp_                   Subtract from low ACC with
-SUBS     *-,_arp_                     sign-extension suppressed
-SUBS     *, _arp_
-SUBS     *+
-SUBS     *-
-SUBS     *
-SUBS     _dma_
-
-TBLR     *+,_arp_                   Table Read
-TBLR     *-,_arp_
-TBLR     *, _arp_
-TBLR     *+
-TBLR     *-
-TBLR     *
-TBLR     _dma_
-
-TBLW     *+,_arp_                   Table Write
-TBLW     *-,_arp_
-TBLW     *, _arp_
-TBLW     *+
-TBLW     *-
-TBLW     *
-TBLW     _dma_
-
-XOR      *+,_arp_                   Exclusive OR with low bits of ACC
-XOR      *-,_arp_
-XOR      *, _arp_
-XOR      *+
-XOR      *-
-XOR      *
-XOR      _dma_
-
-ZAC                                 Zero the ACC
-
-ZALH     *+,_arp_                   Zero ACC and load high
-ZALH     *-,_arp_
-ZALH     *, _arp_
-ZALH     *+
-ZALH     *-
-ZALH     *
-ZALH     _dma_
-
-ZALS     *+,_arp_                   Zero ACC and load low with
-ZALS     *-,_arp_                     sign extension suppressed
-ZALS     *, _arp_
-ZALS     *+
-ZALS     *-
-ZALS     *
-ZALS     _dma_
-
-

See manufacturer's data for more information. -

-
-

TMS32025 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the TMS32025 version of TASM. The following -symbols are used in the table: -

-
SYMBOLIC            DESCRIPTION
------------------------------------------------
-_ar_                Auxiliary register (AR0, AR1, ...)
-_arp_               Auxiliary register pointer
-_nextarp_           Auxiliary register pointer (for next operation)
-_dma_               Direct memory address
-_pma_               Program memory address
-_port_              Port address (0 - 7)
-_shift_             Shift count  (0 - 15)
-_const1_            Constant (1 bit)
-_const2_            Constant (2 bit)
-_const8_            Constant (8 bit)
-_const13_           Constant (13 bit)
-_ind_               Indirect addressing mode indicator
-                      (see following table)
-
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics except for _ind_. The _ind_ symbolic must be one of the following: -

-
        
-_ind_
--------
-*BR0+
-*BR0-
-*0+
-*0-
-*+
-*-
-*
-
-OPCODE   OPERAND                DESCRIPTION
---------------------------------------------------------------------
-ABS                             Absolute value of ACC
-
-ADD  _ind_,_shift_,_nextarp_    Add to ACC with shift
-ADD  _ind_,_shift_
-ADD  _ind_
-ADD  _dma_,_shift_
-ADD  _dma_
-
-ADDC _ind_,_nextarp_            Add to ACC with carry
-ADDC _ind_
-ADDC _dma_
-
-ADDH _ind_,_nextarp_            Add to high ACC
-ADDH _ind_
-ADDH _dma_
-
-ADDK _const8_                   Add to ACC short immediate
-ADDS _ind_,_nextarp_            Add to ACC with sign-extension suppressed
-ADDS _ind_
-ADDS _dma_
-
-ADDT _ind_,_nextarp_            Add to ACC with shift specified by T reg
-ADDT _ind_
-ADDT _dma_
-
-ADLK _const8_,_shift_           Add to ACC long immediate with shift
-ADLK _const8_
-
-ADRK _const8_                   Add to aux register short immediate
-
-AND  _ind_,_nextarp_            And with ACC
-AND  _ind_
-AND  _dma_
-
-ANDK _const8_,_shift_           And immediate with ACC with shift
-ANDK _const8_
-
-APAC                            Add P register to ACC
-
-B    _pma_,_ind_,_nextarp_      Branch unconditionally
-B    _pma_,_ind_
-B    _pma_
-
-BACC                            Branch to address specified by ACC
-
-BANZ _pma_,_ind_,_nextarp_      Branch on Aux register not zero
-BANZ _pma_,_ind_
-BANZ _pma_
-
-BBNZ _pma_,_ind_,_nextarp_      Branch on TC bit not zero
-BBNZ _pma_,_ind_
-BBNZ _pma_
-
-BBZ  _pma_,_ind_,_nextarp_      Branch on TC bit equal to zero
-BBZ  _pma_,_ind_
-BBZ  _pma_
-
-BC   _pma_,_ind_,_nextarp_      Branch on carry
-BC   _pma_,_ind_
-BC   _pma_
-
-BGEZ _pma_,_ind_,_nextarp_      Branch if ACC >= zero
-BGEZ _pma_,_ind_
-BGEZ _pma_
-
-BGZ  _pma_,_ind_,_nextarp_      Branch if ACC > zero
-BGZ  _pma_,_ind_
-BGZ  _pma_
-
-BIOZ _pma_,_ind_,_nextarp_      Branch on I/O status = zero
-BIOZ _pma_,_ind_
-BIOZ _pma_
-
-BIT  _ind_,_bitcode_,_nextarp_  Test bit
-BIT  _ind_,_bitcode_
-BIT  _dma_,_bitcode_
-
-BITT _ind_,_nextarp_            Test bit specified by T register
-BITT _ind_
-BITT _dma_
-
-BLEZ _pma_,_ind_,_nextarp_      Branch if ACC <= zero
-BLEZ _pma_,_ind_
-BLEZ _pma_
-
-BLKD _dma_,_ind_,_nextarp_      Block move from data mem to data mem
-BLKD _dma_,_ind_
-BLKD _dma_,_dma_
-
-BLKP _pma_,_ind_,_nextarp_      Block move from prog mem to data mem
-BLKP _pma_,_ind_
-BLKP _pma_,_dma_
-
-BLZ  _pma_,_ind_,_nextarp_      Branch if ACC < zero
-BLZ  _pma_,_ind_
-BLZ  _pma_
-
-BNC  _pma_,_ind_,_nextarp_      Branch on no carry
-BNC  _pma_,_ind_
-BNC  _pma_
-
-BNV  _pma_,_ind_,_nextarp_      Branch if no overflow
-BNV  _pma_,_ind_
-BNV  _pma_
-
-BNZ  _pma_,_ind_,_nextarp_      Branch if ACC 
-
 zero
-BNZ  _pma_,_ind_
-BNZ  _pma_
-
-BV   _pma_,_ind_,_nextarp_      Branch on overflow
-BV   _pma_,_ind_
-BV   _pma_
-
-BZ   _pma_,_ind_,_nextarp_      Branch if ACC = zero
-BZ   _pma_,_ind_
-BZ   _pma_
-
-CALA                            Call subroutine indirect
-
-CALL _pma_,_ind_,_nextarp_      Call subroutine
-CALL _pma_,_ind_
-CALL _pma_
-
-CMPL                            Complement ACC
-CMPR _const2_                   Compare Aux reg with Aux AR0
-CNFD                            Configure block as data memory
-CNFP                            Configure block as program memory
-CONF _const2_                   Configure block as data/prog memory
-DINT                            Disable interrupt
-
-DMOV _ind_,_nextarp_            Data move in data memory
-DMOV _ind_
-DMOV _dma_
-
-EINT                            Enable interrupt
-
-FORT _const1_                   Format serial port registers
-
-IDLE                            Idle until interrupt
-
-IN   _ind_,_port_,_nextarp_     Input data from port
-IN   _ind_,_port_
-IN   _dma_,_port_
-
-LAC  _ind_,_shift_,_nextarp_    Load ACC with shift
-LAC  _ind_,_shift_
-LAC  _ind_
-LAC  _dma_,_shift_
-LAC  _dma_
-
-LACK _const8_                   Load ACC immediate short
-
-LACT _ind_,_nextarp_            Load ACC with shift specified by T reg
-LACT _ind_
-LACT _dma_
-
-LALK _const16_,_shift_          Load ACC long immediate with shift
-LALK _const16_
-
-LAR  _ar_,_ind_,_nextarp_       Load auxilary register
-LAR  _ar_,_ind_
-LAR  _ar_,_dma_
-
-LARK _ar_,_const8_              Load auxilary register immediate short
-
-LARP _arp_                      Load auxilary register pointer
-
-LDP  _ind_,_nextarp_            Load data memory page pointer
-LDP  _ind_
-LDP  _dma_
-
-LDPK _const8_                   Load data memory page pointer immediate
-
-LPH  _ind_,_nextarp_            Load high P register
-LPH  _ind_
-LPH  _dma_
-
-LRLK _ar_,_const16_             Load auxilary register long immediate
-
-LST  _ind_,_nextarp_            Load status register ST0
-LST  _ind_
-LST  _dma_
-
-LST1 _ind_,_nextarp_            Load status register ST1
-LST1 _ind_
-LST1 _dma_
-
-LT   _ind_,_nextarp_            Load T register
-LT   _ind_
-LT   _dma_
-
-LTA  _ind_,_nextarp_            Load T reg and accumulate prev product
-LTA  _ind_
-LTA  _dma_
-
-LTD  _ind_,_nextarp_            Load T reg, accum prev product & move
-LTD  _ind_
-LTD  _dma_
-
-LTP  _ind_,_nextarp_            Load T reg and store P in ACC
-LTP  _ind_
-LTP  _dma_
-
-LTS  _ind_,_nextarp_            Load T reg, subract previous product
-LTS  _ind_
-LTS  _dma_
-
-MAC  _pma_,_ind_,_nextarp_      Multiply and accumulate
-MAC  _pma_,_ind_
-MAC  _pma_,_dma_
-
-MACD _pma_,_ind_,_nextarp_      Multiply and accumulate with data move
-MACD _pma_,_ind_
-MACD _pma_,_dma_
-
-MAR  _ind_,_nextarp_            Modify auxiliary register
-MAR  _ind_
-MAR  _dma_
-
-MPY  _ind_,_nextarp_            Multiply
-MPY  _ind_
-MPY  _dma_
-
-MPYA _ind_,_nextarp_            Multiply and accum previous product
-MPYA _ind_
-MPYA _dma_
-
-MPYK _const13_                  Multiply immediate
-
-MPYS _ind_,_nextarp_            Multiply and subtract previous product
-MPYS _ind_
-MPYS _dma_
-
-MPYU _ind_,_nextarp_            Multiply unsigned
-MPYU _ind_
-MPYU _dma_
-
-NEG                             Negate ACC
-
-NOP                             No operation
-
-NORM _ind_                      Normalize contents of ACC
-NORM
-
-OR   _ind_,_nextarp_            Or with ACC
-OR   _ind_
-OR   _dma_
-
-ORK  _dma_,_shift_              Or immediate with ACC with shift
-ORK  _dma_
-
-OUT  _ind_,_shift_,_nextarp_    Output data to port
-OUT  _ind_,_shift_
-OUT  _dma_,_shift_
-
-PAC                             Load ACC with P register
-
-POP                             Pop top of stack to low ACC
-
-POPD _ind_,_nextarp_            Pop top of stack to data memory
-POPD _ind_
-POPD _dma_
-
-PSHD _ind_,_nextarp_            Push data memory value onto stack
-PSHD _ind_
-PSHD _dma_
-
-PUSH                            Push low ACC onto stack
-RC                              Reset carry bit
-RET                             Return from subroutine
-RFSM                            Reset serial port frame syn mode
-RHM                             Reset hold mode
-ROL                             Rotate ACC left
-ROR                             Rotate ACC right
-ROVM                            Reset overflow mode
-
-RPT  _ind_,_nextarp_            Repeat instructions as per data mem
-RPT  _ind_
-RPT  _dma_
-
-RPTK _const8_                   Repeat instructions as per immediate
-
-RSXM                            Reset sign extension mode
-RTC                             Reset test control flag
-RTXM                            Reset serial port transmit mode
-RXF                             Reset external flag
-
-SACH _ind_,_shift_,_nextarp_    Store high ACC with shift
-SACH _ind_,_shift_
-SACH _ind_
-SACH _dma_,_shift_
-SACH _dma_
-
-SACL _ind_,_shift_,_nextarp_    Store low ACC with shift
-SACL _ind_,_shift_
-SACL _ind_
-SACL _dma_,_shift_
-SACL _dma_
-
-SAR  _ar_,_ind_,_nextarp_       Store AUX register
-SAR  _ar_,_ind_
-SAR  _ar_,_dma_
-
-SBLK _const16_,_shift_          Subtract from ACC long immediate with shift
-SBLK _const16_
-
-SBRK _const8_                   Subtract from AUX register short immediate
-
-SC                              Set carry bit
-SFL                             Shift ACC left
-SFR                             Shift ACC right
-SFSM                            Set serial port frame sync mode
-SHM                             Set hold mode
-SOVM                            Set overflow mode
-SPAC                            Subtract P register from ACC
-
-SPH  _ind_,_nextarp_            Store high P register
-SPH  _ind_
-SPH  _dma_
-
-SPL  _ind_,_nextarp_            Store low P register
-SPL  _ind_
-SPL  _dma_
-
-SPM  _dma_                      Set P register output shift mode
-
-SQRA _ind_,_nextarp_            Square and accumulate previous product
-SQRA _ind_
-SQRA _dma_
-
-SQRS _ind_,_nextarp_            Square and subtract previous product
-SQRS _ind_
-SQRS _dma_
-
-SST  _ind_,_nextarp_            Store status register ST0
-SST  _ind_
-SST  _dma_
-
-SST1 _ind_,_nextarp_            Store status register ST1
-SST1 _ind_
-SST1 _dma_
-
-SSXM                            Set sign extension mode
-STC                             Set test/control flag
-STXM                            Set serial port transmit mode
-
-
-SUB  _ind_,_shift_,_nextarp_    Subtract from ACC with shift
-SUB  _ind_,_shift_
-SUB  _ind_
-SUB  _dma_,_shift_
-SUB  _dma_
-
-SUBB _ind_,_nextarp_            Subtract from ACC with borrow
-SUBB _ind_
-SUBB _dma_
-SUBC _ind_,_nextarp_            Subtract conditional
-SUBC _ind_
-SUBC _dma_
-
-SUBH _ind_,_nextarp_            Subtract from high ACC
-SUBH _ind_
-SUBH _dma_
-
-SUBK _const8_                   Subtract from ACC short immediate
-
-SUBS _ind_,_nextarp_            Subtract from low ACC without sign-extension
-SUBS _ind_
-SUBS _dma_
-
-SUBT _ind_,_nextarp_            Subtract from ACC with shift as per T reg
-SUBT _ind_
-SUBT _dma_
-
-SXF                             Set external flag
-
-TBLR _ind_,_nextarp_            Table read
-TBLR _ind_
-TBLR _dma_
-
-TBLW _ind_,_nextarp_            Table write
-TBLW _ind_
-TBLW _dma_
-
-TRAP                            Software interrupt
-
-XOR  _ind_,_nextarp_            Exclusive OR with ACC
-XOR  _ind_
-XOR  _dma_
-
-XORK_dma_,_shift_               Exclusive OR immediate ACC with shift
-XORK _dma_
-
-ZAC                             Zero ACC
-
-ZALH _ind_,_nextarp_            Zero low ACC and load high ACC
-ZALH _ind_
-ZALH _dma_
-
-ZALR _ind_,_nextarp_            Zero low ACC, load high ACC with rounding
-ZALR _ind_
-ZALR _dma_
-
-ZALS _ind_,_nextarp_            Zero ACC, load low ACC without sign-extension
-ZALS _ind_
-ZALS _dma_
-
-
-
-

TMS7000 INSTRUCTIONS AND ADDRESSING MODES

-

The following list shows the acceptable opcode mnemonics and their -corresponding operand formats for the TMS7000 version of TASM. The following -symbolic fields used in the table: -

-
SYMBOLIC        DESCRIPTION
--------------------------------------------
-_iop_           Immediate data (8 bits)
-_Rn_            Register file (memory locations 0 to 127 or
-                   0 to 255 depending on on-chip RAM)
-_Pn_            Peripheral file (0-255)
-_rel_           Program address (relative)
-_addr_          Program address (16 bit)
-_trap_          Trap number (0-23)
-
-

Any valid TASM expression can appear in the place of any of the above -symbolics. -

-

Note that TASM allows an alternate syntax for expressing indirection. -Parenthesis can be replaced with brackets (which are less ambiguous because they -do not occur in expressions). Thus, the following are equivalent: -

-
    BR      @addr1(B)
-    BR      @addr1[B]
-
-
OPCODE  OPERANDS
----------------------------------------
-ADC    B,A
-ADC    %_iop_,A
-ADC    %_iop_,B
-ADC    %_iop_,_Rn_
-ADC    _Rn_,A
-ADC    _Rn_,B
-ADC    _Rn_,_Rn_
-
-ADD    B,A
-ADD    %_iop_,A
-ADD    %_iop_,B
-ADD    %_iop_,_Rn_
-ADD    _Rn_,A
-ADD    _Rn_,B
-ADD    _Rn_,_Rn_
-
-AND    B,A
-AND    %_iop_,A
-AND    %_iop_,B
-AND    %_iop_,_Rn_
-AND    _Rn_,A
-AND    _Rn_,B
-AND    _Rn_,_Rn_
-
-ANDP   A,_Pn_
-ANDP   B,_Pn_
-ANDP   %_iop_,_Pn_
-
-BTJO   B,A,_rel_
-BTJO   %_iop_,A,_rel_
-BTJO   %_iop_,B,_rel_
-BTJO   %_iop_,_Rn_,_rel_
-BTJO   _Rn_,A,_rel_
-BTJO   _Rn_,B,_rel_
-BTJO   _Rn_,_Rn_,_rel_
-
-BTJOP  A,_Pn_,_rel_
-BTJOP  B,_Pn_,_rel_
-BTJOP  %_iop_,_Pn_,_rel_
-
-BTJZ   B,A,_rel_
-BTJZ   %_iop_,A,_rel_
-BTJZ   %_iop_,B,_rel_
-BTJZ   %_iop_,_Rn_,_rel_
-BTJZ   _Rn_,A,_rel_
-BTJZ   _Rn_,B,_rel_
-BTJZ   _Rn_,_Rn_,_rel_
-
-BTJZP  A,_Pn_,_rel_
-BTJZP  B,_Pn_,_rel_
-BTJZP  %_iop_,_Pn_,_rel_
-
-BR      @_addr_(B)
-BR      @_addr_[B]
-BR      @_addr_
-BR      *_Rn_
-
-CALL    @_addr_(B)
-CALL    @_addr_[B]
-CALL    @_addr_
-CALL    *_Rn_
-
-CLR     A
-CLR     B
-CLR     _Rn_
-CLRC
-
-CMP     B,A
-CMP     %_iop_,A
-CMP     %_iop_,B
-CMP     %_iop_,_Rn_
-CMP     _Rn_,A
-CMP     _Rn_,B
-CMP     _Rn_,_Rn_
-
-CMPA    @_addr_(B)
-CMPA    @_addr_[B]
-CMPA    @_addr_
-CMPA    *_Rn_
-
-DAC     B,A
-DAC     %_iop_,A
-DAC     %_iop_,B
-DAC     %_iop_,_Rn_
-DAC     _Rn_,A
-DAC     _Rn_,B
-DAC     _Rn_,_Rn_
-
-DEC     A
-DEC     B
-DEC     _Rn_
-
-DECD    A
-DECD    B
-DECD    _Rn_
-
-DINT
-
-DJNZ    A,_rel_
-DJNZ    B,_rel_
-DJNZ    _Rn_,_rel_
-
-DSB     B,A
-DSB     %_iop_,A
-DSB     %_iop_,B
-DSB     %_iop_,_Rn_
-DSB     _Rn_,A
-DSB     _Rn_,B
-DSB     _Rn_,_Rn_
-
-EINT
-IDLE
-
-INC     A
-INC     B
-INC     _Rn_
-
-INV     A
-INV     B
-INV     _Rn_
-
-JMP     _rel_
-
-JC      _rel_
-JEQ     _rel_
-JGE     _rel_
-JGT     _rel_
-JHS     _rel_
-JL      _rel_
-JN      _rel_
-JNC     _rel_
-JNE     _rel_
-JNZ     _rel_
-JP      _rel_
-JPZ     _rel_
-JZ      _rel_
-
-LDA     @_addr_(B)
-LDA     @_addr_[B]
-LDA     @_addr_
-LDA     *_Rn_
-
-LDSP
-
-MOV     A,B
-MOV     B,A
-MOV     A,_Rn_
-MOV     B,_Rn_
-MOV     %_iop_,A
-MOV     %_iop_,B
-MOV     %_iop_,_Rn_
-MOV     _Rn_,A
-MOV     _Rn_,B
-MOV     _Rn_,_Rn_
-
-MOVD    %_iop_[B],_Rn_
-MOVD    %_iop_,_Rn_
-MOVD    _Rn_,_Rn_
-
-MOVP    A,_Pn_
-MOVP    B,_Pn_
-MOVP    %_iop_,_Pn_
-MOVP    _Pn_,A
-MOVP    _Pn_,B
-
-MPY     B,A
-MPY     %_iop_,A
-MPY     %_iop_,B
-MPY     %_iop_,_Rn_
-MPY     _Rn_,A
-MPY     _Rn_,B
-MPY     _Rn_,_Rn_
-
-NOP
-
-OR      B,A
-OR      %_iop_,A
-OR      %_iop_,B
-OR      %_iop_,_Rn_
-OR      _Rn_,A
-OR      _Rn_,B
-OR      _Rn_,_Rn_
-
-ORP     A,_Pn_
-ORP     B,_Pn_
-ORP     %_iop_,_Pn_
-
-POP     A
-POP     B
-POP     ST
-POP     _Rn_
-POPST
-
-PUSH    A
-PUSH    B
-PUSH    ST
-PUSH    _Rn_
-PUSHST
-
-RETI
-
-RETS
-
-RL      A
-RL      B
-RL      _Rn_
-
-RLC     A
-RLC     B
-RLC     _Rn_
-
-RR      A
-RR      B
-RR      _Rn_
-
-RRC     A
-RRC     B
-RRC     _Rn_
-
-SBB     B,A
-SBB     %_iop_,A
-SBB     %_iop_,B
-SBB     %_iop_,_Rn_
-SBB     _Rn_,A
-SBB     _Rn_,B
-SBB     _Rn_,_Rn_
-
-SETC
-
-STA     @_addr_(B)
-STA     @_addr_[B]
-STA     @_addr_
-STA     *_Rn_
-
-STSP
-
-SUB     B,A
-SUB     %_iop_,A
-SUB     %_iop_,B
-SUB     %_iop_,_Rn_
-SUB     _Rn_,A
-SUB     _Rn_,B
-SUB     _Rn_,_Rn_
-
-SWAP    A
-SWAP    B
-SWAP    _Rn_
-
-TRAP    _trap_
-
-TST     A
-TSTA
-TST     B
-TSTB
-
-XCHB    A
-XCHB    _Rn_
-
-XOR     B,A
-XOR     %_iop_,A
-XOR     %_iop_,B
-XOR     %_iop_,_Rn_
-XOR     _Rn_,A
-XOR     _Rn_,B
-XOR     _Rn_,_Rn_
-
-XORP    A,_Pn_
-XORP    B,_Pn_
-XORP    %_iop_,_Pn_
-
-
diff --git a/branches/s100/XSource/bin/TEST05.ASM b/branches/s100/XSource/bin/TEST05.ASM deleted file mode 100644 index a8f7b88f..00000000 --- a/branches/s100/XSource/bin/TEST05.ASM +++ /dev/null @@ -1,251 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test05.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 6805 -; - - - .org 0 -bit3 .equ 3 -data .equ $12 - .block $46 -addz .equ $46 - - .org $1007 -addr: - ADC #data ;A9 2 NOP 1 - ADC ,X ;F9 1 NOP 1 - ADC addr,X ;D9 3 MZERO 1 - ADC addz,X ;D9 3 MZERO 1 - ADC addr ;C9 3 MZERO 1 - ADC addz ;C9 3 MZERO 1 - - ADD #data ;AB 2 NOP 1 - ADD ,X ;FB 1 NOP 1 - ADD addr,X ;DB 3 MZERO 1 - ADD addz,X ;DB 3 MZERO 1 - ADD addr ;CB 3 MZERO 1 - ADD addz ;CB 3 MZERO 1 - - AND #data ;A4 2 NOP 1 - AND ,X ;F4 1 NOP 1 - AND addr,X ;D4 3 MZERO 1 - AND addz,X ;D4 3 MZERO 1 - AND addr ;C4 3 MZERO 1 - AND addz ;C4 3 MZERO 1 - - ASLA ;48 1 NOP 1 - ASLX ;58 1 NOP 1 - ASL ,X ;78 1 NOP 1 - ASL addz,X ;68 2 NOP 1 - ASL addz ;38 2 NOP 1 - - ASRA ;47 1 NOP 1 - ASRX ;57 1 NOP 1 - ASR ,X ;77 1 NOP 1 - ASR addz,X ;37 2 NOP 1 - ASR addz ;37 2 NOP 1 - -loop1: - BCC loop1 ;24 2 R1 1 - BCS loop1 ;25 2 R1 1 - BEQ loop1 ;27 2 R1 1 - BHCC loop1 ;28 2 R1 1 - BHCS loop1 ;29 2 R1 1 - BHI loop1 ;22 2 R1 1 - BHS loop1 ;24 2 R1 1 - BIH loop1 ;2F 2 R1 1 - BIL loop1 ;2E 2 R1 1 - - BIT #data ;A5 2 NOP 1 - BIT ,X ;F5 1 NOP 1 - BIT addr,X ;D5 3 MZERO 1 - BIT addz,X ;C5 3 MZERO 1 - BIT addr ;C5 3 MZERO 1 - BIT addz ;C5 3 MZERO 1 - - BLO loop1 ;25 2 R1 1 - BLS loop1 ;23 2 R1 1 - BMC loop1 ;2C 2 R1 1 - BMI loop1 ;2B 2 R1 1 - BMS loop1 ;2D 2 R1 1 - BNE loop1 ;26 2 R1 1 - BPL loop1 ;2A 2 R1 1 - BRA loop1 ;20 2 R1 1 - BRN loop1 ;21 2 R1 1 - BSR loop1 ;AD 2 R1 1 - - BRCLR bit3,addz,loop1 ;01 3 MBIT 1 - BRSET bit3,addz,loop1 ;00 3 MBIT 1 - - BCLR bit3,addz ;11 2 MBIT 1 - BSET bit3,addz ;10 2 MBIT 1 - - CLC ;98 1 NOP 1 - CLI ;9A 1 NOP 1 - - CLRA ;4F 1 NOP 1 - CLRX ;5F 1 NOP 1 - CLR ,X ;7F 1 NOP 1 - CLR addz,X ;6F 2 NOP 1 - CLR addz ;3F 2 NOP 1 - - CMP #data ;A1 2 NOP 1 - CMP ,X ;F1 1 NOP 1 - CMP addr,X ;D1 3 MZERO 1 - CMP addz,X ;D1 3 MZERO 1 - CMP addr ;C1 3 MZERO 1 - CMP addz ;C1 3 MZERO 1 - - COMA ;43 1 NOP 1 - COMX ;53 1 NOP 1 - COM ,X ;73 1 NOP 1 - COM addz,X ;63 2 NOP 1 - COM addz ;33 2 NOP 1 - - CPX #data ;A3 2 NOP 1 - CPX ,X ;F3 1 NOP 1 - CPX addr,X ;D3 3 MZERO 1 - CPX addz,X ;D3 3 MZERO 1 - CPX addr ;C3 3 MZERO 1 - CPX addz ;C3 3 MZERO 1 - - DECA ;4A 1 NOP 1 - DECX ;5A 1 NOP 1 - DEX ;5A 1 NOP 1 - DEC ,X ;7A 1 NOP 1 - DEC addz,X ;6A 2 NOP 1 - DEC addz ;3A 2 NOP 1 - - EOR #data ;A8 2 NOP 1 - EOR ,X ;F8 1 NOP 1 - EOR addr,X ;D8 3 MZERO 1 - EOR addz,X ;D8 3 MZERO 1 - EOR addr ;C8 3 MZERO 1 - EOR addz ;C8 3 MZERO 1 - - INCA ;4C 1 NOP 1 - INCX ;5C 1 NOP 1 - INX ;5C 1 NOP 1 - INC ,X ;7C 1 NOP 1 - INC addz,X ;6C 2 NOP 1 - INC addz ;3C 2 NOP 1 - - JMP ,X ;FC 1 NOP 1 - JMP addr,X ;DC 3 MZERO 1 - JMP addz,X ;DC 3 MZERO 1 - JMP addr ;CC 3 MZERO 1 - JMP addz ;CC 3 MZERO 1 - - JSR ,X ;FD 1 NOP 1 - JSR addr,X ;DD 3 MZERO 1 - JSR addz,X ;DD 3 MZERO 1 - JSR addr ;CD 3 MZERO 1 - JSR addz ;CD 3 MZERO 1 - - LDA #data ;A6 2 NOP 1 - LDA ,X ;F6 1 NOP 1 - LDA addr,X ;D6 3 MZERO 1 - LDA addz,X ;D6 3 MZERO 1 - LDA addr ;C6 3 MZERO 1 - LDA addz ;C6 3 MZERO 1 - - LDX #data ;AE 2 NOP 1 - LDX ,X ;FE 1 NOP 1 - LDX addr,X ;DE 3 MZERO 1 - LDX addz,X ;DE 3 MZERO 1 - LDX addr ;CE 3 MZERO 1 - LDX addz ;CE 3 MZERO 1 - - LSLA ;48 1 NOP 1 - LSLX ;58 1 NOP 1 - LSL ,X ;78 1 NOP 1 - LSL addz,X ;68 2 NOP 1 - LSL addz ;38 2 NOP 1 - - LSRA ;44 1 NOP 1 - LSRX ;54 1 NOP 1 - LSR ,X ;74 1 NOP 1 - LSR addz,X ;64 2 NOP 1 - LSR addz ;34 2 NOP 1 - - NEGA ;40 1 NOP 1 - NEGX ;50 1 NOP 1 - NEG ,X ;70 1 NOP 1 - NEG addz,X ;60 2 NOP 1 - NEG addz ;30 2 NOP 1 - - NOP ;9D 1 NOP 1 - - ORA #data ;AA 2 NOP 1 - ORA ,X ;FA 1 NOP 1 - ORA addr,X ;DA 3 MZERO 1 - ORA addz,X ;DA 3 MZERO 1 - ORA addr ;CA 3 MZERO 1 - ORA addz ;CA 3 MZERO 1 - - ROLA ;49 1 NOP 1 - ROLX ;59 1 NOP 1 - ROL ,X ;79 1 NOP 1 - ROL addz,X ;69 2 NOP 1 - ROL addz ;39 2 NOP 1 - - RORA ;46 1 NOP 1 - RORX ;56 1 NOP 1 - ROR ,X ;76 1 NOP 1 - ROR addz,X ;66 2 NOP 1 - ROR addz ;36 2 NOP 1 - - RSP ;9C 1 NOP 1 - RTI ;80 1 NOP 1 - RTS ;81 1 NOP 1 - - SBC #data ;A2 2 NOP 1 - SBC ,X ;F2 1 NOP 1 - SBC addr,X ;D2 3 MZERO 1 - SBC addz,X ;D2 3 MZERO 1 - SBC addr ;C2 3 MZERO 1 - SBC addz ;C2 3 MZERO 1 - - SEC ;99 1 NOP 1 - SEI ;9B 1 NOP 1 - - STA ,X ;F7 1 NOP 1 - STA addr,X ;D7 3 MZERO 1 - STA addz,X ;D7 3 MZERO 1 - STA addr ;C7 3 MZERO 1 - STA addz ;C7 3 MZERO 1 - - STOP ;8E 1 NOP 1 - - STX ,X ;FF 1 NOP 1 - STX addr,X ;DF 3 MZERO 1 - STX addz,X ;DF 3 MZERO 1 - STX addr ;CF 3 MZERO 1 - STX addz ;CF 3 MZERO 1 - - SUB #data ;A0 2 NOP 1 - SUB ,X ;F0 1 NOP 1 - SUB addr,X ;D0 3 MZERO 1 - SUB addz,X ;D0 3 MZERO 1 - SUB addr ;C0 3 MZERO 1 - SUB addz ;C0 3 MZERO 1 - - SWI ;83 1 NOP 1 - - TAX ;97 1 NOP 1 - - TSTA ;4D 1 NOP 1 - TSTX ;5D 1 NOP 1 - TST ,X ;7D 1 NOP 1 - TST addz,X ;6D 2 NOP 1 - TST addz ;3D 2 NOP 1 - - TXA ;9F 1 NOP 1 - - WAIT ;8F 1 NOP 1 - .end diff --git a/branches/s100/XSource/bin/TEST3210.ASM b/branches/s100/XSource/bin/TEST3210.ASM deleted file mode 100644 index 009bfe5d..00000000 --- a/branches/s100/XSource/bin/TEST3210.ASM +++ /dev/null @@ -1,328 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test3210.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: TMS32010 -; - - - .org 100h -shift .equ 4 -shift0 .equ 0 -addr .equ 12h -port .equ 2 -arp .equ 1 -ar .equ 1 -const .equ 34h -const1 .equ 1h - - ABS ;7F88 2 NOP 1 - - ADD *+,shift,arp ;00A0 2 T1 1 8 0F00 - ADD *-,shift,arp ;0090 2 T1 1 8 0F00 - ADD *,shift,arp ;0080 2 T1 1 8 0F00 - ADD *+,shift ;00A8 2 T1 1 8 0F00 - ADD *-,shift ;0098 2 T1 1 8 0F00 - ADD *,shift ;0088 2 T1 1 8 0F00 - ADD *+ ;00A8 2 NOP 1 - ADD *- ;0098 2 NOP 1 - ADD * ;0088 2 NOP 1 - ADD addr,shift ;0000 2 TDMA 1 8 0F00 - ADD addr ;0000 2 T1 1 0 007F - - ADDH *+,arp ;60A0 2 T1 1 0 01 - ADDH *-,arp ;6090 2 T1 1 0 01 - ADDH *,arp ;6080 2 T1 1 0 01 - ADDH *+ ;60A8 2 NOP 1 - ADDH *- ;6098 2 NOP 1 - ADDH * ;6088 2 NOP 1 - ADDH addr ;6000 2 T1 1 0 007F - - ADDS *+,arp ;61A0 2 T1 1 0 01 - ADDS *-,arp ;6190 2 T1 1 0 01 - ADDS *,arp ;6180 2 T1 1 0 01 - ADDS *+ ;61A8 2 NOP 1 - ADDS *- ;6198 2 NOP 1 - ADDS * ;6188 2 NOP 1 - ADDS addr ;6100 2 T1 1 0 007F - - AND *+,arp ;79A0 2 T1 1 0 01 - AND *-,arp ;7990 2 T1 1 0 01 - AND *,arp ;7980 2 T1 1 0 01 - AND *+ ;79A8 2 NOP 1 - AND *- ;7998 2 NOP 1 - AND * ;7988 2 NOP 1 - AND addr ;7900 2 T1 1 0 7F - - APAC ;7F8F 2 NOP 1 - -loop1: - B loop1 ;F900 4 SWAP 1 - BANZ loop1 ;F400 4 SWAP 1 - BGEZ loop1 ;FD00 4 SWAP 1 - BGZ loop1 ;FC00 4 SWAP 1 - BIOZ loop1 ;F600 4 SWAP 1 - BLEZ loop1 ;FB00 4 SWAP 1 - BLZ loop1 ;FA00 4 SWAP 1 - BNZ loop1 ;FE00 4 SWAP 1 - BV loop1 ;F500 4 SWAP 1 - BZ loop1 ;FF00 4 SWAP 1 - - CALA ;7F8C 2 NOP 1 - CALL loop1 ;F800 4 SWAP 1 - DINT ;7F81 2 NOP 1 - - DMOV *+,arp ;69A0 2 T1 1 0 01 - DMOV *-,arp ;6990 2 T1 1 0 01 - DMOV *,arp ;6980 2 T1 1 0 01 - DMOV *+ ;69A8 2 NOP 1 - DMOV *- ;6998 2 NOP 1 - DMOV * ;6988 2 NOP 1 - DMOV addr ;6900 2 T1 1 0 007F - - EINT ;7F82 2 NOP 1 - - IN *+,port ,arp ;40A0 2 T1 1 8 0700 - IN *-,port ,arp ;4090 2 T1 1 8 0700 - IN * ,port ,arp ;4080 2 T1 1 8 0700 - IN *+,port ;40A8 2 T1 1 8 0700 - IN *-,port ;4098 2 T1 1 8 0700 - IN * ,port ;4088 2 T1 1 8 0700 - IN addr,port ;4000 2 TDMA 1 8 0700 - - LAC *+,shift,arp ;20A0 2 T1 1 8 0F00 - LAC *-,shift,arp ;2090 2 T1 1 8 0F00 - LAC *,shift,arp ;2080 2 T1 1 8 0F00 - LAC *+,shift ;20A8 2 T1 1 8 0F00 - LAC *-,shift ;2098 2 T1 1 8 0F00 - LAC *,shift ;2088 2 T1 1 8 0F00 - LAC *+ ;20A8 2 NOP 1 - LAC *- ;2098 2 NOP 1 - LAC * ;2088 2 NOP 1 - LAC addr,shift ;2000 2 TDMA 1 8 0F00 - LAC addr ;2000 2 T1 1 0 007F - - LACK const ;7E00 2 T1 1 0 00FF - - LAR ar,*+,arp ;38A0 2 TAR 1 0 0001 - LAR ar,*-,arp ;3890 2 TAR 1 0 0001 - LAR ar,*,arp ;3880 2 TAR 1 0 0001 - LAR ar,*+ ;38A8 2 TAR 1 0 0001 - LAR ar,*- ;3898 2 TAR 1 0 0001 - LAR ar,* ;3888 2 TAR 1 0 0001 - LAR ar, addr ;3800 2 TAR 1 0 007F - - LARK ar,const ;7000 2 TAR 1 0 00FF - LARP const1 ;6880 2 T1 1 0 0001 - - LDP *+,arp ;6FA0 2 T1 1 0 01 - LDP *-,arp ;6F90 2 T1 1 0 01 - LDP *,arp ;6F80 2 T1 1 0 01 - LDP *+ ;6FA8 2 NOP 1 - LDP *- ;6F98 2 NOP 1 - LDP * ;6F88 2 NOP 1 - LDP addr ;6F00 2 T1 1 0 007F - - LDPK const1 ;6E00 2 T1 1 0 01 - - LST *+,arp ;7BA0 2 T1 1 0 01 - LST *-,arp ;7B90 2 T1 1 0 01 - LST *,arp ;7B80 2 T1 1 0 01 - LST *+ ;7BA8 2 NOP 1 - LST *- ;7B98 2 NOP 1 - LST * ;7B88 2 NOP 1 - LST addr ;7B00 2 T1 1 0 007F - - LT *+,arp ;6AA0 2 T1 1 0 01 - LT *-,arp ;6A90 2 T1 1 0 01 - LT *,arp ;6A80 2 T1 1 0 01 - LT *+ ;6AA8 2 NOP 1 - LT *- ;6A98 2 NOP 1 - LT * ;6A88 2 NOP 1 - LT addr ;6A00 2 T1 1 0 007F - - LTA *+,arp ;6CA0 2 T1 1 0 01 - LTA *-,arp ;6C90 2 T1 1 0 01 - LTA *,arp ;6C80 2 T1 1 0 01 - LTA *+ ;6CA8 2 NOP 1 - LTA *- ;6C98 2 NOP 1 - LTA * ;6C88 2 NOP 1 - LTA addr ;6C00 2 T1 1 0 007F - - LTD *+,arp ;6BA0 2 T1 1 0 01 - LTD *-,arp ;6B90 2 T1 1 0 01 - LTD *,arp ;6B80 2 T1 1 0 01 - LTD *+ ;6BA8 2 NOP 1 - LTD *- ;6B98 2 NOP 1 - LTD * ;6B88 2 NOP 1 - LTD addr ;6B00 2 T1 1 0 007F - - MAR *+,arp ;68A0 2 T1 1 0 01 - MAR *-,arp ;6890 2 T1 1 0 01 - MAR *,arp ;6880 2 T1 1 0 01 - MAR *+ ;68A8 2 NOP 1 - MAR *- ;6898 2 NOP 1 - MAR * ;6888 2 NOP 1 - MAR addr ;6800 2 T1 1 0 007F - - MPY *+,arp ;6DA0 2 T1 1 0 01 - MPY *-,arp ;6D90 2 T1 1 0 01 - MPY *,arp ;6D80 2 T1 1 0 01 - MPY *+ ;6DA8 2 NOP 1 - MPY *- ;6D98 2 NOP 1 - MPY * ;6D88 2 NOP 1 - MPY addr ;6D00 2 T1 1 0 007F - - MPYK const ;8000 2 T1 1 0 1FFF - - NOP ;7F80 2 NOP 1 - - OR *+,arp ;7AA0 2 T1 1 0 01 - OR *-,arp ;7A90 2 T1 1 0 01 - OR *,arp ;7A80 2 T1 1 0 01 - OR *+ ;7AA8 2 NOP 1 - OR *- ;7A98 2 NOP 1 - OR * ;7A88 2 NOP 1 - OR addr ;7A00 2 T1 1 0 007F - - OUT *+,port,arp ;48A0 2 T1 1 8 0700 - OUT *-,port,arp ;4890 2 T1 1 8 0700 - OUT *, port,arp ;4880 2 T1 1 8 0700 - OUT *+,port ;48A8 2 T1 1 8 0700 - OUT *-,port ;4898 2 T1 1 8 0700 - OUT *, port ;4888 2 T1 1 8 0700 - OUT addr,port ;4800 2 TDMA 1 8 0700 - - PAC ;7F8E 2 NOP 1 - POP ;7F9D 2 NOP 1 - PUSH ;7F9C 2 NOP 1 - RET ;7F8D 2 NOP 1 - ROVM ;7F8A 2 NOP 1 - -;Note that shift count can only be 0,1, or 4. -;Mask also allows 5. Beware. - SACH *+,shift,arp ;58A0 2 T1 1 8 0500 - SACH *-,shift,arp ;5890 2 T1 1 8 0500 - SACH *, shift,arp ;5880 2 T1 1 8 0500 - SACH *+,shift ;58A8 2 T1 1 8 0500 - SACH *-,shift ;5898 2 T1 1 8 0500 - SACH *, shift ;5888 2 T1 1 8 0500 - SACH *+ ;58A8 2 NOP 1 - SACH *- ;5898 2 NOP 1 - SACH * ;5888 2 NOP 1 - SACH addr,shift ;5800 2 TDMA 1 8 0500 - SACH addr ;5800 2 T1 1 0 007F - -; Shift count must be zero for SACL - SACL *+,shift0,arp ;50A0 2 T1 1 8 0000 - SACL *-,shift0,arp ;5090 2 T1 1 8 0000 - SACL *, shift0,arp ;5080 2 T1 1 8 0000 - SACL *+,shift0 ;50A8 2 T1 1 8 0000 - SACL *-,shift0 ;5098 2 T1 1 8 0000 - SACL *, shift0 ;5088 2 T1 1 8 0000 - SACL *+ ;50A8 2 NOP 1 - SACL *- ;5098 2 NOP 1 - SACL * ;5088 2 NOP 1 - SACL addr,shift0 ;5000 2 TDMA 1 8 0000 - SACL addr ;5000 2 T1 1 0 007F - - SAR ar,*+,arp ;30A0 2 TAR 1 0 0001 - SAR ar,*-,arp ;3090 2 TAR 1 0 0001 - SAR ar,*,arp ;3080 2 TAR 1 0 0001 - SAR ar,*+ ;30A8 2 TAR 1 0 0001 - SAR ar,*- ;3098 2 TAR 1 0 0001 - SAR ar,* ;3088 2 TAR 1 0 0001 - SAR ar,addr ;3000 2 TAR 1 0 007F - - SOVM ;7F8B 2 NOP 1 - SPAC ;7F90 2 NOP 1 - - SST *+,arp ;7CA0 2 T1 1 0 0001 - SST *-,arp ;7C90 2 T1 1 0 0001 - SST *,arp ;7C80 2 T1 1 0 0001 - SST *+ ;7CA8 2 NOP 1 - SST *- ;7C98 2 NOP 1 - SST * ;7C88 2 NOP 1 - SST addr ;7C00 2 T1 1 0 007F - - SUB *+,shift,arp ;10A0 2 T1 1 8 0F00 - SUB *-,shift,arp ;1090 2 T1 1 8 0F00 - SUB *, shift,arp ;1080 2 T1 1 8 0F00 - SUB *+,shift ;10A8 2 T1 1 8 0F00 - SUB *-,shift ;1098 2 T1 1 8 0F00 - SUB *, shift ;1088 2 T1 1 8 0F00 - SUB *+ ;10A8 2 NOP 1 - SUB *- ;1098 2 NOP 1 - SUB * ;1088 2 NOP 1 - SUB addr,shift ;1000 2 TDMA 1 8 0F00 - SUB addr ;1000 2 T1 1 0 007F - - SUBC *+,arp ;64A0 2 T1 1 0 01 - SUBC *-,arp ;6490 2 T1 1 0 01 - SUBC *,arp ;6480 2 T1 1 0 01 - SUBC *+ ;64A8 2 NOP 1 - SUBC *- ;6498 2 NOP 1 - SUBC * ;6488 2 NOP 1 - SUBC addr ;6400 2 T1 1 0 007F - - SUBH *+,arp ;62A0 2 T1 1 0 01 - SUBH *-,arp ;6290 2 T1 1 0 01 - SUBH *,arp ;6280 2 T1 1 0 01 - SUBH *+ ;62A8 2 NOP 1 - SUBH *- ;6298 2 NOP 1 - SUBH * ;6288 2 NOP 1 - SUBH addr ;6200 2 T1 1 0 007F - - SUBS *+,arp ;63A0 2 T1 1 0 01 - SUBS *-,arp ;6390 2 T1 1 0 01 - SUBS *,arp ;6380 2 T1 1 0 01 - SUBS *+ ;63A8 2 NOP 1 - SUBS *- ;6398 2 NOP 1 - SUBS * ;6388 2 NOP 1 - SUBS addr ;6300 2 T1 1 0 007F - - TBLR *+,arp ;67A0 2 T1 1 0 01 - TBLR *-,arp ;6790 2 T1 1 0 01 - TBLR *,arp ;6780 2 T1 1 0 01 - TBLR *+ ;67A8 2 NOP 1 - TBLR *- ;6798 2 NOP 1 - TBLR * ;6788 2 NOP 1 - TBLR addr ;6700 2 T1 1 0 007F - - TBLW *+,arp ;7DA0 2 T1 1 0 01 - TBLW *-,arp ;7D90 2 T1 1 0 01 - TBLW *,arp ;7D80 2 T1 1 0 01 - TBLW *+ ;7DA8 2 NOP 1 - TBLW *- ;7D98 2 NOP 1 - TBLW * ;7D88 2 NOP 1 - TBLW addr ;7D00 2 T1 1 0 007F - - XOR *+,arp ;78A0 2 T1 1 0 01 - XOR *-,arp ;7890 2 T1 1 0 01 - XOR *,arp ;7880 2 T1 1 0 01 - XOR *+ ;78A8 2 NOP 1 - XOR *- ;7898 2 NOP 1 - XOR * ;7888 2 NOP 1 - XOR addr ;7800 2 T1 1 0 007F - - ZAC ;7F89 2 NOP 1 - - ZALH *+,arp ;65A0 2 T1 1 0 01 - ZALH *-,arp ;6590 2 T1 1 0 01 - ZALH *,arp ;6580 2 T1 1 0 01 - ZALH *+ ;65A8 2 NOP 1 - ZALH *- ;6598 2 NOP 1 - ZALH * ;6588 2 NOP 1 - ZALH addr ;6500 2 T1 1 0 007F - - ZALS *+,arp ;66A0 2 T1 1 0 01 - ZALS *-,arp ;6690 2 T1 1 0 01 - ZALS *,arp ;6680 2 T1 1 0 01 - ZALS *+ ;66A8 2 NOP 1 - ZALS *- ;6698 2 NOP 1 - ZALS * ;6688 2 NOP 1 - ZALS addr ;6600 2 T1 1 0 007F - .end diff --git a/branches/s100/XSource/bin/TEST3225.ASM b/branches/s100/XSource/bin/TEST3225.ASM deleted file mode 100644 index 2fc70558..00000000 --- a/branches/s100/XSource/bin/TEST3225.ASM +++ /dev/null @@ -1,1363 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test3225.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: TMS320C25 -; - - - .org 100h -shift: .equ 4 -shift0: .equ 0 -shiftmode: .equ 3 ;SPM instruction only -addr7: .equ 12h -addr9: .equ 123h -addr16: .equ 1234h -bit: .equ 05h -port: .equ 2 -arp: .equ 3 -nextarp: .equ 4 -ar: .equ 1 -const: .equ 34h -const1: .equ 1h -const8: .equ 0ffh -const13: .equ 0234h -const16: .equ 5678h -cmode: .equ 2 -format: .equ 1 - - ABS - - - ADD *BR0+,shift,nextarp - ADD *BR0-,shift,nextarp - ADD *0+, shift,nextarp - ADD *0-, shift,nextarp - ADD *+, shift,nextarp - ADD *-, shift,nextarp - ADD *, shift,nextarp - ADD *BR0+,shift - ADD *BR0-,shift - ADD *0+, shift - ADD *0-, shift - ADD *+, shift - ADD *-, shift - ADD *, shift - ADD *BR0+ - ADD *BR0- - ADD *0+ - ADD *0- - ADD *+ - ADD *- - ADD * - ADD addr7,shift - ADD addr7 - - ADDC *BR0+,nextarp - ADDC *BR0-,nextarp - ADDC *0+, nextarp - ADDC *0-, nextarp - ADDC *+, nextarp - ADDC *-, nextarp - ADDC *, nextarp - ADDC *BR0+ - ADDC *BR0- - ADDC *0+ - ADDC *0- - ADDC *+ - ADDC *- - ADDC * - ADDC addr7 - - ADDH *BR0+,nextarp - ADDH *BR0-,nextarp - ADDH *0+, nextarp - ADDH *0-, nextarp - ADDH *+, nextarp - ADDH *-, nextarp - ADDH *, nextarp - ADDH *BR0+ - ADDH *BR0- - ADDH *0+ - ADDH *0- - ADDH *+ - ADDH *- - ADDH * - ADDH addr7 - - - ADDK const8 - - ADDS *BR0+,nextarp - ADDS *BR0-,nextarp - ADDS *0+, nextarp - ADDS *0-, nextarp - ADDS *+, nextarp - ADDS *-, nextarp - ADDS *, nextarp - ADDS *BR0+ - ADDS *BR0- - ADDS *0+ - ADDS *0- - ADDS *+ - ADDS *- - ADDS * - ADDS addr7 - - ADDT *BR0+,nextarp - ADDT *BR0-,nextarp - ADDT *0+, nextarp - ADDT *0-, nextarp - ADDT *+, nextarp - ADDT *-, nextarp - ADDT *, nextarp - ADDT *BR0+ - ADDT *BR0- - ADDT *0+ - ADDT *0- - ADDT *+ - ADDT *- - ADDT * - ADDT addr7 - - ADLK const16,shift - ADLK const16 - ADLK 0 - ADLK 1 - ADLK 256 - ADLK 512 - ADLK $1234 - ADLK $1234,0 - - ADRK const8 - - AND *BR0+,nextarp - AND *BR0-,nextarp - AND *0+, nextarp - AND *0-, nextarp - AND *+, nextarp - AND *-, nextarp - AND *, nextarp - AND *BR0+ - AND *BR0- - AND *0+ - AND *0- - AND *+ - AND *- - AND * - AND addr7 - - ANDK const16,shift - ANDK const16 - - APAC - -loop1: - - B loop1,*BR0+,nextarp - B loop1,*BR0-,nextarp - B loop1,*0+, nextarp - B loop1,*0-, nextarp - B loop1,*+, nextarp - B loop1,*-, nextarp - B loop1,*, nextarp - B loop1,*BR0+ - B loop1,*BR0- - B loop1,*0+ - B loop1,*0- - B loop1,*+ - B loop1,*- - B loop1,* - B loop1 - - BACC - - BANZ loop1,*BR0+,nextarp - BANZ loop1,*BR0-,nextarp - BANZ loop1,*0+, nextarp - BANZ loop1,*0-, nextarp - BANZ loop1,*+, nextarp - BANZ loop1,*-, nextarp - BANZ loop1,*, nextarp - BANZ loop1,*BR0+ - BANZ loop1,*BR0- - BANZ loop1,*0+ - BANZ loop1,*0- - BANZ loop1,*+ - BANZ loop1,*- - BANZ loop1,* - BANZ loop1 - - BBNZ loop1,*BR0+,nextarp - BBNZ loop1,*BR0-,nextarp - BBNZ loop1,*0+, nextarp - BBNZ loop1,*0-, nextarp - BBNZ loop1,*+, nextarp - BBNZ loop1,*-, nextarp - BBNZ loop1,*, nextarp - BBNZ loop1,*BR0+ - BBNZ loop1,*BR0- - BBNZ loop1,*0+ - BBNZ loop1,*0- - BBNZ loop1,*+ - BBNZ loop1,*- - BBNZ loop1,* - BBNZ loop1 - - BBZ loop1,*BR0+,nextarp - BBZ loop1,*BR0-,nextarp - BBZ loop1,*0+, nextarp - BBZ loop1,*0-, nextarp - BBZ loop1,*+, nextarp - BBZ loop1,*-, nextarp - BBZ loop1,*, nextarp - BBZ loop1,*BR0+ - BBZ loop1,*BR0- - BBZ loop1,*0+ - BBZ loop1,*0- - BBZ loop1,*+ - BBZ loop1,*- - BBZ loop1,* - BBZ loop1 - - BC loop1,*BR0+,nextarp - BC loop1,*BR0-,nextarp - BC loop1,*0+, nextarp - BC loop1,*0-, nextarp - BC loop1,*+, nextarp - BC loop1,*-, nextarp - BC loop1,*, nextarp - BC loop1,*BR0+ - BC loop1,*BR0- - BC loop1,*0+ - BC loop1,*0- - BC loop1,*+ - BC loop1,*- - BC loop1,* - BC loop1 - - BGEZ loop1,*BR0+,nextarp - BGEZ loop1,*BR0-,nextarp - BGEZ loop1,*0+, nextarp - BGEZ loop1,*0-, nextarp - BGEZ loop1,*+, nextarp - BGEZ loop1,*-, nextarp - BGEZ loop1,*, nextarp - BGEZ loop1,*BR0+ - BGEZ loop1,*BR0- - BGEZ loop1,*0+ - BGEZ loop1,*0- - BGEZ loop1,*+ - BGEZ loop1,*- - BGEZ loop1,* - BGEZ loop1 - - BGZ loop1,*BR0+,nextarp - BGZ loop1,*BR0-,nextarp - BGZ loop1,*0+, nextarp - BGZ loop1,*0-, nextarp - BGZ loop1,*+, nextarp - BGZ loop1,*-, nextarp - BGZ loop1,*, nextarp - BGZ loop1,*BR0+ - BGZ loop1,*BR0- - BGZ loop1,*0+ - BGZ loop1,*0- - BGZ loop1,*+ - BGZ loop1,*- - BGZ loop1,* - BGZ loop1 - - BIOZ loop1,*BR0+,nextarp - BIOZ loop1,*BR0-,nextarp - BIOZ loop1,*0+, nextarp - BIOZ loop1,*0-, nextarp - BIOZ loop1,*+, nextarp - BIOZ loop1,*-, nextarp - BIOZ loop1,*, nextarp - BIOZ loop1,*BR0+ - BIOZ loop1,*BR0- - BIOZ loop1,*0+ - BIOZ loop1,*0- - BIOZ loop1,*+ - BIOZ loop1,*- - BIOZ loop1,* - BIOZ loop1 - - BLEZ loop1,*BR0+,nextarp - BLEZ loop1,*BR0-,nextarp - BLEZ loop1,*0+, nextarp - BLEZ loop1,*0-, nextarp - BLEZ loop1,*+, nextarp - BLEZ loop1,*-, nextarp - BLEZ loop1,*, nextarp - BLEZ loop1,*BR0+ - BLEZ loop1,*BR0- - BLEZ loop1,*0+ - BLEZ loop1,*0- - BLEZ loop1,*+ - BLEZ loop1,*- - BLEZ loop1,* - BLEZ loop1 - - BLZ loop1,*BR0+,nextarp - BLZ loop1,*BR0-,nextarp - BLZ loop1,*0+, nextarp - BLZ loop1,*0-, nextarp - BLZ loop1,*+, nextarp - BLZ loop1,*-, nextarp - BLZ loop1,*, nextarp - BLZ loop1,*BR0+ - BLZ loop1,*BR0- - BLZ loop1,*0+ - BLZ loop1,*0- - BLZ loop1,*+ - BLZ loop1,*- - BLZ loop1,* - BLZ loop1 - - BNC loop1,*BR0+,nextarp - BNC loop1,*BR0-,nextarp - BNC loop1,*0+, nextarp - BNC loop1,*0-, nextarp - BNC loop1,*+, nextarp - BNC loop1,*-, nextarp - BNC loop1,*, nextarp - BNC loop1,*BR0+ - BNC loop1,*BR0- - BNC loop1,*0+ - BNC loop1,*0- - BNC loop1,*+ - BNC loop1,*- - BNC loop1,* - BNC loop1 - - BNV loop1,*BR0+,nextarp - BNV loop1,*BR0-,nextarp - BNV loop1,*0+, nextarp - BNV loop1,*0-, nextarp - BNV loop1,*+, nextarp - BNV loop1,*-, nextarp - BNV loop1,*, nextarp - BNV loop1,*BR0+ - BNV loop1,*BR0- - BNV loop1,*0+ - BNV loop1,*0- - BNV loop1,*+ - BNV loop1,*- - BNV loop1,* - BNV loop1 - - BNZ loop1,*BR0+,nextarp - BNZ loop1,*BR0-,nextarp - BNZ loop1,*0+, nextarp - BNZ loop1,*0-, nextarp - BNZ loop1,*+, nextarp - BNZ loop1,*-, nextarp - BNZ loop1,*, nextarp - BNZ loop1,*BR0+ - BNZ loop1,*BR0- - BNZ loop1,*0+ - BNZ loop1,*0- - BNZ loop1,*+ - BNZ loop1,*- - BNZ loop1,* - BNZ loop1 - - BV loop1,*BR0+,nextarp - BV loop1,*BR0-,nextarp - BV loop1,*0+, nextarp - BV loop1,*0-, nextarp - BV loop1,*+, nextarp - BV loop1,*-, nextarp - BV loop1,*, nextarp - BV loop1,*BR0+ - BV loop1,*BR0- - BV loop1,*0+ - BV loop1,*0- - BV loop1,*+ - BV loop1,*- - BV loop1,* - BV loop1 - - BZ loop1,*BR0+,nextarp - BZ loop1,*BR0-,nextarp - BZ loop1,*0+, nextarp - BZ loop1,*0-, nextarp - BZ loop1,*+, nextarp - BZ loop1,*-, nextarp - BZ loop1,*, nextarp - BZ loop1,*BR0+ - BZ loop1,*BR0- - BZ loop1,*0+ - BZ loop1,*0- - BZ loop1,*+ - BZ loop1,*- - BZ loop1,* - BZ loop1 - - BIT *BR0+,bit ,nextarp - BIT *BR0-,bit ,nextarp - BIT *0+, bit ,nextarp - BIT *0-, bit ,nextarp - BIT *+, bit ,nextarp - BIT *-, bit ,nextarp - BIT *, bit ,nextarp - BIT *BR0+,bit - BIT *BR0-,bit - BIT *0+, bit - BIT *0-, bit - BIT *+, bit - BIT *-, bit - BIT *, bit - BIT addr7,bit - - BITT *BR0+,nextarp - BITT *BR0-,nextarp - BITT *0+, nextarp - BITT *0-, nextarp - BITT *+, nextarp - BITT *-, nextarp - BITT *, nextarp - BITT *BR0+ - BITT *BR0- - BITT *0+ - BITT *0- - BITT *+ - BITT *- - BITT * - BITT addr7 - - BLKD addr16,*BR0+,nextarp - BLKD addr16,*BR0-,nextarp - BLKD addr16,*0+, nextarp - BLKD addr16,*0-, nextarp - BLKD addr16,*+, nextarp - BLKD addr16,*-, nextarp - BLKD addr16,*, nextarp - BLKD addr16,*BR0+ - BLKD addr16,*BR0- - BLKD addr16,*0+ - BLKD addr16,*0- - BLKD addr16,*+ - BLKD addr16,*- - BLKD addr16,* - BLKD addr16,addr7 - - BLKP addr16,*BR0+,nextarp - BLKP addr16,*BR0-,nextarp - BLKP addr16,*0+, nextarp - BLKP addr16,*0-, nextarp - BLKP addr16,*+, nextarp - BLKP addr16,*-, nextarp - BLKP addr16,*, nextarp - BLKP addr16,*BR0+ - BLKP addr16,*BR0- - BLKP addr16,*0+ - BLKP addr16,*0- - BLKP addr16,*+ - BLKP addr16,*- - BLKP addr16,* - BLKP addr16,addr7 - - CALA - - CALL addr16,*BR0+,nextarp - CALL addr16,*BR0-,nextarp - CALL addr16,*0+, nextarp - CALL addr16,*0-, nextarp - CALL addr16,*+, nextarp - CALL addr16,*-, nextarp - CALL addr16,*, nextarp - CALL addr16,*BR0+ - CALL addr16,*BR0- - CALL addr16,*0+ - CALL addr16,*0- - CALL addr16,*+ - CALL addr16,*- - CALL addr16,* - CALL addr16 - - CMPL - - CMPR cmode - - CNFD - CNFP - - DINT - - DMOV *BR0+,nextarp - DMOV *BR0-,nextarp - DMOV *0+, nextarp - DMOV *0-, nextarp - DMOV *+, nextarp - DMOV *-, nextarp - DMOV *, nextarp - DMOV *BR0+ - DMOV *BR0- - DMOV *0+ - DMOV *0- - DMOV *+ - DMOV *- - DMOV * - DMOV addr7 - - EINT - - FORT format - - IDLE - - IN *BR0+,port,nextarp - IN *BR0-,port,nextarp - IN *0+, port,nextarp - IN *0-, port,nextarp - IN *+, port,nextarp - IN *-, port,nextarp - IN *, port,nextarp - IN *BR0+,port - IN *BR0-,port - IN *0+, port - IN *0-, port - IN *+, port - IN *-, port - IN *, port - IN addr7,port - - LAC *BR0+,shift,nextarp - LAC *BR0-,shift,nextarp - LAC *0+, shift,nextarp - LAC *0-, shift,nextarp - LAC *+, shift,nextarp - LAC *-, shift,nextarp - LAC *, shift,nextarp - LAC *BR0+,shift - LAC *BR0-,shift - LAC *0+, shift - LAC *0-, shift - LAC *+, shift - LAC *-, shift - LAC *, shift - LAC *BR0+ - LAC *BR0- - LAC *0+ - LAC *0- - LAC *+ - LAC *- - LAC * - LAC addr7,shift - LAC addr7 - - LACK const8 - - LACT *BR0+,nextarp - LACT *BR0-,nextarp - LACT *0+, nextarp - LACT *0-, nextarp - LACT *+, nextarp - LACT *-, nextarp - LACT *, nextarp - LACT *BR0+ - LACT *BR0- - LACT *0+ - LACT *0- - LACT *+ - LACT *- - LACT * - LACT addr7 - - LALK const16,shift - LALK const16 - - LAR arp,*BR0+,nextarp - LAR arp,*BR0-,nextarp - LAR arp,*0+, nextarp - LAR arp,*0-, nextarp - LAR arp,*+, nextarp - LAR arp,*-, nextarp - LAR arp,*, nextarp - LAR arp,*BR0+ - LAR arp,*BR0- - LAR arp,*0+ - LAR arp,*0- - LAR arp,*+ - LAR arp,*- - LAR arp,* - LAR arp,addr7 - - LARK arp, const8 - - LARP arp - - LDP *BR0+,nextarp - LDP *BR0-,nextarp - LDP *0+, nextarp - LDP *0-, nextarp - LDP *+, nextarp - LDP *-, nextarp - LDP *, nextarp - LDP *BR0+ - LDP *BR0- - LDP *0+ - LDP *0- - LDP *+ - LDP *- - LDP * - LDP addr7 - - LDPK addr9 - - LPH *BR0+,nextarp - LPH *BR0-,nextarp - LPH *0+, nextarp - LPH *0-, nextarp - LPH *+, nextarp - LPH *-, nextarp - LPH *, nextarp - LPH *BR0+ - LPH *BR0- - LPH *0+ - LPH *0- - LPH *+ - LPH *- - LPH * - LPH addr7 - - LRLK arp, const16 - - LST *BR0+,nextarp - LST *BR0-,nextarp - LST *0+, nextarp - LST *0-, nextarp - LST *+, nextarp - LST *-, nextarp - LST *, nextarp - LST *BR0+ - LST *BR0- - LST *0+ - LST *0- - LST *+ - LST *- - LST * - LST addr7 - - LST1 *BR0+,nextarp - LST1 *BR0-,nextarp - LST1 *0+, nextarp - LST1 *0-, nextarp - LST1 *+, nextarp - LST1 *-, nextarp - LST1 *, nextarp - LST1 *BR0+ - LST1 *BR0- - LST1 *0+ - LST1 *0- - LST1 *+ - LST1 *- - LST1 * - LST1 addr7 - - LT *BR0+,nextarp - LT *BR0-,nextarp - LT *0+, nextarp - LT *0-, nextarp - LT *+, nextarp - LT *-, nextarp - LT *, nextarp - LT *BR0+ - LT *BR0- - LT *0+ - LT *0- - LT *+ - LT *- - LT * - LT addr7 - - LTA *BR0+,nextarp - LTA *BR0-,nextarp - LTA *0+, nextarp - LTA *0-, nextarp - LTA *+, nextarp - LTA *-, nextarp - LTA *, nextarp - LTA *BR0+ - LTA *BR0- - LTA *0+ - LTA *0- - LTA *+ - LTA *- - LTA * - LTA addr7 - - LTD *BR0+,nextarp - LTD *BR0-,nextarp - LTD *0+, nextarp - LTD *0-, nextarp - LTD *+, nextarp - LTD *-, nextarp - LTD *, nextarp - LTD *BR0+ - LTD *BR0- - LTD *0+ - LTD *0- - LTD *+ - LTD *- - LTD * - LTD addr7 - - LTP *BR0+,nextarp - LTP *BR0-,nextarp - LTP *0+, nextarp - LTP *0-, nextarp - LTP *+, nextarp - LTP *-, nextarp - LTP *, nextarp - LTP *BR0+ - LTP *BR0- - LTP *0+ - LTP *0- - LTP *+ - LTP *- - LTP * - LTP addr7 - - LTS *BR0+,nextarp - LTS *BR0-,nextarp - LTS *0+, nextarp - LTS *0-, nextarp - LTS *+, nextarp - LTS *-, nextarp - LTS *, nextarp - LTS *BR0+ - LTS *BR0- - LTS *0+ - LTS *0- - LTS *+ - LTS *- - LTS * - LTS addr7 - - MAC addr16,*BR0+,nextarp - MAC addr16,*BR0-,nextarp - MAC addr16,*0+, nextarp - MAC addr16,*0-, nextarp - MAC addr16,*+, nextarp - MAC addr16,*-, nextarp - MAC addr16,*, nextarp - MAC addr16,*BR0+ - MAC addr16,*BR0- - MAC addr16,*0+ - MAC addr16,*0- - MAC addr16,*+ - MAC addr16,*- - MAC addr16,* - MAC addr16,addr7 - - MACD addr16,*BR0+,nextarp - MACD addr16,*BR0-,nextarp - MACD addr16,*0+, nextarp - MACD addr16,*0-, nextarp - MACD addr16,*+, nextarp - MACD addr16,*-, nextarp - MACD addr16,*, nextarp - MACD addr16,*BR0+ - MACD addr16,*BR0- - MACD addr16,*0+ - MACD addr16,*0- - MACD addr16,*+ - MACD addr16,*- - MACD addr16,* - MACD addr16,addr7 - - MAR *BR0+,nextarp - MAR *BR0-,nextarp - MAR *0+, nextarp - MAR *0-, nextarp - MAR *+, nextarp - MAR *-, nextarp - MAR *, nextarp - MAR *BR0+ - MAR *BR0- - MAR *0+ - MAR *0- - MAR *+ - MAR *- - MAR * - MAR addr7 - - MPY *BR0+,nextarp - MPY *BR0-,nextarp - MPY *0+, nextarp - MPY *0-, nextarp - MPY *+, nextarp - MPY *-, nextarp - MPY *, nextarp - MPY *BR0+ - MPY *BR0- - MPY *0+ - MPY *0- - MPY *+ - MPY *- - MPY * - MPY addr7 - - MPYA *BR0+,nextarp - MPYA *BR0-,nextarp - MPYA *0+, nextarp - MPYA *0-, nextarp - MPYA *+, nextarp - MPYA *-, nextarp - MPYA *, nextarp - MPYA *BR0+ - MPYA *BR0- - MPYA *0+ - MPYA *0- - MPYA *+ - MPYA *- - MPYA * - MPYA addr7 - - MPYK const13 - - MPYS *BR0+,nextarp - MPYS *BR0-,nextarp - MPYS *0+, nextarp - MPYS *0-, nextarp - MPYS *+, nextarp - MPYS *-, nextarp - MPYS *, nextarp - MPYS *BR0+ - MPYS *BR0- - MPYS *0+ - MPYS *0- - MPYS *+ - MPYS *- - MPYS * - MPYS addr7 - - MPYU *BR0+,nextarp - MPYU *BR0-,nextarp - MPYU *0+, nextarp - MPYU *0-, nextarp - MPYU *+, nextarp - MPYU *-, nextarp - MPYU *, nextarp - MPYU *BR0+ - MPYU *BR0- - MPYU *0+ - MPYU *0- - MPYU *+ - MPYU *- - MPYU * - MPYU addr7 - - NEG - - NOP - - NORM *BR0+ - NORM *BR0- - NORM *0+ - NORM *0- - NORM *+ - NORM *- - NORM * - NORM - - OR *BR0+,nextarp - OR *BR0-,nextarp - OR *0+, nextarp - OR *0-, nextarp - OR *+, nextarp - OR *-, nextarp - OR *, nextarp - OR *BR0+ - OR *BR0- - OR *0+ - OR *0- - OR *+ - OR *- - OR * - OR addr7 - - ORK const16, shift - ORK const16 - - OUT *BR0+,port,nextarp - OUT *BR0-,port,nextarp - OUT *0+, port,nextarp - OUT *0-, port,nextarp - OUT *+, port,nextarp - OUT *-, port,nextarp - OUT *, port,nextarp - OUT *BR0+,port - OUT *BR0-,port - OUT *0+, port - OUT *0-, port - OUT *+, port - OUT *-, port - OUT *, port - OUT addr7,port - - PAC - POP - - POPD *BR0+,nextarp - POPD *BR0-,nextarp - POPD *0+, nextarp - POPD *0-, nextarp - POPD *+, nextarp - POPD *-, nextarp - POPD *, nextarp - POPD *BR0+ - POPD *BR0- - POPD *0+ - POPD *0- - POPD *+ - POPD *- - POPD * - POPD addr7 - - PSHD *BR0+,nextarp - PSHD *BR0-,nextarp - PSHD *0+, nextarp - PSHD *0-, nextarp - PSHD *+, nextarp - PSHD *-, nextarp - PSHD *, nextarp - PSHD *BR0+ - PSHD *BR0- - PSHD *0+ - PSHD *0- - PSHD *+ - PSHD *- - PSHD * - PSHD addr7 - - PUSH - RC - RET - RFSM - RHM - ROL - ROR - ROVM - - RPT *BR0+,nextarp - RPT *BR0-,nextarp - RPT *0+, nextarp - RPT *0-, nextarp - RPT *+, nextarp - RPT *-, nextarp - RPT *, nextarp - RPT *BR0+ - RPT *BR0- - RPT *0+ - RPT *0- - RPT *+ - RPT *- - RPT * - RPT addr7 - - RPTK const8 - - RSXM - RTC - RTXM - RXF - - SACH *BR0+,shift,nextarp - SACH *BR0-,shift,nextarp - SACH *0+, shift,nextarp - SACH *0-, shift,nextarp - SACH *+, shift,nextarp - SACH *-, shift,nextarp - SACH *, shift,nextarp - SACH *BR0+,shift - SACH *BR0-,shift - SACH *0+, shift - SACH *0-, shift - SACH *+, shift - SACH *-, shift - SACH *, shift - SACH *BR0+ - SACH *BR0- - SACH *0+ - SACH *0- - SACH *+ - SACH *- - SACH * - SACH addr7,shift - SACH addr7 - - SACL *BR0+,shift,nextarp - SACL *BR0-,shift,nextarp - SACL *0+, shift,nextarp - SACL *0-, shift,nextarp - SACL *+, shift,nextarp - SACL *-, shift,nextarp - SACL *, shift,nextarp - SACL *BR0+,shift - SACL *BR0-,shift - SACL *0+, shift - SACL *0-, shift - SACL *+, shift - SACL *-, shift - SACL *, shift - SACL *BR0+ - SACL *BR0- - SACL *0+ - SACL *0- - SACL *+ - SACL *- - SACL * - SACL addr7,shift - SACL addr7 - - SAR arp,*BR0+,nextarp - SAR arp,*BR0-,nextarp - SAR arp,*0+, nextarp - SAR arp,*0-, nextarp - SAR arp,*+, nextarp - SAR arp,*-, nextarp - SAR arp,*, nextarp - SAR arp,*BR0+ - SAR arp,*BR0- - SAR arp,*0+ - SAR arp,*0- - SAR arp,*+ - SAR arp,*- - SAR arp,* - SAR arp,addr7 - - SBLK const16, shift - SBLK const16 - - SBRK const8 - - SC - SFL - SFR - SFSM - SHM - SOVM - SPAC - - SPH *BR0+,nextarp - SPH *BR0-,nextarp - SPH *0+, nextarp - SPH *0-, nextarp - SPH *+, nextarp - SPH *-, nextarp - SPH *, nextarp - SPH *BR0+ - SPH *BR0- - SPH *0+ - SPH *0- - SPH *+ - SPH *- - SPH * - SPH addr7 - - SPL *BR0+,nextarp - SPL *BR0-,nextarp - SPL *0+, nextarp - SPL *0-, nextarp - SPL *+, nextarp - SPL *-, nextarp - SPL *, nextarp - SPL *BR0+ - SPL *BR0- - SPL *0+ - SPL *0- - SPL *+ - SPL *- - SPL * - SPL addr7 - - SPM shiftmode - - SQRA *BR0+,nextarp - SQRA *BR0-,nextarp - SQRA *0+, nextarp - SQRA *0-, nextarp - SQRA *+, nextarp - SQRA *-, nextarp - SQRA *, nextarp - SQRA *BR0+ - SQRA *BR0- - SQRA *0+ - SQRA *0- - SQRA *+ - SQRA *- - SQRA * - SQRA addr7 - - SQRS *BR0+,nextarp - SQRS *BR0-,nextarp - SQRS *0+, nextarp - SQRS *0-, nextarp - SQRS *+, nextarp - SQRS *-, nextarp - SQRS *, nextarp - SQRS *BR0+ - SQRS *BR0- - SQRS *0+ - SQRS *0- - SQRS *+ - SQRS *- - SQRS * - SQRS addr7 - - SST *BR0+,nextarp - SST *BR0-,nextarp - SST *0+, nextarp - SST *0-, nextarp - SST *+, nextarp - SST *-, nextarp - SST *, nextarp - SST *BR0+ - SST *BR0- - SST *0+ - SST *0- - SST *+ - SST *- - SST * - SST addr7 - - SST1 *BR0+,nextarp - SST1 *BR0-,nextarp - SST1 *0+, nextarp - SST1 *0-, nextarp - SST1 *+, nextarp - SST1 *-, nextarp - SST1 *, nextarp - SST1 *BR0+ - SST1 *BR0- - SST1 *0+ - SST1 *0- - SST1 *+ - SST1 *- - SST1 * - SST1 addr7 - - SSXM - STC - STXM - - SUB *BR0+,shift,nextarp - SUB *BR0-,shift,nextarp - SUB *0+, shift,nextarp - SUB *0-, shift,nextarp - SUB *+, shift,nextarp - SUB *-, shift,nextarp - SUB *, shift,nextarp - SUB *BR0+,shift - SUB *BR0-,shift - SUB *0+, shift - SUB *0-, shift - SUB *+, shift - SUB *-, shift - SUB *, shift - SUB *BR0+ - SUB *BR0- - SUB *0+ - SUB *0- - SUB *+ - SUB *- - SUB * - SUB addr7,shift - SUB addr7 - - SUBB *BR0+,nextarp - SUBB *BR0-,nextarp - SUBB *0+, nextarp - SUBB *0-, nextarp - SUBB *+, nextarp - SUBB *-, nextarp - SUBB *, nextarp - SUBB *BR0+ - SUBB *BR0- - SUBB *0+ - SUBB *0- - SUBB *+ - SUBB *- - SUBB * - SUBB addr7 - - SUBC *BR0+,nextarp - SUBC *BR0-,nextarp - SUBC *0+, nextarp - SUBC *0-, nextarp - SUBC *+, nextarp - SUBC *-, nextarp - SUBC *, nextarp - SUBC *BR0+ - SUBC *BR0- - SUBC *0+ - SUBC *0- - SUBC *+ - SUBC *- - SUBC * - SUBC addr7 - - SUBH *BR0+,nextarp - SUBH *BR0-,nextarp - SUBH *0+, nextarp - SUBH *0-, nextarp - SUBH *+, nextarp - SUBH *-, nextarp - SUBH *, nextarp - SUBH *BR0+ - SUBH *BR0- - SUBH *0+ - SUBH *0- - SUBH *+ - SUBH *- - SUBH * - SUBH addr7 - - SUBK const8 - - SUBS *BR0+,nextarp - SUBS *BR0-,nextarp - SUBS *0+, nextarp - SUBS *0-, nextarp - SUBS *+, nextarp - SUBS *-, nextarp - SUBS *, nextarp - SUBS *BR0+ - SUBS *BR0- - SUBS *0+ - SUBS *0- - SUBS *+ - SUBS *- - SUBS * - SUBS addr7 - - SUBT *BR0+,nextarp - SUBT *BR0-,nextarp - SUBT *0+, nextarp - SUBT *0-, nextarp - SUBT *+, nextarp - SUBT *-, nextarp - SUBT *, nextarp - SUBT *BR0+ - SUBT *BR0- - SUBT *0+ - SUBT *0- - SUBT *+ - SUBT *- - SUBT * - SUBT addr7 - - SXF - - TBLR *BR0+,nextarp - TBLR *BR0-,nextarp - TBLR *0+, nextarp - TBLR *0-, nextarp - TBLR *+, nextarp - TBLR *-, nextarp - TBLR *, nextarp - TBLR *BR0+ - TBLR *BR0- - TBLR *0+ - TBLR *0- - TBLR *+ - TBLR *- - TBLR * - TBLR addr7 - - TBLW *BR0+,nextarp - TBLW *BR0-,nextarp - TBLW *0+, nextarp - TBLW *0-, nextarp - TBLW *+, nextarp - TBLW *-, nextarp - TBLW *, nextarp - TBLW *BR0+ - TBLW *BR0- - TBLW *0+ - TBLW *0- - TBLW *+ - TBLW *- - TBLW * - TBLW addr7 - - TRAP - - XOR *BR0+,nextarp - XOR *BR0-,nextarp - XOR *0+, nextarp - XOR *0-, nextarp - XOR *+, nextarp - XOR *-, nextarp - XOR *, nextarp - XOR *BR0+ - XOR *BR0- - XOR *0+ - XOR *0- - XOR *+ - XOR *- - XOR * - XOR addr7 - - XORK const16, shift - XORK const16 - - ZAC - - ZALH *BR0+,nextarp - ZALH *BR0-,nextarp - ZALH *0+, nextarp - ZALH *0-, nextarp - ZALH *+, nextarp - ZALH *-, nextarp - ZALH *, nextarp - ZALH *BR0+ - ZALH *BR0- - ZALH *0+ - ZALH *0- - ZALH *+ - ZALH *- - ZALH * - ZALH addr7 - - ZALR *BR0+,nextarp - ZALR *BR0-,nextarp - ZALR *0+, nextarp - ZALR *0-, nextarp - ZALR *+, nextarp - ZALR *-, nextarp - ZALR *, nextarp - ZALR *BR0+ - ZALR *BR0- - ZALR *0+ - ZALR *0- - ZALR *+ - ZALR *- - ZALR * - ZALR addr7 - - ZALS *BR0+,nextarp - ZALS *BR0-,nextarp - ZALS *0+, nextarp - ZALS *0-, nextarp - ZALS *+, nextarp - ZALS *-, nextarp - ZALS *, nextarp - ZALS *BR0+ - ZALS *BR0- - ZALS *0+ - ZALS *0- - ZALS *+ - ZALS *- - ZALS * - ZALS addr7 - .end - diff --git a/branches/s100/XSource/bin/TEST48.ASM b/branches/s100/XSource/bin/TEST48.ASM deleted file mode 100644 index c51eabeb..00000000 --- a/branches/s100/XSource/bin/TEST48.ASM +++ /dev/null @@ -1,279 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test48.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8048 -; - - -label1 .equ 12H - - ADD A,R0 - ADD A,R1 - ADD A,R2 - ADD A,R3 - ADD A,R4 - ADD A,R5 - ADD A,R6 - ADD A,R7 - ADD A,@R0 - ADD A,@R1 - ADD A,#label1 - - ADDC A,R0 - ADDC A,R1 - ADDC A,R2 - ADDC A,R3 - ADDC A,R4 - ADDC A,R5 - ADDC A,R6 - ADDC A,R7 - ADDC A,@R0 - ADDC A,@R1 - ADDC A,#label1 - - ANL A,R0 - ANL A,R1 - ANL A,R2 - ANL A,R3 - ANL A,R4 - ANL A,R5 - ANL A,R6 - ANL A,R7 - ANL A,@R0 - ANL A,@R1 - ANL A,#label1 - ANL BUS,#label1 - ANL P1,#label1 - ANL P2,#label1 - - ANLD P4,A - ANLD P5,A - ANLD P6,A - ANLD P7,A - - CALL label1 - - CLR A - CLR C - CLR F0 - CLR F1 - - CPL A - CPL C - CPL F0 - CPL F1 - - DA A - - DEC A - DEC R0 - DEC R1 - DEC R2 - DEC R3 - DEC R4 - DEC R5 - DEC R6 - DEC R7 - - DIS I - DIS TCNTI - - DJNZ R0,label1 - DJNZ R1,label1 - DJNZ R2,label1 - DJNZ R3,label1 - DJNZ R4,label1 - DJNZ R5,label1 - DJNZ R6,label1 - DJNZ R7,label1 - - EN DMA - EN FLAGS - EN I - EN TCNTI - ENT0 CLK - - IN A,DBB - IN A,P0 - IN A,P1 - IN A,P2 - - INC A - INC R0 - INC R1 - INC R2 - INC R3 - INC R4 - INC R5 - INC R6 - INC R7 - INC @R0 - INC @R1 - - INS A,BUS - - JB0 label1 - JB1 label1 - JB2 label1 - JB3 label1 - JB4 label1 - JB5 label1 - JB6 label1 - JB7 label1 - - JMP label1 - - JC label1 - JF0 label1 - JF1 label1 - JNC label1 - JNI label1 - JNIBF label1 - JNT0 label1 - JNT1 label1 - JNZ label1 - JOBF label1 - JTF label1 - JT0 label1 - JT1 label1 - JZ label1 - - JMPP @A - - MOV A,PSW - MOV A,R0 - MOV A,R1 - MOV A,R2 - MOV A,R3 - MOV A,R4 - MOV A,R5 - MOV A,R6 - MOV A,R7 - MOV A,T - MOV A,@R0 - MOV A,@R1 - MOV A,#label1 - MOV PSW,A - MOV R0,A - MOV R1,A - MOV R2,A - MOV R3,A - MOV R4,A - MOV R5,A - MOV R6,A - MOV R7,A - MOV R0,#label1 - MOV R1,#label1 - MOV R2,#label1 - MOV R3,#label1 - MOV R4,#label1 - MOV R5,#label1 - MOV R6,#label1 - MOV R7,#label1 - MOV STS,A - MOV T,A - MOV @R0,A - MOV @R1,A - MOV @R0,#label1 - MOV @R1,#label1 - - MOVD A,P4 - MOVD A,P5 - MOVD A,P6 - MOVD A,P7 - MOVD P4,A - MOVD P5,A - MOVD P6,A - MOVD P7,A - - MOVP A,@A - MOVP3 A,@A - - - MOVX A,@R0 - MOVX A,@R1 - MOVX @R0,A - MOVX @R1,A - - NOP - - ORL A,R0 - ORL A,R1 - ORL A,R2 - ORL A,R3 - ORL A,R4 - ORL A,R5 - ORL A,R6 - ORL A,R7 - ORL A,@R0 - ORL A,@R1 - ORL A,#label1 - ORL BUS,#label1 - ORL P1,#label1 - ORL P2,#label1 - - ORLD P4,A - ORLD P5,A - ORLD P6,A - ORLD P7,A - - OUTL BUS,A - OUT DBB,A - OUTL P0,A - OUTL P1,A - OUTL P2,A - - RAD - - RET - RETI - RETR - - RL A - RLC A - RR A - RRC A - - SEL AN0 - SEL AN1 - SEL MB0 - SEL MB1 - SEL RB0 - SEL RB1 - - STOP TCNT - STRT CNT - STRT T - - SWAP A - - XCH A,R0 - XCH A,R1 - XCH A,R2 - XCH A,R3 - XCH A,R4 - XCH A,R5 - XCH A,R6 - XCH A,R7 - XCH A,@R0 - XCH A,@R1 - - XCHD A,@R0 - XCHD A,@R1 - - XRL A,R0 - XRL A,R1 - XRL A,R2 - XRL A,R3 - XRL A,R4 - XRL A,R5 - XRL A,R6 - XRL A,R7 - XRL A,@R0 - XRL A,@R1 - XRL A,#label1 - .end diff --git a/branches/s100/XSource/bin/TEST51.ASM b/branches/s100/XSource/bin/TEST51.ASM deleted file mode 100644 index 781ff094..00000000 --- a/branches/s100/XSource/bin/TEST51.ASM +++ /dev/null @@ -1,297 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test51.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8051 -; - - - .AVSYM - -labimm: .EQU 56h -lab2: .EQU 12h -lab3: .EQU 1234h -lab5: .EQU 0feh -labbt_1: .EQU 34h -bit .equ 81h - - - ACALL lab4 ;11 2 JMP 1 -lab4: - ADD A,R0 ;28 1 NOP 1 - ADD A,R1 ;29 1 NOP 1 - ADD A,R2 ;2A 1 NOP 1 - ADD A,R3 ;2B 1 NOP 1 - ADD A,R4 ;2C 1 NOP 1 - ADD A,R5 ;2D 1 NOP 1 - ADD A,R6 ;2E 1 NOP 1 - ADD A,R7 ;2F 1 NOP 1 - ADD A,@R0 ;26 1 NOP 1 - ADD A,@R1 ;27 1 NOP 1 - ADD A,#labimm ;24 2 NOP 1 - ADD A,lab2 ;25 2 NOP 1 - - ADDC A,R0 ;38 1 NOP 1 - ADDC A,R1 ;39 1 NOP 1 - ADDC A,R2 ;3A 1 NOP 1 - ADDC A,R3 ;3B 1 NOP 1 - ADDC A,R4 ;3C 1 NOP 1 - ADDC A,R5 ;3D 1 NOP 1 - ADDC A,R6 ;3E 1 NOP 1 - ADDC A,R7 ;3F 1 NOP 1 - ADDC A,@R0 ;36 1 NOP 1 - ADDC A,@R1 ;37 1 NOP 1 - ADDC A,#labimm ;34 2 NOP 1 - ADDC A,lab2 ;35 2 NOP 1 - - AJMP jlab ;01 2 JMP 1 - - ANL A,R0 ;58 1 NOP 1 - ANL A,R1 ;59 1 NOP 1 - ANL A,R2 ;5A 1 NOP 1 - ANL A,R3 ;5B 1 NOP 1 - ANL A,R4 ;5C 1 NOP 1 - ANL A,R5 ;5D 1 NOP 1 - ANL A,R6 ;5E 1 NOP 1 - ANL A,R7 ;5F 1 NOP 1 - ANL A,@R0 ;56 1 NOP 1 - ANL A,@R1 ;57 1 NOP 1 - ANL A,#labimm - ANL A,lab2 - ANL C,/bit - ANL C,bit - ANL lab2,A - ANL lab2,#labimm - - CJNE A,#labimm,jlab ;b4 3 CR 1 - CJNE A,lab2,jlab ;b5 3 CR 1 - CJNE R0,#labimm,jlab ;b8 3 CR 1 - CJNE R1,#labimm,jlab ;b9 3 CR 1 - CJNE R2,#labimm,jlab ;ba 3 CR 1 - CJNE R3,#labimm,jlab ;bb 3 CR 1 - CJNE R4,#labimm,jlab ;bc 3 CR 1 - CJNE R5,#labimm,jlab ;bd 3 CR 1 - CJNE R6,#labimm,jlab ;be 3 CR 1 - CJNE R7,#labimm,jlab ;bf 3 CR 1 - CJNE @R0,#labimm,jlab ;b6 3 CR 1 - CJNE @R1,#labimm,jlab ;b7 3 CR 1 - - CLR A ;e4 1 NOP 1 - CLR C ;c3 1 NOP 1 - CLR bit - - CPL A ;f4 1 NOP 1 - CPL C ;b3 1 NOP 1 - CPL bit - - DA A ;d4 1 NOP 1 - - DEC A ;14 1 NOP 1 - DEC R0 ;18 1 NOP 1 - DEC R1 ;19 1 NOP 1 - DEC R2 ;1A 1 NOP 1 - DEC R3 ;1B 1 NOP 1 - DEC R4 ;1C 1 NOP 1 - DEC R5 ;1D 1 NOP 1 - DEC R6 ;1E 1 NOP 1 - DEC R7 ;1F 1 NOP 1 - DEC @R0 ;16 1 NOP 1 - DEC @R1 ;17 1 NOP 1 - DEC lab2 ;15 2 NOP 1 - - DIV AB ;84 1 NOP 1 - - DJNZ R0,jlab ;d8 2 NOP 1 - DJNZ R1,jlab ;d9 2 NOP 1 - DJNZ R2,jlab ;dA 2 NOP 1 - DJNZ R3,jlab ;dB 2 NOP 1 - DJNZ R4,jlab ;dC 2 NOP 1 - DJNZ R5,jlab ;dD 2 NOP 1 - DJNZ R6,jlab ;dE 2 NOP 1 - DJNZ R7,jlab ;dF 2 NOP 1 - DJNZ lab2,jlab ;d5 3 CR 1 - - INC A ;04 1 NOP 1 - INC R0 ;08 1 NOP 1 - INC R1 ;09 1 NOP 1 - INC R2 ;0A 1 NOP 1 - INC R3 ;0B 1 NOP 1 - INC R4 ;0C 1 NOP 1 - INC R5 ;0D 1 NOP 1 - INC R6 ;0E 1 NOP 1 - INC R7 ;0F 1 NOP 1 - INC @R0 ;06 1 NOP 1 - INC @R1 ;07 1 NOP 1 - INC DPTR ;a3 1 NOP 1 - INC lab2 ;05 2 NOP 1 - -jlab: - JB labbt_1,jlab ;20 3 CR 1 - JBC labbt_1,jlab ;10 3 CR 1 - JC jlab ;40 2 R1 1 - JMP @A+DPTR ;73 1 NOP 1 - JNB labbt_1,jlab ;30 3 CR 1 - JNC jlab ;50 2 R1 1 - JNZ jlab ;70 2 R1 1 - JZ jlab ;60 2 R1 1 - - LCALL lab3 ;12 3 SWAP 1 - - LJMP lab3 ;02 3 SWAP 1 - - MOV A,R0 ;e8 1 NOP 1 - MOV A,R1 ;e9 1 NOP 1 - MOV A,R2 ;eA 1 NOP 1 - MOV A,R3 ;eB 1 NOP 1 - MOV A,R4 ;eC 1 NOP 1 - MOV A,R5 ;eD 1 NOP 1 - MOV A,R6 ;eE 1 NOP 1 - MOV A,R7 ;eF 1 NOP 1 - MOV A,@R0 ;e6 1 NOP 1 - MOV A,@R1 ;e7 1 NOP 1 - MOV A,#labimm ;74 2 NOP 1 - MOV A,lab2 ;e5 2 NOP 1 - MOV C,bit ;a2 2 NOP 1 - MOV DPTR,#labimm ;90 3 SWAP 1 - MOV R0,A ;f8 1 NOP 1 - MOV R1,A ;f9 1 NOP 1 - MOV R2,A ;fA 1 NOP 1 - MOV R3,A ;fB 1 NOP 1 - MOV R4,A ;fC 1 NOP 1 - MOV R5,A ;fD 1 NOP 1 - MOV R6,A ;fE 1 NOP 1 - MOV R7,A ;fF 1 NOP 1 - MOV R0,#labimm ;78 2 NOP 1 - MOV R1,#labimm ;79 2 NOP 1 - MOV R2,#labimm ;7A 2 NOP 1 - MOV R3,#labimm ;7B 2 NOP 1 - MOV R4,#labimm ;7C 2 NOP 1 - MOV R5,#labimm ;7D 2 NOP 1 - MOV R6,#labimm ;7E 2 NOP 1 - MOV R7,#labimm ;7F 2 NOP 1 - MOV R0,lab2 ;a8 2 NOP 1 - MOV R1,lab2 ;a9 2 NOP 1 - MOV R2,lab2 ;aA 2 NOP 1 - MOV R3,lab2 ;aB 2 NOP 1 - MOV R4,lab2 ;aC 2 NOP 1 - MOV R5,lab2 ;aD 2 NOP 1 - MOV R6,lab2 ;aE 2 NOP 1 - MOV R7,lab2 ;aF 2 NOP 1 - MOV @R0,A ;f6 1 NOP 1 - MOV @R1,A ;f7 1 NOP 1 - MOV @R0,#labimm ;76 2 NOP 1 - MOV @R1,#labimm ;77 2 NOP 1 - MOV @R0,lab2 ;a6 2 NOP 1 - MOV @R1,lab2 ;a7 2 NOP 1 - MOV lab2,A ;f5 2 NOP 1 - MOV bit,C ;92 2 NOP 1 - MOV lab2,R0 ;88 2 NOP 1 - MOV lab2,R1 ;89 2 NOP 1 - MOV lab2,R2 ;8A 2 NOP 1 - MOV lab2,R3 ;8B 2 NOP 1 - MOV lab2,R4 ;8C 2 NOP 1 - MOV lab2,R5 ;8D 2 NOP 1 - MOV lab2,R6 ;8E 2 NOP 1 - MOV lab2,R7 ;8F 2 NOP 1 - MOV lab2,@R0 ;86 2 NOP 1 - MOV lab2,@R1 ;87 2 NOP 1 - MOV lab2,#labimm ;75 3 COMBINE 1 - MOV lab5,lab2 ;85 3 COMBINE 1 - - MOVC A,@A+DPTR ;93 1 NOP 1 - MOVC A,@A+PC ;83 1 NOP 1 - - MOVX A,@R0 ;e2 1 NOP 1 - MOVX A,@R1 ;e3 1 NOP 1 - MOVX A,@DPTR ;e0 1 NOP 1 - MOVX @R0,A ;f2 1 NOP 1 - MOVX @R1,A ;f3 1 NOP 1 - MOVX @DPTR,A ;f0 1 NOP 1 - - MUL AB ;a4 1 NOP 1 - - NOP ;00 1 NOP 1 - - ORL A,R0 ;48 1 NOP 1 - ORL A,R1 ;49 1 NOP 1 - ORL A,R2 ;4A 1 NOP 1 - ORL A,R3 ;4B 1 NOP 1 - ORL A,R4 ;4C 1 NOP 1 - ORL A,R5 ;4D 1 NOP 1 - ORL A,R6 ;4E 1 NOP 1 - ORL A,R7 ;4F 1 NOP 1 - ORL A,@R0 ;46 1 NOP 1 - ORL A,@R1 ;47 1 NOP 1 - ORL A,#labimm ;44 2 NOP 1 - ORL A,lab2 ;45 2 NOP 1 - ORL C,/bit ;a0 2 NOP 1 - ORL C,bit ;72 2 NOP 1 - ORL lab2,A ;42 2 NOP 1 - ORL lab2,#labimm ;43 3 COMBINE 1 - - POP lab2 ;d0 2 NOP 1 - PUSH lab2 ;c0 2 NOP 1 - - RET ;22 1 NOP 1 - RETI ;32 1 NOP 1 - - RL A ;23 1 NOP 1 - RLC A ;33 1 NOP 1 - RR A ;03 1 NOP 1 - RRC A ;13 1 NOP 1 - -jlab5: - SETB C ;d3 1 NOP 1 - SETB bit ;d2 2 NOP 1 - - SJMP jlab5 ;80 2 NOP 1 - - SUBB A,R0 ;98 1 NOP 1 - SUBB A,R1 ;99 1 NOP 1 - SUBB A,R2 ;9A 1 NOP 1 - SUBB A,R3 ;9B 1 NOP 1 - SUBB A,R4 ;9C 1 NOP 1 - SUBB A,R5 ;9D 1 NOP 1 - SUBB A,R6 ;9E 1 NOP 1 - SUBB A,R7 ;9F 1 NOP 1 - SUBB A,@R0 ;96 1 NOP 1 - SUBB A,@R1 ;97 1 NOP 1 - SUBB A,#labimm ;94 2 NOP 1 - SUBB A,lab2 ;95 2 NOP 1 - - SWAP A ;c4 1 NOP 1 - - XCH A,R0 ;c8 1 NOP 1 - XCH A,R1 ;c9 1 NOP 1 - XCH A,R2 ;cA 1 NOP 1 - XCH A,R3 ;cB 1 NOP 1 - XCH A,R4 ;cC 1 NOP 1 - XCH A,R5 ;cD 1 NOP 1 - XCH A,R6 ;cE 1 NOP 1 - XCH A,R7 ;cF 1 NOP 1 - XCH A,@R0 ;c6 1 NOP 1 - XCH A,@R1 ;c7 1 NOP 1 - XCH A,lab2 ;c5 2 NOP 1 - - XCHD A,@R0 ;d6 1 NOP 1 - XCHD A,@R1 ;d7 1 NOP 1 - - XRL A,R0 ;68 1 NOP 1 - XRL A,R1 ;69 1 NOP 1 - XRL A,R2 ;6A 1 NOP 1 - XRL A,R3 ;6B 1 NOP 1 - XRL A,R4 ;6C 1 NOP 1 - XRL A,R5 ;6D 1 NOP 1 - XRL A,R6 ;6E 1 NOP 1 - XRL A,R7 ;6F 1 NOP 1 - XRL A,@R0 ;66 1 NOP 1 - XRL A,@R1 ;67 1 NOP 1 - XRL A,#labimm ;64 2 NOP 1 - XRL A,lab2 ;65 2 NOP 1 - XRL lab2,A ;62 2 NOP 1 - XRL lab2,#labimm ;63 3 COMBINE 1 - - .end diff --git a/branches/s100/XSource/bin/TEST65.ASM b/branches/s100/XSource/bin/TEST65.ASM deleted file mode 100644 index d7efce4e..00000000 --- a/branches/s100/XSource/bin/TEST65.ASM +++ /dev/null @@ -1,298 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test65.asm 1.2 1997/11/29 13:07:53 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 6502 -; - - - -#define FLAG1 -#define TORG $1234 - .org $56 -zlabel .byte $12 - .word $1234 - .word $1234/3 - .word 1234h - .word %0101010 - .word 0101010b - .word @1234 - .word 1234o - .word 1234 - .word 1234d - .word 0d - .word 1d - .word 2d - .word 3d - .word 4d - .word 10d - .word 20d - .word 100d - .word * - .word $ - .word 3 * 7 - .word 3 + 7 - .word 3 - 7 - .word 73 % 7 - .word $1234 >> 4 - .word $1234 << 4 - .word 1 = 1 - .word 1 = 0 - .word 1 >= 1 - .word 1 >= 2 - .word 1 >= 0 - .word 1 <= 1 - .word 1 <= 2 - .word 1 <= 0 - .word 1 <= -1 - .word TORG - - .org $0234 -alabel - ADC #zlabel - ADC (zlabel,X) - ADC (zlabel),Y - ADC (zlabel) - ADC (alabel & $ff) ; suppress UNUSED DATA error - ADC zlabel,X - ADC zlabel,Y - ADC zlabel - ADC alabel - - AND #zlabel - AND (zlabel,X) - AND (zlabel),Y - AND (zlabel) - AND zlabel,X - AND zlabel,Y - AND zlabel - AND alabel - - ASL A - ASL zlabel,X - ASL zlabel -loop - BCC loop - BCS loop - BEQ loop - BNE loop - BMI loop - BPL loop - BVC loop - BVS loop - - BIT #zlabel - BIT zlabel,X - BIT zlabel - BIT alabel - - BRK - - CLC - CLD - CLI - CLV - - CMP #zlabel - CMP (zlabel,X) - CMP (zlabel),Y - CMP (zlabel) - CMP zlabel,X - CMP zlabel,Y - CMP zlabel - CMP alabel - - CPX #zlabel - CPX zlabel - CPX alabel - - CPY #zlabel - CPY zlabel - CPY alabel - - DEC A - DEC zlabel,X - DEC alabel,X - DEC zlabel - DEC alabel - - DEX - DEY - - EOR #zlabel - EOR (zlabel,X) - EOR (zlabel),Y - EOR (zlabel) - EOR zlabel,X - EOR zlabel,Y - EOR zlabel - EOR alabel - - INC A - INC zlabel,X - INC alabel,X - INC zlabel - INC alabel - - INX - INY - - JMP (zlabel,X) - JMP (zlabel) - JMP zlabel - - JSR zlabel - JSR alabel - - LDA #zlabel - LDA (zlabel,X) - LDA (zlabel),Y - LDA (zlabel) - LDA zlabel,X - LDA zlabel,Y - LDA zlabel - LDA alabel - - LDX #zlabel - LDX zlabel,Y - LDX zlabel - LDX alabel - - LDY #zlabel - LDY zlabel,X - LDY zlabel - LDY alabel - - LSR A - LSR zlabel,X - LSR zlabel - LSR alabel - - NOP - - ORA #zlabel - ORA (zlabel,X) - ORA (zlabel),Y - ORA (zlabel) - ORA zlabel,X - ORA zlabel,Y - ORA zlabel - ORA alabel - - PHA - PHP - PLA - PLP - - ROL A - ROL zlabel,X - ROL zlabel - ROL alabel - - ROR A - ROR zlabel,X - ROR alabel,X - ROR zlabel - ROR alabel - - RTI - RTS - - SBC #zlabel - SBC (zlabel,X) - SBC (zlabel),Y - SBC (zlabel) - SBC zlabel,X - SBC zlabel,Y - SBC zlabel - SBC alabel - - SEC - SED - SEI - - STA (zlabel,X) - STA (zlabel),Y - STA (zlabel) - STA zlabel,X - STA zlabel,Y - STA zlabel - STA alabel - - STX zlabel,Y - STX zlabel - STX alabel - - STY zlabel,X - STY zlabel - STY alabel - - TAX - TAY - TSX - TXA - TXS - TYA - - BRA loop2 -loop2 - BBR0 zlabel,loop2 - BBR1 zlabel,loop2 - BBR2 zlabel,loop2 - BBR3 zlabel,loop2 - BBR4 zlabel,loop2 - BBR5 zlabel,loop2 - BBR6 zlabel,loop2 - BBR7 zlabel,loop2 - - BBS0 zlabel,loop2 - BBS1 zlabel,loop2 - BBS2 zlabel,loop2 - BBS3 zlabel,loop2 - BBS4 zlabel,loop2 - BBS5 zlabel,loop2 - BBS6 zlabel,loop2 - BBS7 zlabel,loop2 - - MUL - - PHX - PHY - PLX - PLY - - RMB0 zlabel - RMB1 zlabel - RMB2 zlabel - RMB3 zlabel - RMB4 zlabel - RMB5 zlabel - RMB6 zlabel - RMB7 zlabel - - SMB0 zlabel - SMB1 zlabel - SMB2 zlabel - SMB3 zlabel - SMB4 zlabel - SMB5 zlabel - SMB6 zlabel - SMB7 zlabel - - - STZ zlabel,X - STZ zlabel - STZ alabel - - TRB zlabel - TSB zlabel - .end - - - - - - diff --git a/branches/s100/XSource/bin/TEST68.ASM b/branches/s100/XSource/bin/TEST68.ASM deleted file mode 100644 index 54ae1023..00000000 --- a/branches/s100/XSource/bin/TEST68.ASM +++ /dev/null @@ -1,422 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test68.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 6801/6803/68HC11 -; - - -data1 .equ $12 -data2 .equ $1234 - - ABA - ABX - - ADDA #data1 ;8B - ADDA data1,X ;AB - ADDA data1 ;9B - ADDA data2 ;BB - - ADDB #data1 ;CB - ADDB data1,X ;EB - ADDB data1 ;DB - ADDB data2 ;FB - - ADCA #data1 ;89 - ADCA data1,X ;A9 - ADCA data1 ;99 - ADCA data2 ;B9 - - ADCB #data1 ;C9 - ADCB data1,X ;E9 - ADCB data1 ;D9 - ADCB data2 ;F9 - - ADDD #data1 ;C3 - ADDD data1,X ;E3 - ADDD data1 ;D3 - ADDD data2 ;F3 - - ANDA #data1 ;84 - ANDA data1,X ;A4 - ANDA data1 ;94 - ANDA data2 ;B4 - - ANDB #data1 ;C4 - ANDB data1,X ;E4 - ANDB data1 ;D4 - ANDB data2 ;F4 - - ASL data1,X ;68 - ASL data1 ;78 - ASL data2 ;78 - ASLA ;48 - ASLB ;58 - ASLD ;05 - - ASR data1,X ; - ASR data1 ; - ASR data2 ; - ASRA ; - ASRB ; - -loop1: - BRA loop1 ;20 - BRN loop1 ;21 - BCC loop1 ;24 - BCS loop1 ;25 - BEQ loop1 ;27 - BGE loop1 ;2C - BGT loop1 ;2E - BHI loop1 ;22 - BHS loop1 ;24 - - BITA #data1 ;85 - BITA data1,X ;A5 - BITA data1 ;B5 - BITA data2 ;B5 - - BITB #data1 ;C5 - BITB data1,X ;E5 - BITB data1 ;F5 - BITB data2 ;F5 - - BLE loop1 ;2F - BLO loop1 ;25 - BLS loop1 ;23 - BLT loop1 ;2D - BMI loop1 ;2B - BNE loop1 ;26 - BVC loop1 ;28 - BVS loop1 ;29 - BPL loop1 ;2A - BSR loop1 ;8D - - CBA - CLC ;0C - CLI ;0E - CLR data1,X ;6F - CLR data1 ;7F - CLR data2 ;7F - CLRA ;4F - CLRB ;5F - CLV ;0A - - COM data1,X ;63 - COM data1 ;73 - COM data2 ;73 - COMA ;43 - COMB ;53 - - CPX #data1 ;8C - CPX data1,X ;AC - CPX data1 ;9C - CPX data2 ;BC - - CMPA #data1 ; - CMPA data1,X ; - CMPA data1 ; - CMPA data2 ; - - CMPB #data1 ; - CMPB data1,X ; - CMPB data1 ; - CMPB data2 ; - - DAA ;19 - - DEC data1,X - DEC data1 - DEC data2 - - DECA ;4A - DECB ;5A - DES ;34 - DEX ;09 - - EORA #data1 ; - EORA data1,X ; - EORA data1 ; - EORA data2 ; - - EORB #data1 ; - EORB data1,X ; - EORB data1 ; - EORB data2 ; - - INC data1,X - INC data1 - INC data2 - - INCA ;4C - INCB ;5C - INS ;31 - INX ;08 - - JMP data1,X ;63 - JMP data1 ;7E - JMP data2 ;7E - - JSR data1,X ;AD - JSR data1 ;9D - JSR data2 ;BD - - LDAA #data1 ;86 - LDAA data1,X ;A6 - LDAA data1 ;96 - LDAA data2 ;B6 - - LDAB #data1 ;C6 - LDAB data1,X ;E6 - LDAB data1 ;D6 - LDAB data2 ;F6 - - LDD #data1 ;CC - LDD data1,X ;EC - LDD data1 ;DC - LDD data2 ;FC - - LDS #data1 ;8E - LDS data1,X ;AE - LDS data1 ;9E - LDS data2 ;BE - - LDX #data1 ;CE - LDX data1,X ;EE - LDX data1 ;DE - LDX data2 ;FE - - LSLA ;48 - LSLB ;58 - LSLD ;05 - - LSRA ;44 - LSRB ;54 - LSRD ;04 - LSR data1,X ;64 - LSR data1 ;74 - LSR data2 ;74 - - MUL ;3D - - NEG data1,X ;60 - NEG data1 ;70 - NEG data2 ;70 - NEGA ;40 - NEGB ;50 - - NOP ;01 - - ORAA #data1 ;8A - ORAA data1,X ;AA - ORAA data1 ;BA - ORAA data2 ;9A - - ORAB #data1 ;CA - ORAB data1,X ;EA - ORAB data1 ;DA - ORAB data2 ;FA - - PSHA ;36 - PSHB ;37 - PSHX ;3C - - PULA ;32 - PULB ;33 - PULX ;38 - - ROL data1,X ;69 - ROL data1 ;79 - ROLA ;49 - ROLB ;59 - - ROR data1,X ;66 - ROR data1 ;76 - RORA ;46 - RORB ;56 - - RTI ;3B - RTS ;39 - - SBA ;10 - - SBCA #data1 ;82 - SBCA data1,X ;A2 - SBCA data1 ;92 - SBCA data2 ;B2 - - SBCB #data1 ;C2 - SBCB data1,X ;E2 - SBCB data1 ;D2 - SBCB data2 ;F2 - - SEI ;0F - SEV ;0B - SEC - - STS data1,X - STS data1 - STS data2 - - STAA data1,X ;A7 - STAA data1 ;97 - STAA data2 ;B7 - - STAB data1,X ;E7 - STAB data1 ;D7 - STAB data2 ;F7 - - STD data1,X ;ED - STD data1 ;DD - STD data2 ;FD - - STX data1,X ;EF - STX data1 ;FF - - SUBA #data1 ;80 - SUBA data1,X ;A0 - SUBA data1 ;90 - SUBA data2 ;B0 - - SUBB #data1 ;C0 - SUBB data1,X ;E0 - SUBB data1 ;D0 - SUBB data2 ;F0 - - SUBD #data1 ;83 - SUBD data1,X ;A3 - SUBD data1 ;93 - SUBD data2 ;B3 - - SWI ;3F - - TAB ;16 - TAP ;06 - TPA ;07 - TBA ;17 - - TST data1,X - TST data1 - TST data2 - - TSTA ;4D - TSTB ;5D - - TXS ;35 - TSX ;30 - - WAI ;3E - -; -; Test all the new 68HC11 instructions -; -bmsk .equ 12h -addr1 .equ 34h -addr2 .equ 5678h -imm .equ 55h - - ABY ;183A - ADCA addr1,Y ;18A9 - ADCB addr1,Y ;18E9 - ADDA addr1,Y ;18AB - ADDB addr1,Y ;18EB - ADDD addr1,Y ;18E3 - ANDA addr1,Y ;18A4 - ANDB addr1,Y ;18E4 - ASL addr1,Y ;1868 - ASR addr1,Y ;1867 -lab1 - BCLR addr1,Y,bmsk - BCLR addr1,X,bmsk - BCLR addr1,bmsk - - BITA addr1,Y ;18A5 - BITB addr1,Y ;18E5 - - BRCLR addr1,Y,bmsk,lab1 - BRCLR addr1,X,bmsk,lab1 - BRCLR addr1,bmsk,lab1 - BRCLR addr2,bmsk,lab1 - - BRSET addr1,Y,bmsk,lab1 - BRSET addr1,X,bmsk,lab1 - BRSET addr1,bmsk,lab1 - BRSET addr2,bmsk,lab1 - - BSET addr1,Y,bmsk - BSET addr1,X,bmsk - BSET addr1,bmsk - - CLR addr1,Y ;186F - CMPA addr1,Y ;18A1 - CMPB addr1,Y ;18E1 - COM addr1,Y ;1863 - CPD #imm ;1A83 - CPD addr1,X ;1AA3 - CPD addr1,Y ;CDA3 - CPD addr1 ;1AB3 - CPD addr2 ;1AB3 - CPX addr1,Y ;CDAC - CPY #imm ;188C - CPY addr1,Y ;18AC - CPY addr1,X ;1AAC - CPY addr1 ;18BC - CPY addr2 ;18BC - DEC addr1,Y ;186A - DEY ;1809 - EORA addr1,Y ;18A8 - EORB addr1,Y ;18E8 - FDIV ;03 - IDIV ;02 - INC addr1,Y ;186C - INY ;1808 - JMP addr1,Y ;186E - JSR addr1,Y ;18AD - LDAA addr1,Y ;18A6 - LDAB addr1,Y ;18E6 - LDD addr1,Y ;18EC - LDS addr1,Y ;18AE - LDX addr1,Y ;CDEE - LDY #imm ;18CE - LDY addr1,Y ;18EE - LDY addr1,X ;1AEE - LDY addr1 ;18FE - LDY addr2 ;18FE - LSL addr1,Y ;1868 - LSR addr1,Y ;1864 - NEG addr1,Y ;1860 - ORAA addr1,Y ;18AA - ORAB addr1,Y ;18EA - PSHY ;183C - PULY ;1838 - ROL addr1,Y ;1869 - ROR addr1,Y ;1866 - SBCA addr1,Y ;18A2 - SBCB addr1,Y ;18E2 - STAA addr1,Y ;18A7 - STAB addr1,Y ;18E7 - STD addr1,Y ;18ED - STS addr1,Y ;CDAF - STX addr1,Y ;CDEF - STY addr1,Y ;18EF - STY addr1,X ;1AEF - STY addr1 ;18FF - STY addr2 ;18FF - SUBA addr1,Y ;18A0 - SUBB addr1,Y ;18E0 - SUBD addr1,Y ;18A3 - TST addr1,Y ;186D -; TEST ; - TSY ;1830 2 NOP 4 - TYS ;1835 2 NOP 4 - XGDX ;8F 1 NOP 4 - XGDY ;188F 2 NOP 4 - - .end - - - - diff --git a/branches/s100/XSource/bin/TEST70.ASM b/branches/s100/XSource/bin/TEST70.ASM deleted file mode 100644 index f31223ed..00000000 --- a/branches/s100/XSource/bin/TEST70.ASM +++ /dev/null @@ -1,305 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test70.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: TMS7000 -; - - - -R0 .equ 0 -R1 .equ 1 -R2 .equ 2 -R3 .equ 3 -R12 .equ 12 -R13 .equ 13 -R7 .equ 7 -data1 .equ $34 -data2 .equ $1287 -table .equ $1234 -P7 .equ 7 - - .org $f000 -start: - ADC B,A - ADC %data1,A - ADC %data1,B - ADC %data1,R7 - ADC R12,A - ADC R13,B - ADC R12,R7 - - ADD B,A - ADD %data1,A - ADD %data1,B - ADD %data1,R7 - ADD R12,A - ADD R13,B - ADD R12,R7 - - AND B,A - AND %data1,A - AND %data1,B - AND %data1,R7 - AND R12,A - AND R13,B - AND R12,R7 - - ANDP A,R7 - ANDP B,R7 - ANDP %data1,R7 - - BTJO B,A,start - BTJO %data1,A,start - BTJO %data1,B,start - BTJO %data1,R7,start - BTJO R12,A,start - BTJO R13,B,start - BTJO R12,R7,start - -loop1 - BTJOP A,P7,loop1 - BTJOP B,P7,loop1 - BTJOP %data1,P7,loop1 - - BTJZ B,A,loop1 - BTJZ %data1,A,loop1 - BTJZ %data1,B,loop1 - BTJZ %data1,R7,loop1 - BTJZ R12,A,loop1 - BTJZ R12,B,loop1 - BTJZ R12,R7,loop1 - - BTJZP A,P7,loop1 - BTJZP B,P7,loop1 - BTJZP %data1,P7,loop1 - - BR @start(B) - BR @start[B] - BR @start - BR *R7 - - CALL @sub1(B) - CALL @sub1 - CALL *R7 - -sub1: CLR A - CLR B - CLR R12 - - CLRC - - CMP B,A - CMP %data1,A - CMP %data1,B - CMP %data1,R7 - CMP R12,A - CMP R12,B - CMP R12,R7 - - CMPA @R7(B) - CMPA @R7[B] - CMPA @R7 - CMPA *R7 - - DAC B,A - DAC %data1,A - DAC %data1,B - DAC %data1,R7 - DAC R12,A - DAC R12,B - DAC R12,R7 - - DEC A - DEC B - DEC R7 - - DECD A - DECD B - DECD R7 - - DINT - - DJNZ A,loop2 - DJNZ B,loop2 - DJNZ R12,loop2 - - DSB B,A - DSB %data1,A - DSB %data1,B - DSB %data1,R7 - DSB R12,A - DSB R12,B - DSB R12,R7 - - EINT - - IDLE - - INC A - INC B - INC R7 - - INV A - INV B - INV R7 -loop2: - JMP loop2 - - JC loop2 - JEQ loop2 - JGE loop2 - JGT loop2 - JHS loop2 - JL loop2 - JN loop2 - JNC loop2 - JNE loop2 - JNZ loop2 - JP loop2 - JPZ loop2 - JZ loop2 - - LDA @table(B) - LDA @table - LDA *R7 - - LDSP - - MOV A,B - MOV B,A - MOV A,R7 - MOV B,R7 - MOV %data1,A - MOV %data1,B - MOV %data1,R7 - MOV R12,A - MOV R12,B - MOV R12,R7 - - MOVD %data2,R7 - MOVD %data2[B],R7 - MOVD R12,R7 - - MOVP A,P7 - MOVP B,P7 - MOVP %data1,P7 - MOVP P7,A - MOVP P7,B - - MPY B,A - MPY %data1,A - MPY %data1,B - MPY %data1,R7 - MPY R12,A - MPY R12,B - MPY R12,R7 - - NOP - - OR B,A - OR %data1,A - OR %data1,B - OR %data1,R7 - OR R12,A - OR R12,B - OR R12,R7 - - ORP A,P7 - ORP B,P7 - ORP %data1,P7 - - POP A - POP B - POP R7 - - POPST - POP ST - - PUSH A - PUSH B - PUSH R7 - - PUSHST - PUSH ST - - RETI - - RETS - - RL A - RL B - RL R7 - - RLC A - RLC B - RLC R7 - - RR A - RR B - RR R7 - - RRC A - RRC B - RRC R7 - - SBB B,A - SBB %data1,A - SBB %data1,B - SBB %data1,R7 - SBB R12,A - SBB R12,B - SBB R12,R7 - - SETC - - STA @table(B) - STA @table - STA *R7 - - STSP - - SUB B,A - SUB %data1,A - SUB %data1,B - SUB %data1,R7 - SUB R12,A - SUB R12,B - SUB R12,R7 - - SWAP A - SWAP B - SWAP R7 - - TRAP 0 - TRAP 1 - TRAP 6 - TRAP 12 - TRAP 23 - - TST A - TSTA - TST B - TSTB - - XCHB A - XCHB R7 - - XOR B,A - XOR %data1,A - XOR %data1,B - XOR %data1,R7 - XOR R12,A - XOR R12,B - XOR R12,R7 - - XORP A,P7 - XORP B,P7 - XORP %data1,P7 - - - .end - diff --git a/branches/s100/XSource/bin/TEST85.ASM b/branches/s100/XSource/bin/TEST85.ASM deleted file mode 100644 index f21f9c2f..00000000 --- a/branches/s100/XSource/bin/TEST85.ASM +++ /dev/null @@ -1,294 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test85.asm 1.1 1993/08/02 01:24:21 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8080/8085 -; - - - -idata16 .equ 1234h -idata8 .equ 12h -port .equ 34h -addr16 .equ 5678h - - .org 1000h - -start: - nop - lxi b,idata16 - stax b - inx b - inr b - dcr b - mvi b,idata8 - rlc - - dad b - ldax b - dcx b - inr c - dcr c - mvi c,idata8 - rrc - -; --- ; 10 - lxi d,idata16 - stax d - inx d - inr d - dcr d - mvi d,idata8 - ral -; --- - dad d - ldax d - dcx d - inr e - dcr e - mvi e,idata8 - rar - - rim ; 20 - lxi h,idata16 - shld addr16 - inx h - inr h - dcr h - mvi h,idata8 - daa -; --- - dad h - lhld addr16 - dcx h - inr l - dcr l - mvi l,idata8 - cma - - sim ; 30 - lxi sp,idata16 - sta addr16 - inx sp - inr m - dcr m - mvi m,idata8 - stc -; --- - dad sp - lda addr16 - dcx sp - inr a - dcr a - mvi a,idata8 - cmc - - mov b,b ; 40 - mov b,c - mov b,d - mov b,e - mov b,h - mov b,l - mov b,m - mov b,a - mov c,b - mov c,c - mov c,d - mov c,e - mov c,h - mov c,l - mov c,m - mov c,a - - mov d,b ; 50 - mov d,c - mov d,d - mov d,e - mov d,h - mov d,l - mov d,m - mov d,a - mov e,b - mov e,c - mov e,d - mov e,e - mov e,h - mov e,l - mov e,m - mov e,a - - mov h,b ; 60 - mov h,c - mov h,d - mov h,e - mov h,h - mov h,l - mov h,m - mov h,a - mov l,b - mov l,c - mov l,d - mov l,e - mov l,h - mov l,l - mov l,m - mov l,a - - mov m,b ; 70 - mov m,c - mov m,d - mov m,e - mov m,h - mov m,l - hlt - mov m,a - mov a,b - mov a,c - mov a,d - mov a,e - mov a,h - mov a,l - mov a,m - mov a,a - - add b ; 80 - add c - add d - add e - add h - add l - add m - add a - adc b ; 88 - adc c - adc d - adc e - adc h - adc l - adc m - adc a - - sub b ; 90 - sub c - sub d - sub e - sub h - sub l - sub m - sub a - sbb b ; 98 - sbb c - sbb d - sbb e - sbb h - sbb l - sbb m - sbb a - - ana b ; a0 - ana c - ana d - ana e - ana h - ana l - ana m - ana a - xra b ; a8 - xra c - xra d - xra e - xra h - xra l - xra m - xra a - - ora b ; b0 - ora c - ora d - ora e - ora h - ora l - ora m - ora a - cmp b ; b8 - cmp c - cmp d - cmp e - cmp h - cmp l - cmp m - cmp a - - rnz ; c0 - pop b - jnz start - jmp start - cnz start - push b - adi idata8 - rst 0 - rz - ret - jz start -; --- - cz start - call start - aci idata8 - rst 1 - - rnc ; d0 - pop d - jnc start - out port - cnc start - push d - sui idata8 - rst 2 - rc -; --- - jc start - in port - cc start -; --- - sbi idata8 - rst 3 - - rpo ; e0 - pop h - jpo start - xthl - cpo start - push h - ani idata8 - rst 4 - rpe - pchl - jpe start - xchg - cpe start -; --- - xri idata8 - rst 5 - - rp ; f0 - pop psw - jp start - di - cp start - push psw - ori idata8 - rst 6 - rm - sphl - jm start - ei - cm start -; --- - cpi idata8 - rst 7 - - .END - diff --git a/branches/s100/XSource/bin/TEST96.ASM b/branches/s100/XSource/bin/TEST96.ASM deleted file mode 100644 index be74931e..00000000 --- a/branches/s100/XSource/bin/TEST96.ASM +++ /dev/null @@ -1,887 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: test96.asm 1.1 1997/11/23 15:51:20 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: 8096/8XC196KC -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; - -; CPU "8096.TBL" ; CPU TABLE -; HOF "INT8" ; HEX FORMAT - -#define EQU .equ -#define END .end -#define ORG .org -#define DWL .dw -#define IF #if -#define ENDI #endif - -wreg: EQU 12h ; word register even address -wreg1: EQU 22h ; word register even address -wreg2: EQU 32h ; word register even address -wreg3: EQU 42h ; word register even address -lreg1: EQU 44h ; long register (32 bit) -lreg2: EQU 48h ; long register (32 bit) -breg: EQU wreg+1 ; low byte of reg. where odd is allowed -breg1: EQU wreg+3 ; low byte of reg. where odd is allowed -breg2: EQU wreg+5 ; low byte of reg. where odd is allowed -breg3: EQU wreg+7 ; low byte of reg. where odd is allowed - -imm8: EQU 88H -imm16: EQU 4321H - -addr8: EQU 12H -addr16: EQU 3456H - -ishort: EQU 12H -ishrt: EQU 12H -ilong: EQU 4567H - -count: EQU 7H - - ORG 7418h - -dtable: DWL $1234 - DWL $5678 - DWL $1234 - - -;------------------------------------- -; ADD - add wreg1,#imm8 - add wreg1,#imm16 - add wreg1,wreg2 - add wreg1,addr16 - add wreg1,[wreg2] - add wreg1,[wreg2]+ - add wreg1,addr8[wreg2] - add wreg1,addr16[wreg2] - - add wreg1,wreg2,#imm8 - add wreg1,wreg2,#imm16 - add wreg1,wreg2,wreg3 - add wreg1,wreg2,addr16 - add wreg1,wreg2,[wreg3] - add wreg1,wreg2,[wreg3]+ - add wreg1,wreg2,addr8[wreg3] - add wreg1,wreg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; ADDB - addb breg1,#imm8 - addb breg1,breg2 - addb breg1,addr16 - addb breg1,[wreg2] - addb breg1,[wreg2]+ - addb breg1,addr8[wreg2] - addb breg1,addr16[wreg2] - - addb breg1,breg2,#imm8 - addb breg1,breg2,breg3 - addb breg1,breg2,addr16 - addb breg1,breg2,[wreg3] - addb breg1,breg2,[wreg3]+ - addb breg1,breg2,addr8[wreg3] - addb breg1,breg2,addr16[wreg3] -;------------------------------------- - - -;------------------------------------- -; ADDB - addc wreg1,#imm8 - addc wreg1,#imm16 - addc wreg1,wreg2 - addc wreg1,addr16 - addc wreg1,[wreg2] - addc wreg1,[wreg2]+ - addc wreg1,addr8[wreg2] - addc wreg1,addr16[wreg2] - - ; No three arg form for addc -;------------------------------------- - -;------------------------------------- -; ADDCB - addcb breg1,#imm8 - addcb breg1,breg2 - addcb breg1,addr16 - addcb breg1,[wreg2] - addcb breg1,[wreg2]+ - addcb breg1,addr8[wreg2] - addcb breg1,addr16[wreg2] - - ; No three arg form for addcb -;------------------------------------- - -;------------------------------------- -; AND - and wreg1,#imm8 - and wreg1,#imm16 - and wreg1,wreg2 - and wreg1,addr16 - and wreg1,[wreg2] - and wreg1,[wreg2]+ - and wreg1,addr8[wreg2] - and wreg1,addr16[wreg2] - - and wreg1,wreg2,#imm8 - and wreg1,wreg2,#imm16 - and wreg1,wreg2,wreg3 - and wreg1,wreg2,addr16 - and wreg1,wreg2,[wreg3] - and wreg1,wreg2,[wreg3]+ - and wreg1,wreg2,addr8[wreg3] - and wreg1,wreg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; ANDB - andb breg1,#imm8 - andb breg1,breg2 - andb breg1,addr16 - andb breg1,[wreg2] - andb breg1,[wreg2]+ - andb breg1,addr8[wreg2] - andb breg1,addr16[wreg2] - - andb breg1,breg2,#imm8 - andb breg1,breg2,breg3 - andb breg1,breg2,addr16 - andb breg1,breg2,[wreg3] - andb breg1,breg2,[wreg3]+ - andb breg1,breg2,addr8[wreg3] - andb breg1,breg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; BMOV - bmov lreg1,wreg1 - bmov lreg1,wreg2 -;------------------------------------- - -;------------------------------------- -; BR - br [wreg1] -;------------------------------------- - -;------------------------------------- -; MISC CLR - clr wreg1 - clrb breg1 - clrc - clrvt -;------------------------------------- - - - -;------------------------------------- -; CMP - cmp wreg1,#imm8 - cmp wreg1,#imm16 - cmp wreg1,wreg2 - cmp wreg1,addr16 - cmp wreg1,[wreg2] - cmp wreg1,[wreg2]+ - cmp wreg1,addr8[wreg2] - cmp wreg1,addr16[wreg2] - - ; No three arg form for cmp -;------------------------------------- - -;------------------------------------- -; CMPB - cmpb breg1,#imm8 - cmpb breg1,breg2 - cmpb breg1,addr16 - cmpb breg1,[wreg2] - cmpb breg1,[wreg2]+ - cmpb breg1,addr8[wreg2] - cmpb breg1,addr16[wreg2] - - ; No three arg form for cmpb -;------------------------------------- - -;------------------------------------- -; CMPL - cmpl lreg1,lreg2 -;------------------------------------- - -;------------------------------------- -; DEC - dec wreg1 - decb breg1 -;------------------------------------- - -;------------------------------------- -; DEC - di -;------------------------------------- - - -;------------------------------------- -; DIV - div lreg1,#imm8 - div lreg1,#imm16 - div lreg1,wreg2 - div lreg1,addr16 - div lreg1,[wreg2] - div lreg1,[wreg2]+ - div lreg1,addr8[wreg2] - div lreg1,addr16[wreg2] - - ; No three arg form for div -;------------------------------------- - -;------------------------------------- -; DIVB - divb wreg1,#imm8 - divb wreg1,breg2 - divb wreg1,addr16 - divb wreg1,[wreg2] - divb wreg1,[wreg2]+ - divb wreg1,addr8[wreg2] - divb wreg1,addr16[wreg2] - - ; No three arg form for divb -;------------------------------------- - - -;------------------------------------- -; DIVU - divu lreg1,#imm8 - divu lreg1,#imm16 - divu lreg1,wreg2 - divu lreg1,addr16 - divu lreg1,[wreg2] - divu lreg1,[wreg2]+ - divu lreg1,addr8[wreg2] - divu lreg1,addr16[wreg2] - - ; No three arg form for divu -;------------------------------------- - -;------------------------------------- -; DIVUB - divub wreg1,#imm8 - divub wreg1,breg2 - divub wreg1,addr16 - divub wreg1,[wreg2] - divub wreg1,[wreg2]+ - divub wreg1,addr8[wreg2] - divub wreg1,addr16[wreg2] - - ; No three arg form for divub -;------------------------------------- - - -;------------------------------------- -; DJNZ -rtest1: ;backward reference - djnz breg1,rtest1 - djnz breg1,rtest1 - djnz breg1,rtest2 - djnz breg1,rtest2 -rtest2: ;forward reference -;------------------------------------- - -;------------------------------------- -; DJNZW - djnzw wreg1,rtest1 - djnzw wreg1,rtest1 - djnzw wreg1,rtest3 - djnzw wreg1,rtest3 -rtest3: ;forward reference -;------------------------------------- - -;------------------------------------- -; DPTS - dpts -;------------------------------------- - -;------------------------------------- -; EI - ei -;------------------------------------- - -;------------------------------------- -; EPTS - epts -;------------------------------------- - -;------------------------------------- -; EXT & EXTB - ext lreg1 - ext lreg2 - extb wreg1 - extb wreg2 -;------------------------------------- - -;------------------------------------- -; IDLPD - idlpd #1 - idlpd #2 -;------------------------------------- - -;------------------------------------- -; INC & INCB - inc wreg1 - inc wreg2 - incb breg1 - incb breg2 -;------------------------------------- - - -FLAG: EQU 3 -;------------------------------------- -; JBC - jbc breg1,0,rtest1 - jbc breg1,1,rtest1 - jbc breg1,2,rtest1 - jbc breg1,3,rtest1 - jbc breg1,4,rtest1 - jbc breg1,5,rtest1 - jbc breg1,6,rtest1 - jbc breg1,7,rtest1 -;------------------------------------- - -;------------------------------------- -; JBS - jbs breg1,0,rtest1 - jbs breg1,1,rtest1 - jbs breg1,2,rtest1 - jbs breg1,3,rtest1 - jbs breg1,4,rtest1 - jbs breg1,5,rtest1 - jbs breg1,6,rtest1 - jbs breg1,7,rtest1 -;------------------------------------- - -;------------------------------------- -; MISC Jump backward - jc rtest1 - je rtest1 - jge rtest1 - jgt rtest1 - jh rtest1 - jle rtest1 - jlt rtest1 - jnc rtest1 - jne rtest1 - jnh rtest1 - jnst rtest1 - jnv rtest1 - jnvt rtest1 - jst rtest1 - jv rtest1 - jvt rtest1 -;------------------------------------- - -;------------------------------------- -; MISC Jump forward - jc rtest4 - je rtest4 - jge rtest4 - jgt rtest4 - jh rtest4 - jle rtest4 - jlt rtest4 - jnc rtest4 - jne rtest4 - jnh rtest4 - jnst rtest4 - jnv rtest4 - jnvt rtest4 - jst rtest4 - jv rtest4 -rtest4: jvt rtest4 -;------------------------------------- - -;------------------------------------- -; LCALL - lcall rtest1 - lcall rtest2 - lcall rtest4 - lcall addr8 - lcall addr16 -;------------------------------------- - - -;------------------------------------- -; LD - ld wreg1,#imm8 - ld wreg1,#imm16 - ld wreg1,wreg2 - ld wreg1,addr16 - ld wreg1,[wreg2] - ld wreg1,[wreg2]+ - ld wreg1,addr8[wreg2] - ld wreg1,addr16[wreg2] - - ; No three arg form for ld -;------------------------------------- - -;------------------------------------- -; LDB - ldb breg1,#imm8 - ldb breg1,breg2 - ldb breg1,addr16 - ldb breg1,[wreg2] - ldb breg1,[wreg2]+ - ldb breg1,addr8[wreg2] - ldb breg1,addr16[wreg2] - - ; No three arg form for ldb -;------------------------------------- - -;------------------------------------- -; LDBSE - ldbse wreg1,#imm8 - ldbse wreg1,breg2 - ldbse wreg1,addr16 - ldbse wreg1,[wreg2] - ldbse wreg1,[wreg2]+ - ldbse wreg1,addr8[wreg2] - ldbse wreg1,addr16[wreg2] - - ; No three arg form for ldbse -;------------------------------------- - -;------------------------------------- -; LDBZE - ldbze wreg1,#imm8 - ldbze wreg1,breg2 - ldbze wreg1,addr16 - ldbze wreg1,[wreg2] - ldbze wreg1,[wreg2]+ - ldbze wreg1,addr8[wreg2] - ldbze wreg1,addr16[wreg2] - - ; No three arg form for ldbze -;------------------------------------- - -;------------------------------------- -; LJMP - ljmp addr8 - ljmp addr16 -;------------------------------------- - - -;------------------------------------- -; MUL - mul lreg1,#imm8 - mul lreg1,#imm16 - mul lreg1,wreg2 - mul lreg1,addr16 - mul lreg1,[wreg2] - mul lreg1,[wreg2]+ - mul lreg1,addr8[wreg2] - mul lreg1,addr16[wreg2] - - mul lreg1,wreg2,#imm8 - mul lreg1,wreg2,#imm16 - mul lreg1,wreg2,wreg3 - mul lreg1,wreg2,addr16 - mul lreg1,wreg2,[wreg3] - mul lreg1,wreg2,[wreg3]+ - mul lreg1,wreg2,addr8[wreg3] - mul lreg1,wreg2,addr16[wreg3] - -;------------------------------------- - - -;------------------------------------- -; MULB - mulb wreg1,#imm8 - mulb wreg1,breg2 - mulb wreg1,addr16 - mulb wreg1,[wreg2] - mulb wreg1,[wreg2]+ - mulb wreg1,addr8[wreg2] - mulb wreg1,addr16[wreg2] - - mulb wreg1,breg2,#imm8 - mulb wreg1,breg2,breg3 - mulb wreg1,breg2,addr16 - mulb wreg1,breg2,[wreg3] - mulb wreg1,breg2,[wreg3]+ - mulb wreg1,breg2,addr8[wreg3] - mulb wreg1,breg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; MULU - mulu lreg1,#imm8 - mulu lreg1,#imm16 - mulu lreg1,wreg2 - mulu lreg1,addr16 - mulu lreg1,[wreg2] - mulu lreg1,[wreg2]+ - mulu lreg1,addr8[wreg2] - mulu lreg1,addr16[wreg2] - - mulu lreg1,wreg2,#imm8 - mulu lreg1,wreg2,#imm16 - mulu lreg1,wreg2,wreg3 - mulu lreg1,wreg2,addr16 - mulu lreg1,wreg2,[wreg3] - mulu lreg1,wreg2,[wreg3]+ - mulu lreg1,wreg2,addr8[wreg3] - mulu lreg1,wreg2,addr16[wreg3] - -;------------------------------------- - - -;------------------------------------- -; MULUB - mulub wreg1,#imm8 - mulub wreg1,breg2 - mulub wreg1,addr16 - mulub wreg1,[wreg2] - mulub wreg1,[wreg2]+ - mulub wreg1,addr8[wreg2] - mulub wreg1,addr16[wreg2] - - mulub wreg1,breg2,#imm8 - mulub wreg1,breg2,breg3 - mulub wreg1,breg2,addr16 - mulub wreg1,breg2,[wreg3] - mulub wreg1,breg2,[wreg3]+ - mulub wreg1,breg2,addr8[wreg3] - mulub wreg1,breg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; NEG & NEGB - neg wreg1 - negb breg1 -;------------------------------------- - -;------------------------------------- -; NOP - nop -;------------------------------------- - -;------------------------------------- -; NORML - norml lreg1,breg1 -;------------------------------------- - -;------------------------------------- -; NOT & NOTB - not wreg1 - notb breg1 -;------------------------------------- - - -;------------------------------------- -; OR - or wreg1,#imm8 - or wreg1,#imm16 - or wreg1,wreg2 - or wreg1,addr16 - or wreg1,[wreg2] - or wreg1,[wreg2]+ - or wreg1,addr8[wreg2] - or wreg1,addr16[wreg2] - - ; No three arg form for or -;------------------------------------- - -;------------------------------------- -; ORB - orb breg1,#imm8 - orb breg1,breg2 - orb breg1,addr16 - orb breg1,[wreg2] - orb breg1,[wreg2]+ - orb breg1,addr8[wreg2] - orb breg1,addr16[wreg2] - - ; No three arg form for orb -;------------------------------------- - - -;------------------------------------- -; POP - pop wreg1 - pop [wreg1] - pop [wreg1]+ - pop addr8[wreg1] - pop addr16[wreg1] - - popa - popf -;------------------------------------- - -;------------------------------------- -; PUSH - push wreg1 - push [wreg1] - push [wreg1]+ - push addr8[wreg1] - push addr16[wreg1] - - pusha - pushf -;------------------------------------- - - -;------------------------------------- -; RET - return - ret -;------------------------------------- - -;------------------------------------- -; RST - reset - rst -;------------------------------------- - -;------------------------------------- -; SCALL - short call -scall1: -scall2: EQU scall1-1015 - scall scall1 - scall scall1 - scall scall2 - scall scall2 - scall scall3 - scall scall4 -scall3: -scall4: EQU scall3+1020 -;------------------------------------- - -;------------------------------------- -; SETC - set carry - setc -;------------------------------------- - -;------------------------------------- -; shl - shift word left - shl wreg1,#count - shl wreg2,breg1 -;------------------------------------- - -;------------------------------------- -; shlb - shift byte left - shlb breg1,#count - shlb breg2,breg1 -;------------------------------------- - -;------------------------------------- -; shll - shift long word left - shll lreg1,#count - shll lreg1,breg1 -;------------------------------------- - -;------------------------------------- -; shr - logical shift word right - shr wreg1,#count - shr wreg2,breg1 -;------------------------------------- - -;------------------------------------- -; shra - arithmetic shift word right - shra wreg1,#count - shra wreg2,breg1 -;------------------------------------- - -;------------------------------------- -; shrab - arithmetic shift byte right - shrab breg1,#count - shrab breg2,breg1 -;------------------------------------- - -;------------------------------------- -; shral - arithmetic shift long word right - shral lreg1,#count - shral lreg1,breg1 -;------------------------------------- - -;------------------------------------- -; shrb - logical shift byte right - shrb breg1,#count - shrb breg2,breg1 -;------------------------------------- - -;------------------------------------- -; shrl - logical shift long word right - shrl lreg1,#count - shrl lreg1,breg1 -;------------------------------------- - - -;------------------------------------- -; SJMP - short jump -sjump1: -sjump2: EQU sjump1-1015 - sjmp sjump1 - sjmp sjump1 - sjmp sjump2 - sjmp sjump2 - sjmp sjump3 - sjmp sjump4 -sjump3: -sjump4: EQU sjump3+1020 -;------------------------------------- - -;------------------------------------- -; skip - two byte nop - skip breg1 -;------------------------------------- - - -;------------------------------------- -; ST - store word - st wreg1,wreg2 - st wreg1,addr16 - st wreg1,[wreg2] - st wreg1,[wreg2]+ - st wreg1,addr8[wreg2] - st wreg1,addr16[wreg2] - - ; No three arg form for st; No immediate -;------------------------------------- - -;------------------------------------- -; STB - store byte - stb breg1,breg2 - stb breg1,addr16 - stb breg1,[wreg2] - stb breg1,[wreg2]+ - stb breg1,addr8[wreg2] - stb breg1,addr16[wreg2] - - ; No three arg form for stb; No immediate -;------------------------------------- - - -;------------------------------------- -; SUB - subtract word - sub wreg1,#imm8 - sub wreg1,#imm16 - sub wreg1,wreg2 - sub wreg1,addr16 - sub wreg1,[wreg2] - sub wreg1,[wreg2]+ - sub wreg1,addr8[wreg2] - sub wreg1,addr16[wreg2] - - sub wreg1,wreg2,#imm8 - sub wreg1,wreg2,#imm16 - sub wreg1,wreg2,wreg3 - sub wreg1,wreg2,addr16 - sub wreg1,wreg2,[wreg3] - sub wreg1,wreg2,[wreg3]+ - sub wreg1,wreg2,addr8[wreg3] - sub wreg1,wreg2,addr16[wreg3] -;------------------------------------- - -;------------------------------------- -; SUBB - subtract byte - subb breg1,#imm8 - subb breg1,breg2 - subb breg1,addr16 - subb breg1,[wreg2] - subb breg1,[wreg2]+ - subb breg1,addr8[wreg2] - subb breg1,addr16[wreg2] - - subb breg1,breg2,#imm8 - subb breg1,breg2,breg3 - subb breg1,breg2,addr16 - subb breg1,breg2,[wreg3] - subb breg1,breg2,[wreg3]+ - subb breg1,breg2,addr8[wreg3] - subb breg1,breg2,addr16[wreg3] -;------------------------------------- - - -;------------------------------------- -; SUBC - subtract word with carry - subc wreg1,#imm8 - subc wreg1,#imm16 - subc wreg1,wreg2 - subc wreg1,addr16 - subc wreg1,[wreg2] - subc wreg1,[wreg2]+ - subc wreg1,addr8[wreg2] - subc wreg1,addr16[wreg2] - - ; No three arg form for subc -;------------------------------------- - -;------------------------------------- -; SUBCB - subtract byte with carry - subcb breg1,#imm8 - subcb breg1,breg2 - subcb breg1,addr16 - subcb breg1,[wreg2] - subcb breg1,[wreg2]+ - subcb breg1,addr8[wreg2] - subcb breg1,addr16[wreg2] - - ; No three arg form for subcb -;------------------------------------- - - -;------------------------------------- -; tijmp - table indirect jump - tijmp wreg1,[wreg2],#imm8 - tijmp wreg2,[wreg1],#imm8 - tijmp wreg3,[wreg2],#13 -;------------------------------------- - -;------------------------------------- -; TRAP - software trap - trap -;------------------------------------- - -;------------------------------------- -; XCH - exchange word - xch wreg1,wreg2 - xch wreg1,addr16 - xch wreg1,addr8[wreg2] - xch wreg1,addr16[wreg2] -;------------------------------------- - -;------------------------------------- -; XCHB - exchange byte - xchb breg1,breg2 - xchb breg1,addr16 - xchb breg1,addr8[wreg2] - xchb breg1,addr16[wreg2] -;------------------------------------- - - -;------------------------------------- -; XOR - xor wreg1,#imm8 - xor wreg1,#imm16 - xor wreg1,wreg2 - xor wreg1,addr16 - xor wreg1,[wreg2] - xor wreg1,[wreg2]+ - xor wreg1,addr8[wreg2] - xor wreg1,addr16[wreg2] - - ; No three arg form for xor -;------------------------------------- - -;------------------------------------- -; XORB - xorb breg1,#imm8 - xorb breg1,breg2 - xorb breg1,addr16 - xorb breg1,[wreg2] - xorb breg1,[wreg2]+ - xorb breg1,addr8[wreg2] - xorb breg1,addr16[wreg2] - - ; No three arg form for xorb -;------------------------------------- - - END diff --git a/branches/s100/XSource/bin/TESTTABS.BAT b/branches/s100/XSource/bin/TESTTABS.BAT deleted file mode 100644 index 1c00a89e..00000000 --- a/branches/s100/XSource/bin/TESTTABS.BAT +++ /dev/null @@ -1,18 +0,0 @@ -rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -rem $Id: testtabs.bat 1.3 1998/02/25 12:27:04 toma Exp $ -rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -rem Run TASM on all the table test files. Those that have -rem extended instuctions use the -x option. - -tasm -48 -x test48.asm -tasm -65 -x test65.asm -tasm -51 test51.asm -tasm -85 test85.asm -tasm -80 -x testz80.asm -tasm -05 -x test05.asm -tasm -3210 test3210.asm -tasm -3225 test3225.asm -tasm -68 -x test68.asm -tasm -70 test70.asm -tasm -96 -x test96.asm - diff --git a/branches/s100/XSource/bin/TESTTABS.SH b/branches/s100/XSource/bin/TESTTABS.SH deleted file mode 100644 index be0ab2ca..00000000 --- a/branches/s100/XSource/bin/TESTTABS.SH +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -#rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -#rem $Id: testtabs.bat 1.3 1998/02/25 12:27:04 toma Exp $ -#rem mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm -#rem Run TASM on all the table test files. Those that have -#rem extended instuctions use the -x option. - -./TASM -48 -x TEST48.ASM -./TASM -65 -x TEST65.ASM -./TASM -51 TEST51.ASM -./TASM -85 TEST85.ASM -./TASM -80 -x TESTz80.ASM -./TASM -05 -x TEST05.ASM -./TASM -3210 TEST3210.ASM -./TASM -3225 TEST3225.ASM -./TASM -68 -x TEST68.ASM -./TASM -70 TEST70.ASM -./TASM -96 -x TEST96.ASM - diff --git a/branches/s100/XSource/bin/TESTZ80.ASM b/branches/s100/XSource/bin/TESTZ80.ASM deleted file mode 100644 index a4437f23..00000000 --- a/branches/s100/XSource/bin/TESTZ80.ASM +++ /dev/null @@ -1,831 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; $Id: testz80.asm 1.4 1998/02/25 12:18:20 toma Exp $ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TASM test file -; Test all instructions and addressing modes. -; Processor: Z80 -; -; SEPT. 16,1987 -; CARL A. WALL -; VE3APY -; -; - -#define equ .equ -#define end .end - -n: equ 20h -nn: equ 0584h -dddd: equ 07h -addr16: equ $1234 -port: equ 3 -imm8: equ 56h ;immediate data (8 bits) -offset: equ 7 -offset_neg: equ -7 - -; try a few cases that have two expressions in the args and -; one is inside (). - LD (IX+offset),n+1+4+8-9 - LD (IX+offset+5),n-1 - LD (IX+dddd),n - LD (IX+offset),n - LD (IX+offset),n - -; Try all possible instructions - - ADC A,(HL) - ADC A,(IX+offset) - ADC A,(IX+offset_neg) - ADC A,(IY+offset) - ADC A,(IY+offset_neg) - ADC A,A - ADC A,B - ADC A,C - ADC A,D - ADC A,E - ADC A,H - ADC A,L - ADC A,n - ADC HL,BC - ADC HL,DE - ADC HL,HL - ADC HL,SP - - ADD A,(HL) - ADD A,(IX+offset) - ADD A,(IY+offset) - ADD A,A - ADD A,B - ADD A,C - ADD A,D - ADD A,E - ADD A,H - ADD A,L - ADD A,n - ADD HL,BC - ADD HL,DE - ADD HL,HL - ADD HL,SP - ADD IX,BC - ADD IX,DE - ADD IX,IX - ADD IX,SP - ADD IY,BC - ADD IY,DE - ADD IY,IY - ADD IY,SP - - AND (HL) - AND (IX+offset) - AND (IY+offset) - AND A - AND B - AND C - AND D - AND E - AND H - AND L - AND n - - BIT 0,(HL) - BIT 0,(IX+offset) - BIT 0,(IY+offset) - BIT 0,A - BIT 0,B - BIT 0,C - BIT 0,D - BIT 0,E - BIT 0,H - BIT 0,L - - BIT 1,(HL) - BIT 1,(IX+offset) - BIT 1,(IY+offset) - BIT 1,A - BIT 1,B - BIT 1,C - BIT 1,D - BIT 1,E - BIT 1,H - BIT 1,L - - BIT 2,(HL) - BIT 2,(IX+offset) - BIT 2,(IY+offset) - BIT 2,A - BIT 2,B - BIT 2,C - BIT 2,D - BIT 2,E - BIT 2,H - BIT 2,L - - BIT 3,(HL) - BIT 3,(IX+offset) - BIT 3,(IY+offset) - BIT 3,A - BIT 3,B - BIT 3,C - BIT 3,D - BIT 3,E - BIT 3,H - BIT 3,L - - BIT 4,(HL) - BIT 4,(IX+offset) - BIT 4,(IY+offset) - BIT 4,A - BIT 4,B - BIT 4,C - BIT 4,D - BIT 4,E - BIT 4,H - BIT 4,L - - BIT 5,(HL) - BIT 5,(IX+offset) - BIT 5,(IY+offset) - BIT 5,A - BIT 5,B - BIT 5,C - BIT 5,D - BIT 5,E - BIT 5,H - BIT 5,L - - BIT 6,(HL) - BIT 6,(IX+offset) - BIT 6,(IY+offset) - BIT 6,A - BIT 6,B - BIT 6,C - BIT 6,D - BIT 6,E - BIT 6,H - BIT 6,L - - BIT 7,(HL) - BIT 7,(IX+offset) - BIT 7,(IY+offset) - BIT 7,A - BIT 7,B - BIT 7,C - BIT 7,D - BIT 7,E - BIT 7,H - BIT 7,L - - CALL C,addr16 - CALL M,addr16 - CALL NC,addr16 - CALL NZ,addr16 - CALL P,addr16 - CALL PE,addr16 - CALL PO,addr16 - CALL Z,addr16 - CALL addr16 - - CCF - - CP (HL) - CP (IX+offset) - CP (IY+offset) - CP A - CP B - CP C - CP D - CP E - CP H - CP L - CP imm8 - CPD - CPDR - CPIR - CPI - CPL - - DAA - - DEC (HL) - DEC (IX+offset) - DEC (IY+offset) - DEC A - DEC B - DEC BC - DEC C - DEC D - DEC DE - DEC E - DEC H - DEC HL - DEC IX - DEC IY - DEC L - DEC SP - DI -loop1: - DJNZ loop1 - - EI - EX (SP),HL - EX (SP),IX - EX (SP),IY - EX AF,AF' - EX DE,HL - EXX - HALT - - IM 0 - IM 1 - IM 2 - - IN A,(C) - IN B,(C) - IN C,(C) - IN D,(C) - IN E,(C) - IN H,(C) - IN L,(C) - IN A,(port) - - IN0 B,(n) - IN0 C,(n) - IN0 D,(n) - IN0 E,(n) - IN0 H,(n) - IN0 L,(n) - - INC (HL) - INC (IX+offset) - INC (IY+offset) - INC A - INC B - INC BC - INC C - INC D - INC DE - INC E - INC H - INC HL - INC IX - INC IY - INC L - INC SP - - IND - INDR - INI - INIR - - JP addr16 - JP (HL) - JP (IX) - JP (IY) - JP C,addr16 - JP M,addr16 - JP NC,addr16 - JP NZ,addr16 - JP P,addr16 - JP PE,addr16 - JP PO,addr16 - JP Z,addr16 - -loop2: - JR C,loop2 - JR NC,loop2 - JR NZ,loop2 - JR Z,loop2 - JR loop2 - - LD (BC),A - LD (DE),A - LD (HL),A - LD (HL),B - LD (HL),C - LD (HL),D - LD (HL),E - LD (HL),H - LD (HL),L - LD (HL),n - LD (IX+offset),A - LD (IX+offset),B - LD (IX+offset),C - LD (IX+offset),D - LD (IX+offset),E - LD (IX+offset),H - LD (IX+offset),L - LD (IX+offset),n - LD (IY+offset),A - LD (IY+offset),B - LD (IY+offset),C - LD (IY+offset),D - LD (IY+offset),E - LD (IY+offset),H - LD (IY+offset),L - LD (IY+offset),n - LD (nn),A - LD (nn),BC - LD (nn),DE - LD (nn),HL - LD (nn),IX - LD (nn),IY - LD (nn),SP - LD A,(BC) - LD A,(DE) - LD A,(HL) - LD A,(IX+offset) - LD A,(IY+offset) - LD A,(nn) - LD A,A - LD A,B - LD A,C - LD A,D - LD A,E - LD A,H - LD A,I - LD A,L - LD A,n - LD A,R - LD B,(HL) - LD B,(IX+offset) - LD B,(IY+offset) - LD B,A - LD B,B - LD B,C - LD B,D - LD B,E - LD B,H - LD B,L - LD B,n - LD BC,(nn) - LD BC,nn - LD C,(HL) - LD C,(IX+offset) - LD C,(IY+offset) - LD C,A - LD C,B - LD C,C - LD C,D - LD C,E - LD C,H - LD C,L - LD C,n - LD D,(HL) - LD D,(IX+offset) - LD D,(IY+offset) - LD D,A - LD D,B - LD D,C - LD D,D - LD D,E - LD D,H - LD D,L - LD D,n - LD DE,(nn) - LD DE,nn - LD E,(HL) - LD E,(IX+offset) - LD E,(IY+offset) - LD E,A - LD E,B - LD E,C - LD E,D - LD E,E - LD E,H - LD E,L - LD E,n - LD H,(HL) - LD H,(IX+offset) - LD H,(IY+offset) - LD H,A - LD H,B - LD H,C - LD H,D - LD H,E - LD H,H - LD H,L - LD H,n - LD HL,(nn) - LD HL,nn - LD I,A - LD IX,(nn) - LD IX,nn - LD IY,(nn) - LD IY,nn - LD L,(HL) - LD L,(IX+offset) - LD L,(IY+offset) - LD L,A - LD L,B - LD L,C - LD L,D - LD L,E - LD L,H - LD L,L - LD L,n - LD R,A - LD SP,(nn) - LD SP,HL - LD SP,IX - LD SP,IY - LD SP,nn - - LDD - LDDR - LDI - LDIR - - MLT BC - MLT DE - MLT HL - MLT SP - - NEG - NOP - - OR (HL) - OR (IX+offset) - OR (IY+offset) - OR A - OR B - OR C - OR D - OR E - OR H - OR L - OR imm8 - - OTDR - OTIR - - OUT (C),A - OUT (C),B - OUT (C),C - OUT (C),D - OUT (C),E - OUT (C),H - OUT (C),L - OUT (port),A - - OUT0 (imm8),A - OUT0 (imm8),B - OUT0 (imm8),C - OUT0 (imm8),D - OUT0 (imm8),E - OUT0 (imm8),H - OUT0 (imm8),L - - OUTD - OUTI - OTIM - OTDM - OTIMR - OTDMR - - POP AF - POP BC - POP DE - POP HL - POP IX - POP IY - - PUSH AF - PUSH BC - PUSH DE - PUSH HL - PUSH IX - PUSH IY - - RES 0,(HL) - RES 0,(IX+offset) - RES 0,(IY+offset) - RES 0,A - RES 0,B - RES 0,C - RES 0,D - RES 0,E - RES 0,H - RES 0,L - - RES 1,(HL) - RES 1,(IX+offset) - RES 1,(IY+offset) - RES 1,A - RES 1,B - RES 1,C - RES 1,D - RES 1,E - RES 1,H - RES 1,L - - RES 2,(HL) - RES 2,(IX+offset) - RES 2,(IY+offset) - RES 2,A - RES 2,B - RES 2,C - RES 2,D - RES 2,E - RES 2,H - RES 2,L - - RES 3,(HL) - RES 3,(IX+offset) - RES 3,(IY+offset) - RES 3,A - RES 3,B - RES 3,C - RES 3,D - RES 3,E - RES 3,H - RES 3,L - - RES 4,(HL) - RES 4,(IX+offset) - RES 4,(IY+offset) - RES 4,A - RES 4,B - RES 4,C - RES 4,D - RES 4,E - RES 4,H - RES 4,L - - RES 5,(HL) - RES 5,(IX+offset) - RES 5,(IY+offset) - RES 5,A - RES 5,B - RES 5,C - RES 5,D - RES 5,E - RES 5,H - RES 5,L - - RES 6,(HL) - RES 6,(IX+offset) - RES 6,(IY+offset) - RES 6,A - RES 6,B - RES 6,C - RES 6,D - RES 6,E - RES 6,H - RES 6,L - - RES 7,(HL) - RES 7,(IX+offset) - RES 7,(IY+offset) - RES 7,A - RES 7,B - RES 7,C - RES 7,D - RES 7,E - RES 7,H - RES 7,L - - RET - RET C - RET M - RET NC - RET NZ - RET P - RET PE - RET PO - RET Z - RETI - RETN - - RL (HL) - RL (IX+offset) - RL (IY+offset) - RL A - RL B - RL C - RL D - RL E - RL H - RL L - RLA - - RLC (HL) - RLC (IX+offset) - RLC (IY+offset) - RLC A - RLC B - RLC C - RLC D - RLC E - RLC H - RLC L - RLCA - RLD - - RR (HL) - RR (IX+offset) - RR (IY+offset) - RR A - RR B - RR C - RR D - RR E - RR H - RR L - RRA - - RRC (HL) - RRC (IX+offset) - RRC (IY+offset) - RRC A - RRC B - RRC C - RRC D - RRC E - RRC H - RRC L - RRCA - RRD - - RST 00H - RST 08H - RST 10H - RST 18H - RST 20H - RST 28H - RST 30H - RST 38H - - SBC A,n - SBC A,(HL) - SBC A,(IX+offset) - SBC A,(IY+offset) - SBC A,A - SBC A,B - SBC A,C - SBC A,D - SBC A,E - SBC A,H - SBC A,L - SBC HL,BC - SBC HL,DE - SBC HL,HL - SBC HL,SP - SCF - - SET 0,(HL) - SET 0,(IX+offset) - SET 0,(IY+offset) - SET 0,A - SET 0,B - SET 0,C - SET 0,D - SET 0,E - SET 0,H - SET 0,L - - SET 1,(HL) - SET 1,(IX+offset) - SET 1,(IY+offset) - SET 1,A - SET 1,B - SET 1,C - SET 1,D - SET 1,E - SET 1,H - SET 1,L - - SET 2,(HL) - SET 2,(IX+offset) - SET 2,(IY+offset) - SET 2,A - SET 2,B - SET 2,C - SET 2,D - SET 2,E - SET 2,H - SET 2,L - - SET 3,(HL) - SET 3,(IX+offset) - SET 3,(IY+offset) - SET 3,A - SET 3,B - SET 3,C - SET 3,D - SET 3,E - SET 3,H - SET 3,L - - SET 4,(HL) - SET 4,(IX+offset) - SET 4,(IY+offset) - SET 4,A - SET 4,B - SET 4,C - SET 4,D - SET 4,E - SET 4,H - SET 4,L - - SET 5,(HL) - SET 5,(IX+offset) - SET 5,(IY+offset) - SET 5,A - SET 5,B - SET 5,C - SET 5,D - SET 5,E - SET 5,H - SET 5,L - - SET 6,(HL) - SET 6,(IX+offset) - SET 6,(IY+offset) - SET 6,A - SET 6,B - SET 6,C - SET 6,D - SET 6,E - SET 6,H - SET 6,L - - SET 7,(HL) - SET 7,(IX+offset) - SET 7,(IY+offset) - SET 7,A - SET 7,B - SET 7,C - SET 7,D - SET 7,E - SET 7,H - SET 7,L - - SLA (HL) - SLA (IX+offset) - SLA (IY+offset) - SLA A - SLA B - SLA C - SLA D - SLA E - SLA H - SLA L - - SLP - - SRA (HL) - SRA (IX+offset) - SRA (IY+offset) - SRA A - SRA B - SRA C - SRA D - SRA E - SRA H - SRA L - - SRL (HL) - SRL (IX+offset) - SRL (IY+offset) - SRL A - SRL B - SRL C - SRL D - SRL E - SRL H - SRL L - - SUB (HL) - SUB (IX+offset) - SUB (IY+offset) - SUB A - SUB B - SUB C - SUB D - SUB E - SUB H - SUB L - SUB n - - TST A - TST B - TST C - TST D - TST E - TST (HL) - TST n - - XOR (HL) - XOR (IX+offset) - XOR (IY+offset) - XOR A - XOR B - XOR C - XOR D - XOR E - XOR H - XOR L - XOR n - end diff --git a/branches/s100/XSource/makeall b/branches/s100/XSource/makeall deleted file mode 100755 index a2558435..00000000 --- a/branches/s100/XSource/makeall +++ /dev/null @@ -1,5 +0,0 @@ -make clean -make -f Makefile_n8vem -make -f Makefile_n8_2312 -make -f Makefile_zeta -ls -l ../Output diff --git a/branches/s100/cpurom/Makefile b/branches/s100/cpurom/Makefile deleted file mode 100644 index 9442748f..00000000 --- a/branches/s100/cpurom/Makefile +++ /dev/null @@ -1,692 +0,0 @@ -######################################################## -# Makefile for Doug's Unified BIOS 8/07/2011 # -# The BIOS and associated utilities are generated # -# using the Small Device C Compiler (SDCC) & tools # -# With multiplatform enhancements by John Coffman # -# # -# sdcc.l00 added because stupid Windoze 'echo' appends # -# a confusing SPACE to the end of every line. # -######################################################## - -##################################################### -# SPREFIX tells where the SDCC package in installed # -# The SDCC package is used to assemble Z80 portions # -# of the software such as the ROM and perhaps some # -# .COM files such as FDISK. # -##################################################### - -################################################################# -# TPREFIX tells where the host development tools are installed. # -# The host tools are used to manipulate the Z80 objects after # -# the basic assemblies and compilations have been completed. # -################################################################# - -################################################################### -# SDCC is not available on the DOS host, so something else may be # -# used at the descretion of the builder. (TASM for instance). # -################################################################### - -################################################################### -# The COPY, DEL and RENAME macros are used to customize the build # -# rules for the host enviroonment. # -################################################################### - -#------------------------------------------- -# Choose one only, then Make will work for -# your platform. - -#CFG = $(shell uname) -# Mac OS X returns 'Darwin' -# Linux returns 'Linux' - -#CFG = dos -#CFG = linux -#CFG = macosx -CFG = windows - -#------------------------------------------- -ifeq ($(CFG),Darwin) -DELIM = / -SPREFIX = /Developer/sdcc -SDAS = $(SPREFIX)/bin/sdasz80 -SDASFLG = -plosff -Iinc -SDCC = $(SPREFIX)/bin/sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)/share/sdcc/lib/z80 -SDLD = $(SPREFIX)/bin/sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCFLG = -I inc -COPY = cp -DEL = rm -DELFLG = -f -# use native ECHO o Mac OS X -ECHO = echo -REN = mv -EXE = -endif -#------------------------------------------- -ifeq ($(CFG),windows) -DELIM = \ -SDRIVE = C: -SPREFIX = $(SDRIVE)\Program Files (x86)\sdcc -SDAS = $(SPREFIX)\bin\sdasz80 -SDASFLG = -plosff -SDCC = $(SPREFIX)\bin\sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)\lib\z80 -SDLD = $(SPREFIX)\bin\sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCOPT = -I inc -COPY = copy -DEL = erase -DELFLG = -REN = rename - -# This is special handling for John Coffman to get around funky windows -# behavior where echo adds spurious space o end f line -# ECHO = { lecho | lechocr | lecholf | lechocrlf | lecholfcr } - -#ECHO = $(BIN)$(DELIM)lechocr -#ECHO = $(BIN)$(DELIM)lecho - -EXE = .exe -endif - -#------------------------------------------- -ifeq ($(CFG),Linux) -DELIM = / -SPREFIX = /home/$(USER) -SDAS = $(SPREFIX)/bin/sdasz80 -SDASFLG = -plosff -SDCC = $(SPREFIX)/bin/sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = /usr/local/share/sdcc/lib/z80 -SDLD = $(SPREFIX)/bin/sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCFLG = -I inc -COPY = cp -DEL = rm -DELFLG = -f -REN = mv -# Use native 'echo' on Linux -ECHO = echo -EXE = -endif -#------------------------------------------- -ifeq ($(CFG),dos) -DELIM = \ -SPREFIX = -SDAS = -SDASFLG = -SDCC = -SDCCFLG = -SDCCLIB = -SDLD = -SDLDFLG = -TPREFIX = -TCC = wcl -TCCOPT = -COPY = copy -DEL = erase -DELFLG = -REN = rename -EXE = .exe -endif -############################################################ - -# Misc other macros - -BIN = bin$(DELIM) -COM = com$(DELIM) -INC = inc$(DELIM) -LIB = lib$(DELIM) -LST = lst$(DELIM) -MAP = map$(DELIM) -OBJ = obj$(DELIM) -REF = ref$(DELIM) -ROM = rom$(DELIM) -SRC = src$(DELIM) -TMP = tmp$(DELIM) - -# CP/M-80 v2.2 Command files written in SDCC -COMFILES = $(COM)copyfile.com $(COM)fdisk.com - -# Components used by CP/M-80 v2.2 Command files -COMRELS = $(OBJ)cpm0.rel $(OBJ)cpmbdos.rel $(OBJ)cprintf.rel - -# Components of ROM image containing CP/M for SBC V2 -CPMRELS = $(OBJ)crt0.rel $(OBJ)dbgmon.rel $(OBJ)bdosb01.rel \ - $(OBJ)ccpb03.rel $(OBJ)cbios.rel - -# Components of ROM image used in test protocols -ROMRELS = $(OBJ)crt0jplp.rel $(OBJ)crt0scrm.rel - -# Components that control hardware in SBC V2 -SBCV2HW = - -# Components that control hardware in the SCSI2IDE -SCSI2IDEHW = $(OBJ)z53c80.rel - -FDISK = $(BIN)fdisk$(EXE) -DWGH2B = $(BIN)dwgh2b$(EXE) -INCFILES = $(INC)cpmbdos.h $(INC)cprintf.h $(INC)portab.h -JRCH2B = $(BIN)jrch2b$(EXE) -LOAD = $(BIN)load$(EXE) -MK = Makefile -#QUIET = @ - -# ROM images for SBC V2 and N8 -ROMFILES = $(ROM)scsiscrm.rom $(ROM)scsijplp.rom $(ROM)scsi2ide.rom $(ROM)baseline.rom $(ROM)n8.rom -SCSI2IDE = $(ROM)scsi2ide.rom - -SYSGEN = $(BIN)sysgen$(EXE) -VERIFY = $(BIN)verify$(EXE) - -# C programs compiled on host system used in build -TOOLS = $(FDISK) $(DWGH2B) $(LOAD) $(JRCH2B) $(SYSGEN) - -# Versions of 'echo' compiled on host system -ETOOLS = $(BIN)lechocr $(BIN)lecholf $(BIN)lechocrlf $(BIN)lecholfcr - -# dribdos.rel is not part of the production set yet -##TEST = dribdos.rel - -############################################################ - -#all: $(ETOOLS) $(TOOLS) $(BINFILES) $(COMFILES) $(CPMFILES) $(ROMFILES) - -#all: $(TEST) $(ROMFILES) $(COMFILES) - -roms: $(ROMFILES) -scsi2ide: $(SCSI2IDE) - -############################################################ - -# A test assembly of DRI source code for BDOS (from SIMH) -dribdos.rel: $(SRC)dribdos.s - $(QUIET)$(SDAS) $(SDASFLG) dribdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dribdos.lst $(LST) - -############################################################ -############################################################ - -# Build SCSIJPLP ROM image - -$(ROM)scsijplp.rom: $(OBJ)scsijplp.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.bin $(ROM)scsijplp.rom - $(QUIET)$(DEL) $(DELFLG) scsijplp.* - -$(OBJ)scsijplp.bin: $(OBJ)scsijplp.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsijplp - -$(OBJ)scsijplp.hex: $(OBJ)scsijplp.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.ihx $(OBJ)scsijplp.hex - -$(OBJ)scsijplp.ihx: $(OBJ)crt0jplp.rel $(TMP)scsijplp.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lk - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsijplp.lnk - $(QUIET)$(COPY) $(COPYFLG) scsijplp.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsijplp.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsijplp.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsijplp.arf - $(ECHO) -i scsijplp.ihx >> $(TMP)scsijplp.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsijplp.arf - $(ECHO) -l z80 >> $(TMP)scsijplp.arf - $(ECHO) $(OBJ)crt0jplp.rel >> $(TMP)scsijplp.arf - $(ECHO) -e >> $(TMP)scsijplp.arf - -############################################################ -############################################################ - -# Build SCSISCRM ROM image - -$(ROM)scsiscrm.rom: $(OBJ)scsiscrm.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.bin $(ROM)scsiscrm.rom - $(QUIET)$(DEL) $(DELFLG) scsiscrm.* - -$(OBJ)scsiscrm.bin: $(OBJ)scsiscrm.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsiscrm - -$(OBJ)scsiscrm.hex: $(OBJ)scsiscrm.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.ihx $(OBJ)scsiscrm.hex - -$(OBJ)scsiscrm.ihx: $(OBJ)crt0scrm.rel $(TMP)scsiscrm.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lk - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsiscrm.lnk - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsiscrm # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsiscrm.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsiscrm.arf - $(ECHO) -i scsiscrm.ihx >> $(TMP)scsiscrm.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsiscrm.arf - $(ECHO) -l z80 >> $(TMP)scsiscrm.arf - $(ECHO) $(OBJ)crt0scrm.rel >> $(TMP)scsiscrm.arf - $(ECHO) -e >> $(TMP)scsiscrm.arf - -############################################################ -############################################################ - -# Build SCSI2IDE ROM image - -$(ROM)scsi2ide.rom: $(OBJ)scsi2ide.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.bin $(ROM)scsi2ide.rom - $(QUIET)$(DEL) $(DELFLG) scsi2ide.* - -$(OBJ)scsi2ide.bin: $(OBJ)scsi2ide.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsi2ide - -$(OBJ)scsi2ide.hex: $(OBJ)scsi2ide.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.ihx $(OBJ)scsi2ide.hex - -$(OBJ)scsi2ide.ihx: $(CPMRELS) $(SCSI2IDEHW) $(OBJ)scsi2ide.rel $(TMP)scsi2ide.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lk - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsi2ide.lnk - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsi2ide.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsi2ide.arf - $(ECHO) -i scsi2ide.ihx >> $(TMP)scsi2ide.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsi2ide.arf - $(ECHO) -l z80 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)scsi2ide.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)cbios.rel >> $(TMP)scsi2ide.arf - $(ECHO) -e >> $(TMP)scsi2ide.arf - -######################################################## -# Compile C portion of the scsi2ide EEPROM Image -$(OBJ)scsi2ide.rel: $(SRC)scsi2ide.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)scsi2ide.c - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.lst $(LST) - - -############################################################ -############################################################ - -# Build SBC V2 ROM image - -$(ROM)baseline.rom: $(OBJ)baseline.bin $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.bin $(ROM)baseline.rom - $(QUIET)$(DEL) $(DELFLG) baseline.* - -$(OBJ)baseline.bin: $(OBJ)baseline.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)baseline - -$(OBJ)baseline.hex: $(OBJ)baseline.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.ihx $(OBJ)baseline.hex - -$(OBJ)baseline.ihx: $(CPMRELS) $(SBCV2HW) $(OBJ)baseline.rel $(TMP)baseline.arf $(MK) - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lk - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)baseline.lnk - $(QUIET)$(COPY) $(COPYFLG) baseline.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.map $(MAP) - -######################################################### -# Dynamically generate linker control file for baseline # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)baseline.arf: $(MK) - $(ECHO) -mjx > $(TMP)baseline.arf - $(ECHO) -i baseline.ihx >> $(TMP)baseline.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)baseline.arf - $(ECHO) -l z80 >> $(TMP)baseline.arf - $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)baseline.arf - $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)baseline.arf - $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)baseline.arf - $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)baseline.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)baseline.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)cbios.rel >> $(TMP)baseline.arf - $(ECHO) -e >> $(TMP)baseline.arf - -######################################################## -# Compile C portion of the Baseline PROM Image -$(OBJ)baseline.rel: $(SRC)baseline.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)baseline.c - $(QUIET)$(COPY) $(COPYFLG) baseline.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.lst $(LST) - -############################################################ - -# Build N8 ROM image - -# -# Save the resulting merged image in the Rom folder -# -$(ROM)n8.rom: $(OBJ)n8-romim.bin $(MK) - $(QUIET)$(COPY) $(OBJ)n8-romim.bin $(ROM)n8.rom - $(QUIET)$(DEL) $(DELFLG) n8.* - -# -# Convert the Intel hex file into a binary, similar -# to the results of the "copy /B ..." -# -$(OBJ)n8-romim.bin: $(OBJ)sysimage.hex $(REF)n8-romim.ref $(SYSGEN) $(HEX2BIN) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)sysimage - $(QUIET)$(COPY) $(REF)n8-romim.ref $(OBJ)n8-romim.bin - $(QUIET)$(SYSGEN) -i $(OBJ)sysimage.bin $(OBJ)n8-romim.bin - -# -# Take the output of the linker and rename to the more -# recognizable .hex form and the expected name "sysimage.hex" -# -$(OBJ)sysimage.hex: $(OBJ)n8.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)n8.ihx $(OBJ)sysimage.hex - -# -# Combine the independently assembled components into one piece -# and output Intel hex file (ihx) -# -$(OBJ)n8.ihx: $(OBJ)loadern8.rel $(OBJ)dbgmon.rel $(OBJ)ccpb03.rel $(OBJ)bdosb01.rel $(OBJ)cbiosn8.rel $(TMP)n8.arf $(MK) - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lk - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)n8.lnk - $(QUIET)$(COPY) $(COPYFLG) n8.ihx $(OBJ)n8.ihx - $(QUIET)$(COPY) $(COPYFLG) n8.map $(MAP) - -$(OBJ)cbiosn8.rel: $(SRC)cbiosn8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbiosn8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.lst $(LST) - -$(OBJ)loadern8.rel: $(SRC)loadern8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)loadern8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.rel $(OBJ) - $(QUIET)$(COPY $(COPYFLG) $(SRC)loadern8.lst $(LST) - -######################################################## -# Dynamically generate the linker control file for N8 # -# Now uses the macro controlled ECHO feature # -######################################################## -$(TMP)n8.arf: Makefile - $(ECHO) -mjx > $(TMP)n8.arf - $(ECHO) -i n8.ihx >> $(TMP)n8.arf - $(ECHO) -k /usr/local/share/sdcc/lib/z80 >> $(TMP)n8.arf - $(ECHO) -l z80 >> $(TMP)n8.arf - $(ECHO) -b _CCPB03 = 0x0900 >> $(TMP)n8.arf - $(ECHO) -b _BDOSB01 = 0x1100 >> $(TMP)n8.arf - $(ECHO) -b _CBIOS = 0x1f00 >> $(TMP)n8.arf - $(ECHO) $(OBJ)loadern8.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)cbiosn8.rel >> $(TMP)n8.arf - $(ECHO) -e >> $(TMP)n8.arf - -############################################################ - -# Hardware specific assemblies (most likely used by BIOS's) - -# -# Assemble hardware control code for the Zilog Z53C8003V5C -# -$(OBJ)z53c80.rel: $(SRC)z53c80.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)z53c80.c - $(QUIET)$(COPY) $(COPYFLG) z53c80.rel $(OBJ) - $(QUIET)$(DEL) $(DELFLG) z53c80.* - -# -# Compile ersatz printf routine for use in CP/M-80 command files -# -$(OBJ)cprintf.rel: $(SRC)cprintf.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)cprintf.c - $(QUIET)$(COPY) $(COPYFLG) cprintf.rel obj - $(QUIET)$(DEL) $(DELFLG) cprintf.* - -############################################################ - -# Build CP/M 2.2 command files (copyfile.com, fdisk.com) - -#----------------------------------------------------------- - -$(COM)copyfile.com: $(OBJ)copyfile.com $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.com $(COM)copyfile.com - $(QUIET)$(DEL) $(DELFLG) copyfile.* - -$(OBJ)copyfile.com: $(OBJ)copyfile.hex $(LOAD) $(BINFILES) $(MK) - $(QUIET)$(LOAD) $(OBJ)copyfile - -$(OBJ)copyfile.hex: $(OBJ)copyfile.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.ihx $(OBJ)copyfile.hex - -$(OBJ)copyfile.ihx: $(OBJ)copyfile.rel $(COMRELS) $(TMP)copyfile.arf $(MK) - $(QUIET)$(COPY) $(TMP)copyfile.arf $(TMP)copyfile.lnk - - $(QUIET)$(SDLD) $(LOPTS) -nf $(TMP)copyfile.lnk - $(QUIET)$(COPY) $(COPYFLG) copyfile.ihx obj - $(QUIET)$(COPY) $(COPYFLG) copyfile.map map - -############################################################## -# Dynamicaly create linker command file for copyfile utility # -# Now uses the macro controlled ECHO feature # -############################################################## -$(TMP)copyfile.arf: Makefile - $(ECHO) -mjx > $(TMP)copyfile.arf - $(ECHO) -i copyfile.ihx >> $(TMP)copyfile.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)copyfile.arf - $(ECHO) -l z80 >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)copyfile.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)copyfile.arf - $(ECHO) -e >> $(TMP)copyfile.arf - -$(OBJ)copyfile.rel: $(SRC)copyfile.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)copyfile.c - $(QUIET)$(COPY) copyfile.rel obj - $(QUIET)$(DEL) $(DELFLG) copyfile.rel - ls obj - -#----------------------------------------------------------- - -# -# Use locally compiled 'load' command to covert Intel -# hex formal file to a binary CP/M-80 command file. -# -$(COM)fdisk.com: $(OBJ)fdisk.hex $(TOOLS) $(MK) - $(QUIET)$(BIN)load $(OBJ)fdisk - $(QUIET)$(COPY) $(COPYFLG) $(OBJ)fdisk.com com - $(QUIET)$(DEL) $(DELFLG) fdisk.* - -# -# rename 'ihx' output of linker to 'hex' - -$(OBJ)fdisk.hex: $(OBJ)fdisk.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)fdisk.ihx $(OBJ)fdisk.hex - -$(OBJ)fdisk.ihx: $(OBJ)fdisk.rel $(TMP)fdisk.arf $(MK) - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(COPYFLG) fdisk.ihx $(OBJ)fdisk.ihx - $(QUIET)$(COPY) $(COPYFLG) fdisk.map map - -$(OBJ)fdisk.rel: $(SRC)fdisk.c $(INCFILES) $(MK) - $(QUIET)$(SDCC) -I inc $(SDCCFLG) $(SRC)fdisk.c - $(QUIET)$(COPY) $(COPYFLG) fdisk.rel $(OBJ) - -############################################################################ -# Dynamically created linker command file for fdisk utility (CP/M version) # -# Now uses macro controlled ECHO feature # -############################################################################ -$(TMP)fdisk.arf: $(MK) - $(ECHO) -mjx > $(TMP)fdisk.arf - $(ECHO) -i fdisk.ihx >> $(TMP)fdisk.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)fdisk.arf - $(ECHO) -l z80 >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)fdisk.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)fdisk.arf - $(ECHO) -e >> $(TMP)fdisk.arf - - -#----------------------------------------------------------- - -# Also build host version of fdisk for testing purposes - -$(BIN)fdisk$(EXE): $(SRC)fdisk.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)fdisk.c -o $(BIN)fdisk - -############################################################ - -# Build CP/M-80 Command File Structure Files - -$(OBJ)cpm0.rel: $(SRC)cpm0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpm0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.lst $(LST) - -$(OBJ)cpmbdos.rel: $(SRC)cpmbdos.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpmbdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.lst $(LST) - -############################################################ - -# Build ROM Image structure files - -$(OBJ)crt0.rel: $(SRC)crt0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.lst $(LST) - -$(OBJ)crt0jplp.rel: $(SRC)crt0jplp.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0jplp.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.lst $(LST) - -$(OBJ)crt0scrm.rel: $(SRC)crt0scrm.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0scrm.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.lst $(LST) - -$(OBJ)bdosb01.rel: $(SRC)bdosb01.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)bdosb01.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.lst $(LST) - -$(OBJ)ccpb03.rel: $(SRC)ccpb03.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)ccpb03.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.lst $(LST) - -# -# Assemble hardware control code for SBC V2 -# -$(OBJ)cbios.rel: $(SRC)cbios.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbios.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.lst $(LST) - -# -# Assemble a monitor program for the SBC V2 -# -$(OBJ)dbgmon.rel: $(SRC)dbgmon.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)dbgmon.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.lst $(LST) - -########################################################### - -# Build host based tools ( dwgh2b, jrch2b, load, verify) - -$(DWGH2B): $(SRC)dwgh2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)dwgh2b.c -o $(BIN)dwgh2b$(EXE) - -# -# Compile John Coffman's hex2bin program -# -$(JRCH2B): $(SRC)jrch2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)jrch2b.c -o $(BIN)jrch2b$(EXE) - $(QUIET)$(COPY) $(COPYFLG) $(BIN)jrch2b $(BIN)jrcb2h - -# -# Compile Doug's "load" program -# -$(LOAD): $(SRC)load.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)load.c -o $(BIN)load$(EXE) - -$(SYSGEN): $(SRC)sysgen.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)sysgen.c -o $(BIN)sysgen$(EXE) - -# -# Compile Doug's verif program that compares binary file regions -# -$(VERIFY): $(SRC)verify.c Makefile $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)verify.c -o $(BIN)verify - -$(BIN)lechocr: $(SRC)lechocr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c -o $(BIN)lechocr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c - $(QUIET)$(COPY) lechocr.exe $(BIN) - -$(BIN)lecholf: $(SRC)lecholf.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c -o $(BIN)lecholf - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c - $(COPY) lecholf.exe $(BIN) - -$(BIN)lechocrlf: $(SRC)lechocrlf.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocrlf.c -o $(BIN)lechocrlf - -$(BIN)lecholfcr: $(SRC)lecholfcr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - -############################################################ - -# Builder specific utility rules - -dwginstall: - $(COPY) $(COMFILES) ~/Documents/devobox/cdrive - -############################################################ - -# -# Delete all dynamically generated files that don't need to be -# saved. -# -clean: - $(QUIET)$(DEL) $(DELFLG) *.hex *.ihx *.lst *.rel *.rst *.lnk *.lk - $(QUIET)$(DEL) $(DELFLG) *.sym *.map *.noi *.asm *.com *.ini *.bin - $(QUIET)$(DEL) $(DELFLG) obj/* bin/* com/* rom/* tmp/* map/* lst/* - -################## -# eof - Makefile # -################## diff --git a/branches/s100/cpurom/cleanxp.bat b/branches/s100/cpurom/cleanxp.bat deleted file mode 100644 index b6be7814..00000000 --- a/branches/s100/cpurom/cleanxp.bat +++ /dev/null @@ -1 +0,0 @@ -wmake -f makefile.xp clean diff --git a/branches/s100/cpurom/doc/agm1264f.pdf b/branches/s100/cpurom/doc/agm1264f.pdf deleted file mode 100644 index 60eec3d9..00000000 Binary files a/branches/s100/cpurom/doc/agm1264f.pdf and /dev/null differ diff --git a/branches/s100/cpurom/doc/bdoscalls.webarchive b/branches/s100/cpurom/doc/bdoscalls.webarchive deleted file mode 100644 index 30b4faad..00000000 Binary files a/branches/s100/cpurom/doc/bdoscalls.webarchive and /dev/null differ diff --git a/branches/s100/cpurom/doc/bios.webarchive b/branches/s100/cpurom/doc/bios.webarchive deleted file mode 100644 index ede74cc5..00000000 Binary files a/branches/s100/cpurom/doc/bios.webarchive and /dev/null differ diff --git a/branches/s100/cpurom/doc/fcb.webarchive b/branches/s100/cpurom/doc/fcb.webarchive deleted file mode 100644 index d8468620..00000000 Binary files a/branches/s100/cpurom/doc/fcb.webarchive and /dev/null differ diff --git a/branches/s100/cpurom/doc/jrch2b.doc b/branches/s100/cpurom/doc/jrch2b.doc deleted file mode 100644 index 6231b4db..00000000 --- a/branches/s100/cpurom/doc/jrch2b.doc +++ /dev/null @@ -1,92 +0,0 @@ -Usage: - hex2bin [ ]+ - bin2hex - - Options: - -o -- default is 'out.bin' or 'out.hex' - No suffix is added to the filename, so the full - file name must be specified. - - -p -- default is 0xFF, which is the erased - value for most ROM's. Pad bytes are not explicitly - written out when 'bin2hex' is used. This reduces - the size of sparse ROM images. - - -R -- may be any value. Normally this will be - specified as '128k' or 0x10000. The suffixes 'k' - and 'M' are recognized. The default value is 64k - for 'hex2bin' and 1M for 'bin2hex'. - - -v [] -- used primarily for debugging. A - verbosity level of 3 will print each line as it is - processed. - - Options are global, and may be specified anywhere on the command - line. Only 'flags', below, are position sensitive. Flags must - be specified immediately before the file name they are to affect. - They do not affect more that a single file. They reset to their - default values before the next input file, scanning left to - right, is processed. - - Flags: - Flag values apply only to the following file, and are reset - to the default values before the next file is processed. The - source and destination flags allow code to be relocated - within the ROM so that code may be loaded at a different - location than where it will ultimately be run. - - -d -- default is 0. - data will only be loaded between the limits of - the -d address and the -D address - minus 1. - - -D -- default is 16M. No data - will be loaded at or above this address. - - -s -- default is 0. Hex input - is only processed if it falls at addresses in the - .hex input file between the -s address and the - -S address minus 1. Likewise, Bin input - is only processed if it falls between similar limits - in the input ROM image. - - -S -- default is 16M. No input - data at or above this address will be processed. - - Numeric values on the command line may be specified in any C-like - syntax: 0x0000 is hexadecimal, 1234 is decimal, and 0177 is - octal. In addition the suffixes 'k' for kilo- and 'M' for mega- - cause the preceding values to be multiplied by 1024 or 1048576, - respectively. - - Examples: - hex2bin -p 0xFF -R32k cpm22.hex -o cpmtest.bin - hex2bin -o cpmtest.bin cpm22.hex -R 0x8000 -p255 - - The preceding two lines have identical effects in all - respects. - - hex2bin -R 1M -s 0xd000 -d 0x0800 -D0x2800 image.hex \ - pagezero.hex -oROMIMAGE.bin - - The above line loads the 'pagezero.hex' file at the exact - addresses specified in the file; however, the 'image.hex' file - is assembled at 0xD000, must run at 0xD000, but is loaded - between 0x800 <= addr < 0x2800. It is presumed that the - code will be relocated to the correct address before it is - executed. - - bin2hex -R128k romimage.bin -o image.hex - - Simple conversion from a BIN file to a HEX file. The ROM - data is limited to 128k. - - bin2hex -s 0x1000 -S 0x2000 -d 0x21000 romimage.bin \ - -o Relocated.hex - - Extract from a ROM image file all of the data between 0x1000 - and 0x1FFF, inclusive, and write to an Intel hex file for - re-loading two 64k segments higher in a future ROM. - - -(end) diff --git a/branches/s100/cpurom/doc/make.pdf b/branches/s100/cpurom/doc/make.pdf deleted file mode 100644 index 3e18161c..00000000 Binary files a/branches/s100/cpurom/doc/make.pdf and /dev/null differ diff --git a/branches/s100/cpurom/doc/sdcc-z80-mode.png b/branches/s100/cpurom/doc/sdcc-z80-mode.png deleted file mode 100644 index 064b32b1..00000000 Binary files a/branches/s100/cpurom/doc/sdcc-z80-mode.png and /dev/null differ diff --git a/branches/s100/cpurom/doc/watcom-tools.pdf b/branches/s100/cpurom/doc/watcom-tools.pdf deleted file mode 100644 index 6d3f38c9..00000000 Binary files a/branches/s100/cpurom/doc/watcom-tools.pdf and /dev/null differ diff --git a/branches/s100/cpurom/exp/common.mak b/branches/s100/cpurom/exp/common.mak deleted file mode 100644 index 7430e334..00000000 --- a/branches/s100/cpurom/exp/common.mak +++ /dev/null @@ -1,558 +0,0 @@ -# mak/makebody.mfi 8/8/2011 dwg - - -# Misc other macros - -BIN = bin$(DELIM) -COM = com$(DELIM) -INC = inc$(DELIM) -LIB = lib$(DELIM) -LST = lst$(DELIM) -MAP = map$(DELIM) -OBJ = obj$(DELIM) -REF = ref$(DELIM) -ROM = rom$(DELIM) -SRC = src$(DELIM) -TMP = tmp$(DELIM) - -# CP/M-80 v2.2 Command files written in SDCC -COMFILES = $(COM)copyfile.com $(COM)fdisk.com - -# Components used by CP/M-80 v2.2 Command files -COMRELS = $(OBJ)cpm0.rel $(OBJ)cpmbdos.rel $(OBJ)cprintf.rel - -# Components of ROM image containing CP/M for SBC V2 -CPMRELS = $(OBJ)crt0.rel $(OBJ)dbgmon.rel $(OBJ)bdosb01.rel \ - $(OBJ)ccpb03.rel $(OBJ)cbios.rel - -# Components of ROM image used in test protocols -ROMRELS = $(OBJ)crt0jplp.rel $(OBJ)crt0scrm.rel - -# Components that control hardware in SBC V2 -SBCV2HW = - -# Components that control hardware in the SCSI2IDE -SCSI2IDEHW = $(OBJ)z53c80.rel - -FDISK = $(BIN)fdisk$(EXE) -DWGH2B = $(BIN)dwgh2b$(EXE) -INCFILES = $(INC)cpmbdos.h $(INC)cprintf.h $(INC)portab.h -JRCH2B = $(BIN)jrch2b$(EXE) -LOAD = $(BIN)load$(EXE) -MK = Makefile -#QUIET = @ - -# ROM images for SBC V2 and N8 -ROMFILES = $(ROM)scsiscrm.rom $(ROM)scsijplp.rom $(ROM)scsi2ide.rom $(ROM)baseline.rom $(ROM)n8.rom -SCSI2IDE = $(ROM)scsi2ide.rom - -SYSGEN = $(BIN)sysgen$(EXE) -VERIFY = $(BIN)verify$(EXE) - -# C programs compiled on host system used in build -TOOLS = $(FDISK) $(DWGH2B) $(LOAD) $(JRCH2B) $(SYSGEN) - -# Versions of 'echo' compiled on host system -ETOOLS = $(BIN)lechocr $(BIN)lecholf $(BIN)lechocrlf $(BIN)lecholfcr - -# dribdos.rel is not part of the production set yet -##TEST = dribdos.rel - -############################################################ - -#all: $(ETOOLS) $(TOOLS) $(BINFILES) $(COMFILES) $(CPMFILES) $(ROMFILES) - -#all: $(TEST) $(ROMFILES) $(COMFILES) - -roms: $(ROMFILES) -scsi2ide: $(SCSI2IDE) - -############################################################ - -# A test assembly of DRI source code for BDOS (from SIMH) -dribdos.rel: $(SRC)dribdos.s - $(QUIET)$(SDAS) $(SDASFLG) dribdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dribdos.lst $(LST) - -############################################################ -############################################################ - -# Build SCSIJPLP ROM image - -$(ROM)scsijplp.rom: $(OBJ)scsijplp.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.bin $(ROM)scsijplp.rom - $(QUIET)$(DEL) $(DELFLG) scsijplp.* - -$(OBJ)scsijplp.bin: $(OBJ)scsijplp.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsijplp - -$(OBJ)scsijplp.hex: $(OBJ)scsijplp.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.ihx $(OBJ)scsijplp.hex - -$(OBJ)scsijplp.ihx: $(OBJ)crt0jplp.rel $(TMP)scsijplp.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lk - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsijplp.lnk - $(QUIET)$(COPY) $(COPYFLG) scsijplp.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsijplp.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsijplp.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsijplp.arf - $(ECHO) -i scsijplp.ihx >> $(TMP)scsijplp.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsijplp.arf - $(ECHO) -l z80 >> $(TMP)scsijplp.arf - $(ECHO) $(OBJ)crt0jplp.rel >> $(TMP)scsijplp.arf - $(ECHO) -e >> $(TMP)scsijplp.arf - -############################################################ -############################################################ - -# Build SCSISCRM ROM image - -$(ROM)scsiscrm.rom: $(OBJ)scsiscrm.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.bin $(ROM)scsiscrm.rom - $(QUIET)$(DEL) $(DELFLG) scsiscrm.* - -$(OBJ)scsiscrm.bin: $(OBJ)scsiscrm.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsiscrm - -$(OBJ)scsiscrm.hex: $(OBJ)scsiscrm.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.ihx $(OBJ)scsiscrm.hex - -$(OBJ)scsiscrm.ihx: $(OBJ)crt0scrm.rel $(TMP)scsiscrm.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lk - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsiscrm.lnk - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsiscrm # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsiscrm.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsiscrm.arf - $(ECHO) -i scsiscrm.ihx >> $(TMP)scsiscrm.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsiscrm.arf - $(ECHO) -l z80 >> $(TMP)scsiscrm.arf - $(ECHO) $(OBJ)crt0scrm.rel >> $(TMP)scsiscrm.arf - $(ECHO) -e >> $(TMP)scsiscrm.arf - -############################################################ -############################################################ - -# Build SCSI2IDE ROM image - -$(ROM)scsi2ide.rom: $(OBJ)scsi2ide.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.bin $(ROM)scsi2ide.rom - $(QUIET)$(DEL) $(DELFLG) scsi2ide.* - -$(OBJ)scsi2ide.bin: $(OBJ)scsi2ide.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsi2ide - -$(OBJ)scsi2ide.hex: $(OBJ)scsi2ide.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.ihx $(OBJ)scsi2ide.hex - -$(OBJ)scsi2ide.ihx: $(CPMRELS) $(SCSI2IDEHW) $(OBJ)scsi2ide.rel $(TMP)scsi2ide.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lk - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsi2ide.lnk - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsi2ide.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsi2ide.arf - $(ECHO) -i scsi2ide.ihx >> $(TMP)scsi2ide.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsi2ide.arf - $(ECHO) -l z80 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)scsi2ide.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)cbios.rel >> $(TMP)scsi2ide.arf - $(ECHO) -e >> $(TMP)scsi2ide.arf - -######################################################## -# Compile C portion of the scsi2ide EEPROM Image -$(OBJ)scsi2ide.rel: $(SRC)scsi2ide.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)scsi2ide.c - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.lst $(LST) - - -############################################################ -############################################################ - -# Build SBC V2 ROM image - -$(ROM)baseline.rom: $(OBJ)baseline.bin $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.bin $(ROM)baseline.rom - $(QUIET)$(DEL) $(DELFLG) baseline.* - -$(OBJ)baseline.bin: $(OBJ)baseline.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)baseline - -$(OBJ)baseline.hex: $(OBJ)baseline.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.ihx $(OBJ)baseline.hex - -$(OBJ)baseline.ihx: $(CPMRELS) $(SBCV2HW) $(OBJ)baseline.rel $(TMP)baseline.arf $(MK) - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lk - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)baseline.lnk - $(QUIET)$(COPY) $(COPYFLG) baseline.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.map $(MAP) - -######################################################### -# Dynamically generate linker control file for baseline # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)baseline.arf: $(MK) - $(ECHO) -mjx > $(TMP)baseline.arf - $(ECHO) -i baseline.ihx >> $(TMP)baseline.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)baseline.arf - $(ECHO) -l z80 >> $(TMP)baseline.arf - $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)baseline.arf - $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)baseline.arf - $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)baseline.arf - $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)baseline.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)baseline.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)cbios.rel >> $(TMP)baseline.arf - $(ECHO) -e >> $(TMP)baseline.arf - -######################################################## -# Compile C portion of the Baseline PROM Image -$(OBJ)baseline.rel: $(SRC)baseline.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)baseline.c - $(QUIET)$(COPY) $(COPYFLG) baseline.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.lst $(LST) - -############################################################ - -# Build N8 ROM image - -# -# Save the resulting merged image in the Rom folder -# -$(ROM)n8.rom: $(OBJ)n8-romim.bin $(MK) - $(QUIET)$(COPY) $(OBJ)n8-romim.bin $(ROM)n8.rom - $(QUIET)$(DEL) $(DELFLG) n8.* - -# -# Convert the Intel hex file into a binary, similar -# to the results of the "copy /B ..." -# -$(OBJ)n8-romim.bin: $(OBJ)sysimage.hex $(REF)n8-romim.ref $(SYSGEN) $(HEX2BIN) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)sysimage - $(QUIET)$(COPY) $(REF)n8-romim.ref $(OBJ)n8-romim.bin - $(QUIET)$(SYSGEN) -i $(OBJ)sysimage.bin $(OBJ)n8-romim.bin - -# -# Take the output of the linker and rename to the more -# recognizable .hex form and the expected name "sysimage.hex" -# -$(OBJ)sysimage.hex: $(OBJ)n8.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)n8.ihx $(OBJ)sysimage.hex - -# -# Combine the independently assembled components into one piece -# and output Intel hex file (ihx) -# -$(OBJ)n8.ihx: $(OBJ)loadern8.rel $(OBJ)dbgmon.rel $(OBJ)ccpb03.rel $(OBJ)bdosb01.rel $(OBJ)cbiosn8.rel $(TMP)n8.arf $(MK) - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lk - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)n8.lnk - $(QUIET)$(COPY) $(COPYFLG) n8.ihx $(OBJ)n8.ihx - $(QUIET)$(COPY) $(COPYFLG) n8.map $(MAP) - -$(OBJ)cbiosn8.rel: $(SRC)cbiosn8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbiosn8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.lst $(LST) - -$(OBJ)loadern8.rel: $(SRC)loadern8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)loadern8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.rel $(OBJ) - $(QUIET)$(COPY $(COPYFLG) $(SRC)loadern8.lst $(LST) - -######################################################## -# Dynamically generate the linker control file for N8 # -# Now uses the macro controlled ECHO feature # -######################################################## -$(TMP)n8.arf: Makefile - $(ECHO) -mjx > $(TMP)n8.arf - $(ECHO) -i n8.ihx >> $(TMP)n8.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)n8.arf - $(ECHO) -l z80 >> $(TMP)n8.arf - $(ECHO) -b _CCPB03 = 0x0900 >> $(TMP)n8.arf - $(ECHO) -b _BDOSB01 = 0x1100 >> $(TMP)n8.arf - $(ECHO) -b _CBIOS = 0x1f00 >> $(TMP)n8.arf - $(ECHO) $(OBJ)loadern8.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)cbiosn8.rel >> $(TMP)n8.arf - $(ECHO) -e >> $(TMP)n8.arf - -############################################################ - -# Hardware specific assemblies (most likely used by BIOS's) - -# -# Assemble hardware control code for the Zilog Z53C8003V5C -# -$(OBJ)z53c80.rel: $(SRC)z53c80.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)z53c80.c - $(QUIET)$(COPY) $(COPYFLG) z53c80.rel $(OBJ) - $(QUIET)$(DEL) $(DELFLG) z53c80.* - -# -# Compile ersatz printf routine for use in CP/M-80 command files -# -$(OBJ)cprintf.rel: $(SRC)cprintf.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)cprintf.c - $(QUIET)$(COPY) $(COPYFLG) cprintf.rel obj - $(QUIET)$(DEL) $(DELFLG) cprintf.* - -############################################################ - -# Build CP/M 2.2 command files (copyfile.com, fdisk.com) - -#----------------------------------------------------------- - -$(COM)copyfile.com: $(OBJ)copyfile.com $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.com $(COM)copyfile.com - $(QUIET)$(DEL) $(DELFLG) copyfile.* - -$(OBJ)copyfile.com: $(OBJ)copyfile.hex $(LOAD) $(BINFILES) $(MK) - $(QUIET)$(LOAD) $(OBJ)copyfile - -$(OBJ)copyfile.hex: $(OBJ)copyfile.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.ihx $(OBJ)copyfile.hex - -$(OBJ)copyfile.ihx: $(OBJ)copyfile.rel $(COMRELS) $(TMP)copyfile.arf $(MK) - $(QUIET)$(COPY) $(TMP)copyfile.arf $(TMP)copyfile.lnk - - $(QUIET)$(SDLD) $(LOPTS) -nf $(TMP)copyfile.lnk - $(QUIET)$(COPY) $(COPYFLG) copyfile.ihx obj - $(QUIET)$(COPY) $(COPYFLG) copyfile.map map - -############################################################## -# Dynamicaly create linker command file for copyfile utility # -# Now uses the macro controlled ECHO feature # -############################################################## -$(TMP)copyfile.arf: Makefile - $(ECHO) -mjx > $(TMP)copyfile.arf - $(ECHO) -i copyfile.ihx >> $(TMP)copyfile.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)copyfile.arf - $(ECHO) -l z80 >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)copyfile.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)copyfile.arf - $(ECHO) -e >> $(TMP)copyfile.arf - -$(OBJ)copyfile.rel: $(SRC)copyfile.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)copyfile.c - $(QUIET)$(COPY) copyfile.rel obj - $(QUIET)$(DEL) $(DELFLG) copyfile.rel - ls obj - -#----------------------------------------------------------- - -# -# Use locally compiled 'load' command to covert Intel -# hex formal file to a binary CP/M-80 command file. -# -$(COM)fdisk.com: $(OBJ)fdisk.hex $(TOOLS) $(MK) - $(QUIET)$(BIN)load $(OBJ)fdisk - $(QUIET)$(COPY) $(COPYFLG) $(OBJ)fdisk.com com - $(QUIET)$(DEL) $(DELFLG) fdisk.* - -# -# rename 'ihx' output of linker to 'hex' - -$(OBJ)fdisk.hex: $(OBJ)fdisk.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)fdisk.ihx $(OBJ)fdisk.hex - -$(OBJ)fdisk.ihx: $(OBJ)fdisk.rel $(TMP)fdisk.arf $(MK) - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(COPYFLG) fdisk.ihx $(OBJ)fdisk.ihx - $(QUIET)$(COPY) $(COPYFLG) fdisk.map map - -$(OBJ)fdisk.rel: $(SRC)fdisk.c $(INCFILES) $(MK) - $(QUIET)$(SDCC) -I inc $(SDCCFLG) $(SRC)fdisk.c - $(QUIET)$(COPY) $(COPYFLG) fdisk.rel $(OBJ) - -############################################################################ -# Dynamically created linker command file for fdisk utility (CP/M version) # -# Now uses macro controlled ECHO feature # -############################################################################ -$(TMP)fdisk.arf: $(MK) - $(ECHO) -mjx > $(TMP)fdisk.arf - $(ECHO) -i fdisk.ihx >> $(TMP)fdisk.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)fdisk.arf - $(ECHO) -l z80 >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)fdisk.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)fdisk.arf - $(ECHO) -e >> $(TMP)fdisk.arf - - -#----------------------------------------------------------- - -# Also build host version of fdisk for testing purposes - -$(BIN)fdisk$(EXE): $(SRC)fdisk.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)fdisk.c -o $(BIN)fdisk - -############################################################ - -# Build CP/M-80 Command File Structure Files - -$(OBJ)cpm0.rel: $(SRC)cpm0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpm0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.lst $(LST) - -$(OBJ)cpmbdos.rel: $(SRC)cpmbdos.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpmbdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.lst $(LST) - -############################################################ - -# Build ROM Image structure files - -$(OBJ)crt0.rel: $(SRC)crt0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.lst $(LST) - -$(OBJ)crt0jplp.rel: $(SRC)crt0jplp.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0jplp.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.lst $(LST) - -$(OBJ)crt0scrm.rel: $(SRC)crt0scrm.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0scrm.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.lst $(LST) - -$(OBJ)bdosb01.rel: $(SRC)bdosb01.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)bdosb01.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.lst $(LST) - -$(OBJ)ccpb03.rel: $(SRC)ccpb03.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)ccpb03.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.lst $(LST) - -# -# Assemble hardware control code for SBC V2 -# -$(OBJ)cbios.rel: $(SRC)cbios.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbios.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.lst $(LST) - -# -# Assemble a monitor program for the SBC V2 -# -$(OBJ)dbgmon.rel: $(SRC)dbgmon.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)dbgmon.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.lst $(LST) - -########################################################### - -# Build host based tools ( dwgh2b, jrch2b, load, verify) - -$(DWGH2B): $(SRC)dwgh2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)dwgh2b.c -o $(BIN)dwgh2b$(EXE) - -# -# Compile John Coffman's hex2bin program -# -$(JRCH2B): $(SRC)jrch2b.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)jrch2b.c -o $(BIN)jrch2b$(EXE) - $(QUIET)$(COPY) $(COPYFLG) $(BIN)jrch2b $(BIN)jrcb2h - -# -# Compile Doug's "load" program -# -$(LOAD): $(SRC)load.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)load.c -o $(BIN)load$(EXE) - -$(SYSGEN): $(SRC)sysgen.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)sysgen.c -o $(BIN)sysgen$(EXE) - -# -# Compile Doug's verif program that compares binary file regions -# -$(VERIFY): $(SRC)verify.c Makefile $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)verify.c -o $(BIN)verify - -$(BIN)lechocr: $(SRC)lechocr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c -o $(BIN)lechocr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocr.c - $(QUIET)$(COPY) lechocr.exe $(BIN) - -$(BIN)lecholf: $(SRC)lecholf.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c -o $(BIN)lecholf - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c - $(COPY) lecholf.exe $(BIN) - -$(BIN)lechocrlf: $(SRC)lechocrlf.c $(MK) - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lechocrlf.c -o $(BIN)lechocrlf - -$(BIN)lecholfcr: $(SRC)lecholfcr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - -############################################################ - -# Builder specific utility rules - -dwginstall: - $(COPY) $(COMFILES) ~/Documents/devobox/cdrive - -############################################################ - -# -# Delete all dynamically generated files that don't need to be -# saved. -# -clean: - $(QUIET)$(DEL) $(DELFLG) *.hex *.ihx *.lst *.rel *.rst *.lnk *.lk - $(QUIET)$(DEL) $(DELFLG) *.sym *.map *.noi *.asm *.com *.ini *.bin - $(QUIET)$(DEL) $(DELFLG) obj$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) bin$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) com$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) rom$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) tmp$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) map$(DELIM)*.* - $(QUIET)$(DEL) $(DELFLG) lst$(DELIM)*.* - -################## -# eof - Makefile # -################## diff --git a/branches/s100/cpurom/exp/makefile.mac b/branches/s100/cpurom/exp/makefile.mac deleted file mode 100644 index 506bc8c0..00000000 --- a/branches/s100/cpurom/exp/makefile.mac +++ /dev/null @@ -1,26 +0,0 @@ -# ubios/makefile.mac 8/8/2011 dwg - - -DELIM = / -SPREFIX = /Developer/sdcc -SDAS = $(SPREFIX)/bin/sdasz80 -SDASFLG = -plosff -Iinc -SDCC = $(SPREFIX)/bin/sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)/share/sdcc/lib/z80 -SDLD = $(SPREFIX)/bin/sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCFLG = -I inc -COPY = cp -DEL = rm -DELFLG = -f -# use native ECHO o Mac OS X -ECHO = echo -REN = mv -EXE = - -include common.mak - - - diff --git a/branches/s100/cpurom/exp/makefile.win b/branches/s100/cpurom/exp/makefile.win deleted file mode 100644 index c324b33d..00000000 --- a/branches/s100/cpurom/exp/makefile.win +++ /dev/null @@ -1,24 +0,0 @@ - -DELIM = \ -SDRIVE = C: -SPREFIX = $(SDRIVE)\sdcc -SDAS = $(SPREFIX)\bin\sdasz80 -SDASFLG = -plosff -SDCC = $(SPREFIX)\bin\sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)\lib\z80 -SDLD = $(SPREFIX)\bin\sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCOPT = -I inc -COPY = copy -DEL = erase -DELFLG = /Q -REN = rename -ECHO = $(BIN)lecholf -EXE = .exe - -.include common.mak - - diff --git a/branches/s100/cpurom/inc/agm1264f.h b/branches/s100/cpurom/inc/agm1264f.h deleted file mode 100644 index b32019f9..00000000 --- a/branches/s100/cpurom/inc/agm1264f.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * agm1264f.h 5/14/2011 dwg - - * 8 lines of 21 characters - * - */ - -/* - - 1 2 - 123456789012345678901 - --------------------- -1 |1234 11223344 1234 | -2 | | -3 | | -4 | | -5 | | -6 | | -7 | | -8 | | - --------------------- - -/* This is a 7x5 character layout showing how much text data can be display on the agm1264f - 1 1 1 - 1 2 3 4 5 6 7 8 9 0 1 2 - 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 - --------------------------------------------------------------------------------------------------------------------------------- - 0 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 1 | 2 | - 2 | 3 | - 3 | 4 | - 4 | 5 | - 5 | 6 | - 6 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | | - 8 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 9 | 2 | -10 | 3 | - 1 | 4 | - 2 | 5 | - 3 | 6 | - 4 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 5 | | - 6 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | 2 | - 8 | 3 | - 9 | 4 | -20 | 5 | - 1 | 6 | - 2 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 3 | | - 4 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 5 | 2 | - 6 | 3 | | - 7 | 4 | - 8 | 5 | - 9 | 6 | -30 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 1 | | - 2 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 3 | 2 | - 4 | 3 | - 5 | 4 | - 6 | 5 | - 7 | 6 | - 8 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 9 | | -40 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 1 | 2 | - 2 | 3 | - 3 | 4 | - 4 | 5 | - 5 | 6 | - 6 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | | - 8 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 9 | 2 | -50 | 3 | - 1 | 4 | - 2 | 5 | - 3 | 6 | - 4 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 5 | | - 6 | 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 7 | 2 | - 8 | 3 | - 9 | 4 | -60 | 5 | - 1 | 6 | - 2 | 72345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 12345 | - 3 | | - --------------------------------------------------------------------------------------------------------------------------------- -*/ - - diff --git a/branches/s100/cpurom/inc/cpmbdos.h b/branches/s100/cpurom/inc/cpmbdos.h deleted file mode 100644 index 6bb522db..00000000 --- a/branches/s100/cpurom/inc/cpmbdos.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * CP/M-80 v2.2 BDOS Interfaces - * Copyright (C) Douglas W. Goodall - * For Non-Commercial use by N8VEM - * 5/10/2011 dwg - initial version -*/ -#define EXIT_SUCCESS 0 -#define EXIT_FAILURE 1 - -#define C_READ 1 -#define C_WRITE 2 -#define A_READ 3 -#define A_WRITE 4 -#define L_WRITE 5 -#define C_RAWIO 6 -#define GETIOBYTE 7 -#define SETIOBYTE 8 -#define C_WRITESTR 9 -#define C_READSTR 10 -#define F_OPEN 15 -#define F_CLOSE 16 -#define F_DELETE 19 -#define F_READ 20 -#define F_WRITE 21 -#define F_MAKE 22 -#define F_RENAME 23 -#define DRV_LOGINVEC 24 -#define DRV_GET 25 -#define F_DMAOFF 26 -#define DRV_ALLOCVEC 27 -#define DRV_SETRO 28 -#define DRV_ROVEC 29 -#define F_ATTRIB 30 -#define DRV_DPB 31 -#define F_USERNUM 32 -#define F_READRAND 33 -#define F_WRITERAND 34 -#define F_SIZE 35 -#define F_RANDREC 36 -#define DRV_RESET 37 -#define F_WRITEZF 40 - - -struct BDOSCALL { - unsigned char func8; - unsigned int parm16; -}; - -unsigned char cpmbdos(struct BDOSCALL *p); - -struct FCB { - unsigned char drive; - char filename[8]; - char filetype[3]; - unsigned char ex; - unsigned char s1; - unsigned char s2; - unsigned char rc; - unsigned char al[16]; - unsigned char cr; - unsigned char r0; - unsigned char r1; - unsigned char r2; -}; - -struct READSTR { - unsigned char size; - unsigned char len; - char bytes[80]; - } rsbuffer; - -struct BDOSCALL readstr = { C_READSTR, { (unsigned int)&rsbuffer } }; - -char * mygets(char *p) -{ - memset(rsbuffer.bytes,0,sizeof(rsbuffer.bytes)); - rsbuffer.size = sizeof(rsbuffer.bytes); - rsbuffer.len = 0; - cpmbdos(&readstr); - rsbuffer.bytes[rsbuffer.len] = '\n'; - strcpy(p,rsbuffer.bytes); - return p; -} - -#define gets mygets - -/*****************/ -/* eof - cpm80.h */ -/*****************/ diff --git a/branches/s100/cpurom/inc/cprintf.h b/branches/s100/cpurom/inc/cprintf.h deleted file mode 100644 index 925275e3..00000000 --- a/branches/s100/cpurom/inc/cprintf.h +++ /dev/null @@ -1,7 +0,0 @@ -/* cprintf.h */ - -int cprintf(const char * fmt, ...); - -#define printf cprintf - - diff --git a/branches/s100/cpurom/inc/diskio.h b/branches/s100/cpurom/inc/diskio.h deleted file mode 100644 index 9a198457..00000000 --- a/branches/s100/cpurom/inc/diskio.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * diskio.h - * - */ - -__sfr __at (DISKIO_IDE + 0x00) pIDELO; -__sfr __at (DISKIO_IDE + 0x01) pIDEERR; -__sfr __at (DISKIO_IDE + 0x02) pIDESECTC; -__sfr __at (DISKIO_IDE + 0x03) pIDESECTN; -__sfr __at (DISKIO_IDE + 0x04) pIDECYLLO; -__sfr __at (DISKIO_IDE + 0x05) pIDECYLHI; -__sfr __at (DISKIO_IDE + 0x06) pIDEHEAD; -__sfr __at (DISKIO_IDE + 0x07) pIDESTTS; -__sfr __at (DISKIO_IDE + 0x08) pIDEHI; -__sfr __at (DISKIO_IDE + 0x0E) pIDECTRL; - -__sfr __at (DISKIO_FLP + 0x06) pFMSR; -__sfr __at (DISKIO_FLP + 0x07) pFDATA; -__sfr __at (DISKIO_FLP + 0x0A) pFLATCH; -__sfr __at (DISKIO_FLP + 0x0C) pFDMA; - -/* - * - * eof - diskio.h - * - */ - - diff --git a/branches/s100/cpurom/inc/ds1302.h b/branches/s100/cpurom/inc/ds1302.h deleted file mode 100644 index 4898ec5a..00000000 --- a/branches/s100/cpurom/inc/ds1302.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * - * ds1302 Dallas Real Time Clock module - * - */ - - diff --git a/branches/s100/cpurom/inc/i8255.h b/branches/s100/cpurom/inc/i8255.h deleted file mode 100644 index 11761e9c..00000000 --- a/branches/s100/cpurom/inc/i8255.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * i8255.h Intel 8255 - * - */ - - -void uart_init(U8 baud); -U8 uart_conin(void); -void uart_conout(U8 data); - -/* - * - * eof - i8255.h - * - */ diff --git a/branches/s100/cpurom/inc/jrctypes.h b/branches/s100/cpurom/inc/jrctypes.h deleted file mode 100644 index c97ed7eb..00000000 --- a/branches/s100/cpurom/inc/jrctypes.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __MYTYPES_H -#define __MYTYPES_H 1 - -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned long dword; - - -#ifdef __SDCC__ -#define outp(port,byte) port = (byte) -#define inp(port) (port) -#endif - -#define nelem(x) (sizeof(x)/sizeof(x[0])) - -#endif /* __MYTYPES_H */ diff --git a/branches/s100/cpurom/inc/ns16550.h b/branches/s100/cpurom/inc/ns16550.h deleted file mode 100644 index 6e81ada9..00000000 --- a/branches/s100/cpurom/inc/ns16550.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * n16550.h National 16550 - * - */ - -#define UART_DLAB 0x80 -#define UART_BAUD_9600 12 -#define UART_RDA 0x01 -#define UART_TBE 0x20 - -/* - * - * eof - n16550.h - * - */ diff --git a/branches/s100/cpurom/inc/ns16550.inc b/branches/s100/cpurom/inc/ns16550.inc deleted file mode 100644 index f405d38a..00000000 --- a/branches/s100/cpurom/inc/ns16550.inc +++ /dev/null @@ -1,8 +0,0 @@ -; ns16550.inc 8/7/2011 dwg - National 16550 - -UART_DLAB = 0x80 -UART_BAUD_9600 = 12 -UART_RDA = 0x01 -UART_TBE = 0x20 - -; eof - ns16550.inc diff --git a/branches/s100/cpurom/inc/portab.h b/branches/s100/cpurom/inc/portab.h deleted file mode 100644 index 6a814a13..00000000 --- a/branches/s100/cpurom/inc/portab.h +++ /dev/null @@ -1,12 +0,0 @@ -/************/ -/* portab.h */ -/************/ - -#define TRUE 1 -#define FALSE 0 - -#define U8 unsigned char - -/******************/ -/* eof - portab.h */ -/******************/ diff --git a/branches/s100/cpurom/inc/sbcv2.h b/branches/s100/cpurom/inc/sbcv2.h deleted file mode 100644 index 83951d3d..00000000 --- a/branches/s100/cpurom/inc/sbcv2.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * sbcv2.h - Macros describing the N8VEM SBC V2 - * - */ - -#define SBCV2 - -/* set i/o base to first block of 32 addresses - possible are 0x00 0x20 0x40 0x60 0x80 0xA0 0xC0 0xE0 - depending oon setting of dip switches on board -*/ - -#define SBCV2_IO_BASE 0x00 -#define UART_IO_BASE ( SBCV2_IO_BASE + 0x68 ) - -__sfr __at (UART_IO_BASE+0) rUART_RBR; -__sfr __at (UART_IO_BASE+0) wUART_THR; -__sfr __at (UART_IO_BASE+0) wUART_DIV_LO; -__sfr __at (UART_IO_BASE+1) wUART_DIV_HI; - -__sfr __at (UART_IO_BASE+1) wUART_IER; -__sfr __at (UART_IO_BASE+2) rUART_IIR; -__sfr __at (UART_IO_BASE+3) wUART_LCR; -__sfr __at (UART_IO_BASE+4) wUART_MCR; -__sfr __at (UART_IO_BASE+5) rUART_LSR; -__sfr __at (UART_IO_BASE+6) rUART_MSR; -__sfr __at (UART_IO_BASE+7) wUART_FCR; - - -#define DISKIO_IDE 0x20 - -#define DISKIO_FLP 0x30 - -#define PPORT 0x60 - -#define MPCL 0x70 -__sfr __at (MPCL + 0x08) pMPCL_RAM; -__sfr __at (MPCL + 0x0c) pMPCL_ROM; - -#define RAMTARG_CPM 0x2000 -#define ROMSTART_CPM 0x0000 -#define CCPSIZ_CPM 0x2000 - -#define LOADER_ORG 0x0000 -#define CPM_ORG 0x0A00 -#define MON_ORG 0x3800 -#define ROM_G 0x5000 -#define ROM_F 0x8000 -/* -#define VDU_DRV 0xF8100 -*/ - diff --git a/branches/s100/cpurom/inc/scsi2ide.h b/branches/s100/cpurom/inc/scsi2ide.h deleted file mode 100644 index 023b8a99..00000000 --- a/branches/s100/cpurom/inc/scsi2ide.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * scsi2ide.h - Macros describing the N8VEM SCSI2IDE - * Friday July 29, 2011 Douglas W. Goodall - * - */ - -#define SCSI2IDE - -/* set i/o base to first block of 32 addresses - possible are 0x00 0x20 0x40 0x60 0x80 0xA0 0xC0 0xE0 - depending oon setting of dip switches on board -*/ - -#define SCSI2IDE_IO_BASE 0x00 - -#define IDE_IO_BASE ( SCSI2IDE_IO_BASE + 0 ) -#define SCSI_IO_BASE ( SCSI2IDE_IO_BASE + 8 ) -#define UART_IO_BASE ( SCSI2IDE_IO_BASE + 16 ) -#define DACK_IO_BASE ( SCSI2IDE_IO_BASE + 24 ) - -__sfr __at (UART_IO_BASE+0) rUART_RDR; -__sfr __at (UART_IO_BASE+0) wUART_TDR; -__sfr __at (UART_IO_BASE+0) wUART_DIV_LO; -__sfr __at (UART_IO_BASE+1) wUART_DIV_HI; -__sfr __at (UART_IO_BASE+1) wUART_IER; -__sfr __at (UART_IO_BASE+2) rUART_IIR; -__sfr __at (UART_IO_BASE+3) wUART_LCR; -__sfr __at (UART_IO_BASE+4) wUART_MCR; -__sfr __at (UART_IO_BASE+5) rUART_LSR; -__sfr __at (UART_IO_BASE+6) rUART_MSR; -__sfr __at (UART_IO_BASE+7) wUART_FCR; - -__sfr __at (SCSI_IO_BASE+0) rSCSI_CSCSID; -__sfr __at (SCSI_IO_BASE+0) wSCSI_OD; -__sfr __at (SCSI_IO_BASE+1) rwSCSI_IC; -__sfr __at (SCSI_IO_BASE+2) rwSCSI_M; -__sfr __at (SCSI_IO_BASE+3) rwSCSI_TC; -__sfr __at (SCSI_IO_BASE+4) rSCSI_CSCSIBS; -__sfr __at (SCSI_IO_BASE+4) wSCSI_SE; -__sfr __at (SCSI_IO_BASE+5) rSCSI_BS; -__sfr __at (SCSI_IO_BASE+5) wSCSI_SDMAS; -__sfr __at (SCSI_IO_BASE+6) rSCSI_ID; -__sfr __at (SCSI_IO_BASE+6) wSCSI_SDMATR; -__sfr __at (SCSI_IO_BASE+7) rSCSI_RPI; -__sfr __at (SCSI_IO_BASE+7) wSCSI_SDMAIR; - diff --git a/branches/s100/cpurom/inc/scsi2ide.inc b/branches/s100/cpurom/inc/scsi2ide.inc deleted file mode 100644 index 64b938ca..00000000 --- a/branches/s100/cpurom/inc/scsi2ide.inc +++ /dev/null @@ -1,20 +0,0 @@ -; scsi2ide.inc 8/7/2011 dwg - macros describing the N8VEM SCSI2IDE - -SCSI2IDE_IO_BASE = 0 - -UART_IO_BASE = SCSI2IDE_IO_BASE+16 - -rUART_RDR = UART_IO_BASE + 0 -wUART_TDR = UART_IO_BASE + 0 -wUART_DIV_LO = UART_IO_BASE + 0 -wUART_DIV_HI = UART_IO_BASE + 1 -wUART_IER = UART_IO_BASE + 1 -rUART_IIR = UART_IO_BASE + 2 -wUART_LCR = UART_IO_BASE + 3 -wUART_MCR = UART_IO_BASE + 4 -rUART_LSR = UART_IO_BASE + 5 -rUART_MSR = UART_IO_BASE + 6 -wUART_FCR = UART_IO_BASE + 7 - -; eof - scsi2ide.inc - diff --git a/branches/s100/cpurom/inc/z53c80.h b/branches/s100/cpurom/inc/z53c80.h deleted file mode 100644 index 9a7039ed..00000000 --- a/branches/s100/cpurom/inc/z53c80.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * z53c80.h Zilog Z53C8003VSC - * - */ - -/* -__sfr __at (UART + 0) pPORTA; -__sfr __at (UART + 1) pPORTB; -__sfr __at (UART + 2) pPORTC; -__sfr __at (UART + 3) pCNTRL; -*/ - -void scsi_init(void); - -/* -U8 uart_conin(void); -void uart_conout(U8 data); -*/ - -/* - * - * eof - z53c80.h - * - */ diff --git a/branches/s100/cpurom/makeclean.bat b/branches/s100/cpurom/makeclean.bat deleted file mode 100644 index 64ef22dd..00000000 --- a/branches/s100/cpurom/makeclean.bat +++ /dev/null @@ -1,3 +0,0 @@ -wmake -f makefile.xp clean -rem wmake -f makefile.xp -dir rom diff --git a/branches/s100/cpurom/makecpurom.bat b/branches/s100/cpurom/makecpurom.bat deleted file mode 100644 index 5798c184..00000000 --- a/branches/s100/cpurom/makecpurom.bat +++ /dev/null @@ -1,3 +0,0 @@ -wmake -f makefile.xp clean -wmake -f makefile.xp etools rom\scsiscrm.rom -dir rom diff --git a/branches/s100/cpurom/makefile.xp b/branches/s100/cpurom/makefile.xp deleted file mode 100644 index 498a5396..00000000 --- a/branches/s100/cpurom/makefile.xp +++ /dev/null @@ -1,646 +0,0 @@ -######################################################## -# Makefile for Doug's Unified BIOS 1/28/2013 # -# The BIOS and associated utilities are generated # -# using the Small Device C Compiler (SDCC) & tools # -# With multiplatform enhancements by John Coffman # -# # -# sdcc.l00 added because stupid Windoze 'echo' appends # -# a confusing SPACE to the end of every line. # -######################################################## - -##################################################### -# SPREFIX tells where the SDCC package in installed # -# The SDCC package is used to assemble Z80 portions # -# of the software such as the ROM and perhaps some # -# .COM files such as FDISK. # -##################################################### - -################################################################# -# TPREFIX tells where the host development tools are installed. # -# The host tools are used to manipulate the Z80 objects after # -# the basic assemblies and compilations have been completed. # -################################################################# - -################################################################### -# SDCC is not available on the DOS host, so something else may be # -# used at the descretion of the builder. (TASM for instance). # -################################################################### - -################################################################### -# The COPY, DEL and RENAME macros are used to customize the build # -# rules for the host enviroonment. # -################################################################### - -#------------------------------------------- -# Choose one only, then Make will work for -# your platform. - -#CFG = $(shell uname) -# Mac OS X returns 'Darwin' -# Linux returns 'Linux' - -#CFG = dos -#CFG = linux -#CFG = macosx -CFG = windows - -#------------------------------------------- - -DELIM = \ -SDRIVE = C: -SPREFIX = $(SDRIVE)\Program Files\sdcc -#SDAS = $(SPREFIX)\bin\sdasz80 -SDAS = sdasz80 -SDASFLG = -plosff -Iinc -#SDCC = $(SPREFIX)\bin\sdcc -SDCC = sdcc -SDCCFLG = -c -mz80 -D__SDCC__=1 -I inc -SDCCLIB = $(SPREFIX)\lib\z80 -#SDLD = $(SPREFIX)\bin\sdldz80 -SDLD = sdldz80 -SDLDFLG = -TPREFIX = -TCC = gcc -TCCOPT = -I inc -COPY = copy -DEL = erase -DELFLG = /Q -REN = rename - -# This is special handling for John Coffman to get around funky windows -# behavior where echo adds spurious space o end f line -# ECHO = { lecho | lechocr | lecholf | lechocrlf | lecholfcr } - -#ECHO = $(BIN)$(DELIM)lechocr -ECHO = $(BIN)lecholf - -EXE = .exe - - -#------------------------------------------- -############################################################ - -# Misc other macros - -BIN = bin$(DELIM) -COM = com$(DELIM) -INC = inc$(DELIM) -LIB = lib$(DELIM) -LST = lst$(DELIM) -MAP = map$(DELIM) -OBJ = obj$(DELIM) -REF = ref$(DELIM) -ROM = rom$(DELIM) -SRC = src$(DELIM) -TMP = tmp$(DELIM) - -# CP/M-80 v2.2 Command files written in SDCC -COMFILES = $(COM)copyfile.com $(COM)fdisk.com - -# Components used by CP/M-80 v2.2 Command files -COMRELS = $(OBJ)cpm0.rel $(OBJ)cpmbdos.rel $(OBJ)cprintf.rel - -# Components of ROM image containing CP/M for SBC V2 -CPMRELS = $(OBJ)crt0.rel $(OBJ)dbgmon.rel $(OBJ)bdosb01.rel $(OBJ)ccpb03.rel $(OBJ)cbios.rel - -# Components of ROM image used in test protocols -ROMRELS = $(OBJ)crt0jplp.rel $(OBJ)crt0scrm.rel - - -# Components that control hardware in SBC V2 -SBCV2HW = - -# Components that control hardware in the SCSI2IDE -SCSI2IDEHW = $(OBJ)z53c80.rel - -FDISK = $(BIN)fdisk$(EXE) -DWGH2B = $(BIN)dwgh2b$(EXE) -INCFILES = $(INC)cpmbdos.h $(INC)cprintf.h $(INC)portab.h -JRCH2B = $(BIN)jrch2b$(EXE) -LOAD = $(BIN)load$(EXE) -MK = Makefile -#QUIET = @ - -# ROM images for SBC V2 and N8 -ROMFILES = $(ROM)scsiscrm.rom $(ROM)scsijplp.rom $(ROM)n8.rom $(ROM)baseline.rom $(ROM)n8.rom -SCSI2IDE = $(ROM)scsi2ide.rom - -SYSGEN = $(BIN)sysgen$(EXE) -VERIFY = $(BIN)verify$(EXE) - -# C programs compiled on host system used in build -TOOLS = $(FDISK) $(DWGH2B) $(LOAD) $(JRCH2B) $(SYSGEN) - -# Versions of 'echo' compiled on host system -ETOOLS = $(BIN)lechocr.exe $(BIN)lecholf.exe $(BIN)lechocrlf.exe $(BIN)lecholfcr.exe - -# dribdos.rel is not part of the production set yet -##TEST = dribdos.rel - -############################################################ - -all: $(ETOOLS) $(TOOLS) $(BINFILES) $(COMFILES) $(CPMFILES) $(ROMFILES) - -#all: $(TEST) $(ROMFILES) $(COMFILES) - -etools: $(ETOOLS) -roms: $(ROMFILES) -scsi2ide: $(SCSI2IDE) - -############################################################ - -# A test assembly of DRI source code for BDOS (from SIMH) -dribdos.rel: $(SRC)dribdos.s - $(QUIET)$(SDAS) $(SDASFLG) dribdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dribdos.lst $(LST) - -############################################################ -############################################################ - -# Build SCSIJPLP ROM image - -$(ROM)scsijplp.rom: $(OBJ)scsijplp.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.bin $(ROM)scsijplp.rom - $(QUIET)$(DEL) $(DELFLG) scsijplp.* - -$(OBJ)scsijplp.bin: $(OBJ)scsijplp.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsijplp - -$(OBJ)scsijplp.hex: $(OBJ)scsijplp.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsijplp.ihx $(OBJ)scsijplp.hex - -$(OBJ)scsijplp.ihx: $(OBJ)crt0jplp.rel $(TMP)scsijplp.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lk - $(QUIET)$(COPY) $(TMP)scsijplp.arf $(TMP)scsijplp.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsijplp.lnk - $(QUIET)$(COPY) $(COPYFLG) scsijplp.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsijplp.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsijplp.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsijplp.arf - $(ECHO) -i scsijplp.ihx >> $(TMP)scsijplp.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsijplp.arf - $(ECHO) -l z80 >> $(TMP)scsijplp.arf - $(ECHO) $(OBJ)crt0jplp.rel >> $(TMP)scsijplp.arf - $(ECHO) -e >> $(TMP)scsijplp.arf - -############################################################ -############################################################ -############################################################ -############################################################ - -# Build SCSISCRM ROM image - -$(ROM)scsiscrm.rom: $(OBJ)scsiscrm.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.bin $(ROM)scsiscrm.rom - $(QUIET)$(DEL) $(DELFLG) scsiscrm.* - -$(OBJ)scsiscrm.bin: $(OBJ)scsiscrm.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsiscrm - -$(OBJ)scsiscrm.hex: $(OBJ)scsiscrm.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsiscrm.ihx $(OBJ)scsiscrm.hex - -$(OBJ)scsiscrm.ihx: $(OBJ)crt0scrm.rel $(TMP)scsiscrm.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lk - $(QUIET)$(COPY) $(TMP)scsiscrm.arf $(TMP)scsiscrm.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsiscrm.lnk - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsiscrm.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsiscrm # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsiscrm.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsiscrm.arf - $(ECHO) -i scsiscrm.ihx >> $(TMP)scsiscrm.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsiscrm.arf - $(ECHO) -l z80 >> $(TMP)scsiscrm.arf - $(ECHO) $(OBJ)crt0scrm.rel >> $(TMP)scsiscrm.arf - $(ECHO) -e >> $(TMP)scsiscrm.arf - -############################################################ -############################################################ - - - - - -############################################################ -############################################################ - -# Build SCSI2IDE ROM image - -$(ROM)scsi2ide.rom: $(OBJ)scsi2ide.bin $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.bin $(ROM)scsi2ide.rom - $(QUIET)$(DEL) $(DELFLG) scsi2ide.* - -$(OBJ)scsi2ide.bin: $(OBJ)scsi2ide.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)scsi2ide - -$(OBJ)scsi2ide.hex: $(OBJ)scsi2ide.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)scsi2ide.ihx $(OBJ)scsi2ide.hex - -$(OBJ)scsi2ide.ihx: $(CPMRELS) $(SCSI2IDEHW) $(OBJ)scsi2ide.rel $(TMP)scsi2ide.arf $(MK) - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lk - $(QUIET)$(COPY) $(TMP)scsi2ide.arf $(TMP)scsi2ide.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)scsi2ide.lnk - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.map $(MAP) - -######################################################### -# Dynamically generate linker control file for scsi2ide # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)scsi2ide.arf: $(MK) - $(ECHO) -mjx > $(TMP)scsi2ide.arf - $(ECHO) -i scsi2ide.ihx >> $(TMP)scsi2ide.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)scsi2ide.arf - $(ECHO) -l z80 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)scsi2ide.arf -# $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)scsi2ide.arf - $(ECHO) $(OBJ)scsi2ide.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)scsi2ide.arf -# $(ECHO) $(OBJ)cbios.rel >> $(TMP)scsi2ide.arf - $(ECHO) -e >> $(TMP)scsi2ide.arf - -######################################################## -# Compile C portion of the scsi2ide EEPROM Image -$(OBJ)scsi2ide.rel: $(SRC)scsi2ide.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)scsi2ide.c - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) scsi2ide.lst $(LST) - - -############################################################ -############################################################ - -# Build SBC V2 ROM image - -$(ROM)baseline.rom: $(OBJ)baseline.bin $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.bin $(ROM)baseline.rom - $(QUIET)$(DEL) $(DELFLG) baseline.* - -$(OBJ)baseline.bin: $(OBJ)baseline.hex $(DWGH2B) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)baseline - -$(OBJ)baseline.hex: $(OBJ)baseline.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)baseline.ihx $(OBJ)baseline.hex - -$(OBJ)baseline.ihx: $(CPMRELS) $(SBCV2HW) $(OBJ)baseline.rel $(TMP)baseline.arf $(MK) - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lk - $(QUIET)$(COPY) $(TMP)baseline.arf $(TMP)baseline.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)baseline.lnk - $(QUIET)$(COPY) $(COPYFLG) baseline.ihx $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.map $(MAP) - -######################################################### -# Dynamically generate linker control file for baseline # -# (now uses the macro controlled ECHO feature # -######################################################### -$(TMP)baseline.arf: $(MK) - $(ECHO) -mjx > $(TMP)baseline.arf - $(ECHO) -i baseline.ihx >> $(TMP)baseline.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)baseline.arf - $(ECHO) -l z80 >> $(TMP)baseline.arf - $(ECHO) -b _CCPB03 = 0xD000 >> $(TMP)baseline.arf - $(ECHO) -b _BDOSB01 = 0xD800 >> $(TMP)baseline.arf - $(ECHO) -b _CBIOS = 0xE600 >> $(TMP)baseline.arf - $(ECHO) -b _DBGMON = 0x8000 >> $(TMP)baseline.arf - $(ECHO) $(OBJ)crt0.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)baseline.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)baseline.arf - $(ECHO) $(OBJ)cbios.rel >> $(TMP)baseline.arf - $(ECHO) -e >> $(TMP)baseline.arf - -######################################################## -# Compile C portion of the Baseline PROM Image -$(OBJ)baseline.rel: $(SRC)baseline.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) -c $(SRC)baseline.c - $(QUIET)$(COPY) $(COPYFLG) baseline.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) baseline.lst $(LST) - -############################################################ - -# Build N8 ROM image - -# -# Save the resulting merged image in the Rom folder -# -$(ROM)n8.rom: $(OBJ)n8-romim.bin $(MK) - $(QUIET)$(COPY) $(OBJ)n8-romim.bin $(ROM)n8.rom - $(QUIET)$(DEL) $(DELFLG) n8.* - -# -# Convert the Intel hex file into a binary, similar -# to the results of the "copy /B ..." -# -$(OBJ)n8-romim.bin: $(OBJ)sysimage.hex $(REF)n8-romim.ref $(SYSGEN) $(HEX2BIN) $(MK) - $(QUIET)$(DWGH2B) $(OBJ)sysimage - $(QUIET)$(COPY) $(REF)n8-romim.ref $(OBJ)n8-romim.bin - $(QUIET)$(SYSGEN) -i $(OBJ)sysimage.bin $(OBJ)n8-romim.bin - -# -# Take the output of the linker and rename to the more -# recognizable .hex form and the expected name "sysimage.hex" -# -$(OBJ)sysimage.hex: $(OBJ)n8.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)n8.ihx $(OBJ)sysimage.hex - -# -# Combine the independently assembled components into one piece -# and output Intel hex file (ihx) -# -$(OBJ)n8.ihx: $(OBJ)loadern8.rel $(OBJ)dbgmon.rel $(OBJ)ccpb03.rel $(OBJ)bdosb01.rel $(OBJ)cbiosn8.rel $(TMP)n8.arf $(MK) - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lk - $(QUIET)$(COPY) $(TMP)n8.arf $(TMP)n8.lnk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)n8.lnk - $(QUIET)$(COPY) $(COPYFLG) n8.ihx $(OBJ)n8.ihx - $(QUIET)$(COPY) $(COPYFLG) n8.map $(MAP) - -$(OBJ)cbiosn8.rel: $(SRC)cbiosn8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbiosn8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbiosn8.lst $(LST) - -$(OBJ)loadern8.rel: $(SRC)loadern8.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)loadern8.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)loadern8.lst $(LST) - -######################################################## -# Dynamically generate the linker control file for N8 # -# Now uses the macro controlled ECHO feature # -######################################################## -$(TMP)n8.arf: Makefile - $(ECHO) -mjx > $(TMP)n8.arf - $(ECHO) -i n8.ihx >> $(TMP)n8.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)n8.arf - $(ECHO) -l z80 >> $(TMP)n8.arf - $(ECHO) -b _CCPB03 = 0x0900 >> $(TMP)n8.arf - $(ECHO) -b _BDOSB01 = 0x1100 >> $(TMP)n8.arf - $(ECHO) -b _CBIOS = 0x1f00 >> $(TMP)n8.arf - $(ECHO) $(OBJ)loadern8.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)dbgmon.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)ccpb03.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)bdosb01.rel >> $(TMP)n8.arf - $(ECHO) $(OBJ)cbiosn8.rel >> $(TMP)n8.arf - $(ECHO) -e >> $(TMP)n8.arf - -############################################################ - -# Hardware specific assemblies (most likely used by BIOS's) - -# -# Assemble hardware control code for the Zilog Z53C8003V5C -# -$(OBJ)z53c80.rel: $(SRC)z53c80.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)z53c80.c - $(QUIET)$(COPY) $(COPYFLG) z53c80.rel $(OBJ) - $(QUIET)$(DEL) $(DELFLG) z53c80.* - -# -# Compile ersatz printf routine for use in CP/M-80 command files -# -$(OBJ)cprintf.rel: $(SRC)cprintf.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)cprintf.c - $(QUIET)$(COPY) $(COPYFLG) cprintf.rel obj - $(QUIET)$(DEL) $(DELFLG) cprintf.* - -############################################################ - -# Build CP/M 2.2 command files (copyfile.com, fdisk.com) - -#----------------------------------------------------------- - -$(COM)copyfile.com: $(OBJ)copyfile.com $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.com $(COM)copyfile.com - $(QUIET)$(DEL) $(DELFLG) copyfile.* - -$(OBJ)copyfile.com: $(OBJ)copyfile.hex $(LOAD) $(BINFILES) $(MK) - $(QUIET)$(LOAD) $(OBJ)copyfile - -$(OBJ)copyfile.hex: $(OBJ)copyfile.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)copyfile.ihx $(OBJ)copyfile.hex - -$(OBJ)copyfile.ihx: $(OBJ)copyfile.rel $(COMRELS) $(TMP)copyfile.arf $(MK) - $(QUIET)$(COPY) $(TMP)copyfile.arf $(TMP)copyfile.lnk - - $(QUIET)$(SDLD) $(LOPTS) -nf $(TMP)copyfile.lnk - $(QUIET)$(COPY) $(COPYFLG) copyfile.ihx obj - $(QUIET)$(COPY) $(COPYFLG) copyfile.map map - -############################################################## -# Dynamicaly create linker command file for copyfile utility # -# Now uses the macro controlled ECHO feature # -############################################################## -$(TMP)copyfile.arf: Makefile - $(ECHO) -mjx > $(TMP)copyfile.arf - $(ECHO) -i copyfile.ihx >> $(TMP)copyfile.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)copyfile.arf - $(ECHO) -l z80 >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)copyfile.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)copyfile.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)copyfile.arf - $(ECHO) -e >> $(TMP)copyfile.arf - -$(OBJ)copyfile.rel: $(SRC)copyfile.c $(MK) - $(QUIET)$(SDCC) $(SDCCFLG) $(SRC)copyfile.c - $(QUIET)$(COPY) copyfile.rel obj - $(QUIET)$(DEL) $(DELFLG) copyfile.rel -# ls obj - -#----------------------------------------------------------- - -# -# Use locally compiled 'load' command to covert Intel -# hex formal file to a binary CP/M-80 command file. -# -$(COM)fdisk.com: $(OBJ)fdisk.hex $(TOOLS) $(MK) - $(QUIET)$(BIN)load $(OBJ)fdisk - $(QUIET)$(COPY) $(COPYFLG) $(OBJ)fdisk.com com - $(QUIET)$(DEL) $(DELFLG) fdisk.* - -# -# rename 'ihx' output of linker to 'hex' - -$(OBJ)fdisk.hex: $(OBJ)fdisk.ihx $(MK) - $(QUIET)$(COPY) $(OBJ)fdisk.ihx $(OBJ)fdisk.hex - -$(OBJ)fdisk.ihx: $(OBJ)fdisk.rel $(TMP)fdisk.arf $(MK) - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(TMP)fdisk.arf $(TMP)fdisk.lk - $(QUIET)$(SDLD) $(SDLDFLG) -nf $(TMP)fdisk.lnk - $(QUIET)$(COPY) $(COPYFLG) fdisk.ihx $(OBJ)fdisk.ihx - $(QUIET)$(COPY) $(COPYFLG) fdisk.map map - -$(OBJ)fdisk.rel: $(SRC)fdisk.c $(INCFILES) $(MK) - $(QUIET)$(SDCC) -I inc $(SDCCFLG) $(SRC)fdisk.c - $(QUIET)$(COPY) $(COPYFLG) fdisk.rel $(OBJ) - -############################################################################ -# Dynamically created linker command file for fdisk utility (CP/M version) # -# Now uses macro controlled ECHO feature # -############################################################################ -$(TMP)fdisk.arf: $(MK) - $(ECHO) -mjx > $(TMP)fdisk.arf - $(ECHO) -i fdisk.ihx >> $(TMP)fdisk.arf - $(ECHO) -k $(SDCCLIB) >> $(TMP)fdisk.arf - $(ECHO) -l z80 >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpm0.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)fdisk.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cpmbdos.rel >> $(TMP)fdisk.arf - $(ECHO) $(OBJ)cprintf.rel >> $(TMP)fdisk.arf - $(ECHO) -e >> $(TMP)fdisk.arf - - -#----------------------------------------------------------- - -# Also build host version of fdisk for testing purposes - -$(BIN)fdisk$(EXE): $(SRC)fdisk.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)fdisk.c -o $(BIN)fdisk - -############################################################ - -# Build CP/M-80 Command File Structure Files - -$(OBJ)cpm0.rel: $(SRC)cpm0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpm0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpm0.lst $(LST) - -$(OBJ)cpmbdos.rel: $(SRC)cpmbdos.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cpmbdos.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cpmbdos.lst $(LST) - -############################################################ - -# Build ROM Image structure files - -$(OBJ)crt0.rel: $(SRC)crt0.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0.lst $(LST) - -$(OBJ)crt0jplp.rel: $(SRC)crt0jplp.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0jplp.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0jplp.lst $(LST) - -$(OBJ)crt0scrm.rel: $(SRC)crt0scrm.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)crt0scrm.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)crt0scrm.lst $(LST) - - - -$(OBJ)bdosb01.rel: $(SRC)bdosb01.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)bdosb01.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)bdosb01.lst $(LST) - -$(OBJ)ccpb03.rel: $(SRC)ccpb03.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)ccpb03.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)ccpb03.lst $(LST) -# -# Assemble hardware control code for SBC V2 -# -$(OBJ)cbios.rel: $(SRC)cbios.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)cbios.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)cbios.lst $(LST) - -# -# Assemble a monitor program for the SBC V2 -# -$(OBJ)dbgmon.rel: $(SRC)dbgmon.s $(MK) - $(QUIET)$(SDAS) $(SDASFLG) $(SRC)dbgmon.s - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.rel $(OBJ) - $(QUIET)$(COPY) $(COPYFLG) $(SRC)dbgmon.lst $(LST) - -########################################################### - -# Build host based tools ( dwgh2b, jrch2b, load, verify) - -$(DWGH2B): $(SRC)dwgh2b.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)dwgh2b.c -o $(BIN)dwgh2b$(EXE) - -# -# Compile John Coffman's hex2bin program -# -$(JRCH2B): $(SRC)jrch2b.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)jrch2b.c -o $(BIN)jrch2b$(EXE) -# $(QUIET)$(COPY) $(COPYFLG) $(BIN)jrch2b $(BIN)jrcb2h - -# -# Compile Doug's "load" program -# -$(LOAD): $(SRC)load.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)load.c -o $(BIN)load$(EXE) - -$(SYSGEN): $(SRC)sysgen.c $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)sysgen.c -o $(BIN)sysgen$(EXE) - -# -# Compile Doug's verif program that compares binary file regions -# -$(VERIFY): $(SRC)verify.c Makefile $(MK) - $(QUIET)$(TCC) $(TCCOPT) $(SRC)verify.c -o $(BIN)verify - -$(BIN)lechocr.exe: $(SRC)lechocr.c $(MK) -# $(QUIET)$(TCC) $(TCCOPT) $(SRC)lechocr.c -o $(BIN)lechocr - $(TCC) $(TCCOPT) $(SRC)lechocr.c -o lechocr.exe - $(COPY) lechocr.exe $(BIN) - -$(BIN)lecholf.exe: $(SRC)lecholf.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholf.c -o $(BIN)lecholf - $(TCC) $(TCCOPT) $(SRC)lecholf.c -o lecholf.exe - $(COPY) lecholf.exe $(BIN) - -$(BIN)lechocrlf.exe: $(SRC)lechocrlf.c $(MK) -# $(QUIET)$(TCC) $(TCCOPT) $(SRC)lechocrlf.c -o $(BIN)lechocrlf - $(TCC) $(TCCOPT) $(SRC)lechocrlf.c -o lechocrlf.exe - $(COPY) lechocrlf.exe $(BIN) - -$(BIN)lecholfcr.exe: $(SRC)lecholfcr.c $(MK) -# $(QUIET)$(TCC) $(TCCFLG) $(SRC)lecholfcr.c -o $(BIN)lecholfcr - $(TCC) $(TCCOPT) $(SRC)lecholfcr.c -o lecholfcr.exe - $(COPY) lecholfcr.exe $(BIN) - -############################################################ - -# Builder specific utility rules - -dwginstall: - $(COPY) $(COMFILES) ~/Documents/devobox/cdrive - -############################################################ - -# -# Delete all dynamically generated files that don't need to be -# saved. -# -clean: - $(QUIET)$(DEL) $(DELFLG) *.hex *.ihx *.lst *.rel *.rst *.lnk *.lk *.exe - $(QUIET)$(DEL) $(DELFLG) *.sym *.map *.noi *.asm *.com *.ini *.bin - $(QUIET)$(DEL) $(DELFLG) obj$(DELIM)*.* bin$(DELIM)*.* com$(DELIM)*.* rom$(DELIM)*.* tmp$(DELIM)*.* map$(DELIM)*.* lst$(DELIM)*.* - -################## -# eof - Makefile # -################## diff --git a/branches/s100/cpurom/makexp.bat b/branches/s100/cpurom/makexp.bat deleted file mode 100644 index 4040c97f..00000000 --- a/branches/s100/cpurom/makexp.bat +++ /dev/null @@ -1,3 +0,0 @@ -wmake -f makefile.xp clean -wmake -f makefile.xp -dir rom diff --git a/branches/s100/cpurom/ref/JRC0521.ZIP b/branches/s100/cpurom/ref/JRC0521.ZIP deleted file mode 100644 index 55eb7806..00000000 Binary files a/branches/s100/cpurom/ref/JRC0521.ZIP and /dev/null differ diff --git a/branches/s100/cpurom/ref/bdosb01.asm b/branches/s100/cpurom/ref/bdosb01.asm deleted file mode 100644 index b5883d94..00000000 --- a/branches/s100/cpurom/ref/bdosb01.asm +++ /dev/null @@ -1,2587 +0,0 @@ - .title "Digital Research BDOS, Version 2.2" - .page 49 - -ENDFIL .EQU 1 ;FILL FULL BDOS LENGTH -; -IOBYTE: .EQU 3 ; I/O DEFINITION BYTE. -TDRIVE: .EQU 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY: .EQU 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB: .EQU 5CH ; DEFAULT FILE CONTROL BLOCK. -TBUFF: .EQU 80H ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE: .EQU 100H ; TRANSIANT PROGRAM STORAGE AREA. -; -; SET CONTROL CHARACTER .EQUATES. -; -CNTRLC: .EQU 3 ; CONTROL-C -CNTRLE: .EQU 05H ; CONTROL-E -BS: .EQU 08H ; BACKSPACE -TAB: .EQU 09H ; TAB -LF: .EQU 0AH ; LINE FEED -FF: .EQU 0CH ; FORM FEED -CR: .EQU 0DH ; CARRIAGE RETURN -CNTRLP: .EQU 10H ; CONTROL-P -CNTRLR: .EQU 12H ; CONTROL-R -CNTRLS: .EQU 13H ; CONTROL-S -CNTRLU: .EQU 15H ; CONTROL-U -CNTRLX: .EQU 18H ; CONTROL-X -CNTRLZ: .EQU 1AH ; CONTROL-Z (END-OF-FILE MARK) -DEL: .EQU 7FH ; RUBOUT - -; CPM ORIGIN CALCULATE - -NK .EQU 59 ;SYSTEM SIZE -BASE .EQU (NK*1024)-5000H -CCPO .EQU BASE+3400H ;CCP ORIGIN -BDOSO .EQU BASE+3C00H ;BDOS ORIGIN -BIOSO .EQU BASE+4A00H ;BIOS ORIGIN - - .ORG BDOSO - .DB 0,0,0,0,0,0 ;OLD SERIAL NUMBER -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE: JP FBASE1 -; -; BDOS ERROR TABLE. -; -BADSCTR:.DW ERROR1 ; BAD SECTOR ON READ OR WRITE. -BADSLCT:.DW ERROR2 ; BAD DISK SELECT. -RODISK: .DW ERROR3 ; DISK IS READ ONLY. -ROFILE: .DW ERROR4 ; FILE IS READ ONLY. -; -; ENTRY INTO BDOS. (DE) OR (E) ARE THE PARAMETERS PASSED. THE -; FUNCTION NUMBER DESIRED IS IN REGISTER (C). -; E contains drive number if passing this -FBASE1: EX DE,HL ; SAVE THE (DE) PARAMETERS. - LD (PARAMS),HL - EX DE,HL - LD A,E ; AND SAVE REGISTER (E) IN PARTICULAR. - LD (EPARAM),A - LD HL,0 - LD (STATUS),HL ; CLEAR RETURN STATUS. - ADD HL,SP - LD (USRSTACK),HL ; SAVE USERS STACK POINTER. - LD SP,STKAREA ; AND SET OUR OWN. - XOR A ; CLEAR AUTO SELECT STORAGE SPACE. - LD (AUTOFLAG),A - LD (AUTO),A - LD HL,GOBACK ; SET RETURN ADDRESS. - PUSH HL - LD A,C ; GET FUNCTION NUMBER. - CP NFUNCTS ; VALID FUNCTION NUMBER? - RET NC - LD C,E ; KEEP SINGLE REGISTER FUNCTION HERE. - LD HL,FUNCTNS ; NOW LOOK THRU THE FUNCTION TABLE. - LD E,A - LD D,0 ; (DE)=FUNCTION NUMBER. - ADD HL,DE - ADD HL,DE ; (HL)=(START OF TABLE)+2*(FUNCTION NUMBER). - LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE)=ADDRESS FOR THIS FUNCTION. - LD HL,(PARAMS) ; RETRIEVE PARAMETERS. - EX DE,HL ; NOW (DE) HAS THE ORIGINAL PARAMETERS. - JP (HL) ; EXECUTE DESIRED FUNCTION. -; -; BDOS FUNCTION JUMP TABLE. -; -NFUNCTS:.EQU 41 ; NUMBER OF FUNCTIONS IN FOLLOWIN TABLE. -; -FUNCTNS:.DW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - .DW SETIOB,PRTSTR,R.DBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - .DW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - .DW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - .DW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - .DW RTN,WTSPECL -; -; BDOS ERROR MESSAGE SECTION. -; -ERROR1: LD HL,BADSEC ; BAD SECTOR MESSAGE. - CALL PRTERR ; PRINT IT AND GET A 1 CHAR RESPONCE. - CP CNTRLC ; RE-BOOT R.EQUEST (CONTROL-C)? - JP Z,0 ; YES. - RET ; NO, RETURN TO RETRY I/O FUNCTION. -; -ERROR2: LD HL,BADSEL ; BAD DRIVE SELECTED. - JP ERROR5 -; -ERROR3: LD HL,DISKRO ; DISK IS READ ONLY. - JP ERROR5 -; -ERROR4: LD HL,FILERO ; FILE IS READ ONLY. -; -ERROR5: CALL PRTERR - JP 0 ; ALWAYS REBOOT ON THESE ERRORS. -; -BDOSERR:.DB "BDOS ERR ON " -BDOSDRV:.DB " : $" -BADSEC: .DB "BAD SECTOR$" -BADSEL: .DB "SELECT$" -FILERO: .DB "FILE " -DISKRO: .DB "R/O$" -; -; PRINT BDOS ERROR MESSAGE. -; -PRTERR: PUSH HL ; SAVE SECOND MESSAGE POINTER. - CALL OUTCRLF ; SEND (CR)(LF). - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - ADD A,'A' ; MAKE ASCII. - LD (BDOSDRV),A ; AND PUT IN MESSAGE. - LD BC,BDOSERR ; AND PRINT IT. - CALL PRTMESG - POP BC ; PRINT SECOND MESSAGE LINE NOW. - CALL PRTMESG -; -; GET AN INPUT CHARACTER. WE WILL CHECK OUR 1 CHARACTER -; BUFFER FIRST. THIS MAY BE SET BY THE CONSOLE STATUS ROUTINE. -; -GETCHAR:LD HL,CHARBUF ; CHECK CHARACTER BUFFER. - LD A,(HL) ; ANYTHING PRESENT ALREADY? - LD (HL),0 ; ...EITHER CASE CLEAR IT. - OR A - RET NZ ; YES, USE IT. - JP CONIN ; NOPE, GO GET A CHARACTER RESPONCE. -; -; INPUT AND ECHO A CHARACTER. -; -GETECHO:CALL GETCHAR ; INPUT A CHARACTER. - CALL CHKCHAR ; CARRIAGE CONTROL? - RET C ; NO, A REGULAR CONTROL CHAR SO DON'T ECHO. - PUSH AF ; OK, SAVE CHARACTER NOW. - LD C,A - CALL OUTCON ; AND ECHO IT. - POP AF ; GET CHARACTER AND RETURN. - RET -; -; CHECK CHARACTER IN (A). SET THE ZERO FLAG ON A CARRIAGE -; CONTROL CHARACTER AND THE CARRY FLAG ON ANY OTHER CONTROL -; CHARACTER. -; -CHKCHAR:CP CR ; CHECK FOR CARRIAGE RETURN, LINE FEED, BACKSPACE, - RET Z ; OR A TAB. - CP LF - RET Z - CP TAB - RET Z - CP BS - RET Z - CP ' ' ; OTHER CONTROL CHAR? SET CARRY FLAG. - RET -; -; CHECK THE CONSOLE DURING OUTPUT. HALT ON A CONTROL-S, THEN -; REBOOT ON A CONTROL-C. IF ANYTHING ELSE IS READY, CLEAR THE -; ZERO FLAG AND RETURN (THE CALLING ROUTINE MAY WANT TO DO -; SOMETHING). -; -CKCONSOL: - LD A,(CHARBUF) ; CHECK BUFFER. - OR A ; IF ANYTHING, JUST RETURN WITHOUT CHECKING. - JP NZ,CKCON2 - CALL CONST ; NOTHING IN BUFFER. CHECK CONSOLE. - AND 01H ; LOOK AT BIT 0. - RET Z ; RETURN IF NOTHING. - CALL CONIN ; OK, GET IT. - CP CNTRLS ; IF NOT CONTROL-S, RETURN WITH ZERO CLEARED. - JP NZ,CKCON1 - CALL CONIN ; HALT PROCESSING UNTIL ANOTHER CHAR - CP CNTRLC ; IS TYPED. CONTROL-C? - JP Z,0 ; YES, REBOOT NOW. - XOR A ; NO, JUST PRETEND NOTHING WAS EVER READY. - RET -CKCON1: LD (CHARBUF),A ; SAVE CHARACTER IN BUFFER FOR LATER PROCESSING. -CKCON2: LD A,1 ; SET (A) TO NON ZERO TO MEAN SOMETHING IS READY. - RET -; -; OUTPUT (C) TO THE SCREEN. IF THE PRINTER FLIP-FLOP FLAG -; IS SET, WE WILL SEND CHARACTER TO PRINTER ALSO. THE CONSOLE -; WILL BE CHECKED IN THE PROCESS. -; -OUTCHAR:LD A,(OUTFLAG) ; CHECK OUTPUT FLAG. - OR A ; ANYTHING AND WE WON'T GENERATE OUTPUT. - JP NZ,OUTCHR1 - PUSH BC - CALL CKCONSOL ; CHECK CONSOLE (WE DON'T CARE WHATS THERE). - POP BC - PUSH BC - CALL CONOUT ; OUTPUT (C) TO THE SCREEN. - POP BC - PUSH BC - LD A,(PRTFLAG) ; CHECK PRINTER FLIP-FLOP FLAG. - OR A - CALL NZ,LIST ; PRINT IT ALSO IF NON-ZERO. - POP BC -OUTCHR1:LD A,C ; UPDATE CURSORS POSITION. - LD HL,CURPOS - CP DEL ; RUBOUTS DON'T DO ANYTHING HERE. - RET Z - INC (HL) ; BUMP LINE POINTER. - CP ' ' ; AND RETURN IF A NORMAL CHARACTER. - RET NC - DEC (HL) ; RESTORE AND CHECK FOR THE START OF THE LINE. - LD A,(HL) - OR A - RET Z ; INGNORE CONTROL CHARACTERS AT THE START OF THE LINE. - LD A,C - CP BS ; IS IT A BACKSPACE? - JP NZ,OUTCHR2 - DEC (HL) ; YES, BACKUP POINTER. - RET -OUTCHR2:CP LF ; IS IT A LINE FEED? - RET NZ ; IGNORE ANYTHING ELSE. - LD (HL),0 ; RESET POINTER TO START OF LINE. - RET -; -; OUTPUT (A) TO THE SCREEN. IF IT IS A CONTROL CHARACTER -; (OTHER THAN CARRIAGE CONTROL), USE ^X FORMAT. -; -SHOWIT: LD A,C - CALL CHKCHAR ; CHECK CHARACTER. - JP NC,OUTCON ; NOT A CONTROL, USE NORMAL OUTPUT. - PUSH AF - LD C,'^' ; FOR A CONTROL CHARACTER, PRECEED IT WITH '^'. - CALL OUTCHAR - POP AF - OR '@' ; AND THEN USE THE LETTER .EQUIVELANT. - LD C,A -; -; FUNCTION TO OUTPUT (C) TO THE CONSOLE DEVICE AND EXPAND TABS -; IF NECESSARY. -; -OUTCON: LD A,C - CP TAB ; IS IT A TAB? - JP NZ,OUTCHAR ; USE REGULAR OUTPUT. -OUTCON1:LD C,' ' ; YES IT IS, USE SPACES INSTEAD. - CALL OUTCHAR - LD A,(CURPOS) ; GO UNTIL THE CURSOR IS AT A MULTIPLE OF 8 - - AND 07H ; POSITION. - JP NZ,OUTCON1 - RET -; -; ECHO A BACKSPACE CHARACTER. ERASE THE PREVOIUS CHARACTER -; ON THE SCREEN. -; -BACKUP: CALL BACKUP1 ; BACKUP THE SCREEN 1 PLACE. - LD C,' ' ; THEN BLANK THAT CHARACTER. - CALL CONOUT -BACKUP1:LD C,BS ; THEN BACK SPACE ONCE MORE. - JP CONOUT -; -; SIGNAL A DELETED LINE. PRINT A '#' AT THE END AND START -; OVER. -; -NEWLINE:LD C,'#' - CALL OUTCHAR ; PRINT THIS. - CALL OUTCRLF ; START NEW LINE. -NEWLN1: LD A,(CURPOS) ; MOVE THE CURSOR TO THE STARTING POSITION. - LD HL,STARTING - CP (HL) - RET NC ; THERE YET? - LD C,' ' - CALL OUTCHAR ; NOPE, KEEP GOING. - JP NEWLN1 -; -; OUTPUT A (CR) (LF) TO THE CONSOLE DEVICE (SCREEN). -; -OUTCRLF:LD C,CR - CALL OUTCHAR - LD C,LF - JP OUTCHAR -; -; PRINT MESSAGE POINTED TO BY (BC). IT WILL END WITH A '$'. -; -PRTMESG:LD A,(BC) ; CHECK FOR TERMINATING CHARACTER. - CP '$' - RET Z - INC BC - PUSH BC ; OTHERWISE, BUMP POINTER AND PRINT IT. - LD C,A - CALL OUTCON - POP BC - JP PRTMESG -; -; FUNCTION TO EXECUTE A BUFFERED READ. -; -R.DBUFF: LD A,(CURPOS) ; USE PRESENT LOCATION AS STARTING ONE. - LD (STARTING),A - LD HL,(PARAMS) ; GET THE MAXIMUM BUFFER SPACE. - LD C,(HL) - INC HL ; POINT TO FIRST AVAILABLE SPACE. - PUSH HL ; AND SAVE. - LD B,0 ; KEEP A CHARACTER COUNT. -R.DBUF1: PUSH BC - PUSH HL -R.DBUF2: CALL GETCHAR ; GET THE NEXT INPUT CHARACTER. - AND 7FH ; STRIP BIT 7. - POP HL ; RESET REGISTERS. - POP BC - CP CR ; EN OF THE LINE? - JP Z,R.DBUF17 - CP LF - JP Z,R.DBUF17 - CP BS ; HOW ABOUT A BACKSPACE? - JP NZ,R.DBUF3 - LD A,B ; YES, BUT IGNORE AT THE BEGINNING OF THE LINE. - OR A - JP Z,R.DBUF1 - DEC B ; OK, UPDATE COUNTER. - LD A,(CURPOS) ; IF WE BACKSPACE TO THE START OF THE LINE, - LD (OUTFLAG),A ; TREAT AS A CANCEL (CONTROL-X). - JP R.DBUF10 -R.DBUF3: CP DEL ; USER TYPED A RUBOUT? - JP NZ,R.DBUF4 - LD A,B ; IGNORE AT THE START OF THE LINE. - OR A - JP Z,R.DBUF1 - LD A,(HL) ; OK, ECHO THE PREVOIUS CHARACTER. - DEC B ; AND RESET POINTERS (COUNTERS). - DEC HL - JP R.DBUF15 -R.DBUF4: CP CNTRLE ; PHYSICAL END OF LINE? - JP NZ,R.DBUF5 - PUSH BC ; YES, DO IT. - PUSH HL - CALL OUTCRLF - XOR A ; AND UPDATE STARTING POSITION. - LD (STARTING),A - JP R.DBUF2 -R.DBUF5: CP CNTRLP ; CONTROL-P? - JP NZ,R.DBUF6 - PUSH HL ; YES, FLIP THE PRINT FLAG FILP-FLOP BYTE. - LD HL,PRTFLAG - LD A,1 ; PRTFLAG=1-PRTFLAG - SUB (HL) - LD (HL),A - POP HL - JP R.DBUF1 -R.DBUF6: CP CNTRLX ; CONTROL-X (CANCEL)? - JP NZ,R.DBUF8 - POP HL -R.DBUF7: LD A,(STARTING) ; YES, BACKUP THE CURSOR TO HERE. - LD HL,CURPOS - CP (HL) - JP NC,R.DBUFF ; DONE YET? - DEC (HL) ; NO, DECREMENT POINTER AND OUTPUT BACK UP ONE SPACE. - CALL BACKUP - JP R.DBUF7 -R.DBUF8: CP CNTRLU ; CNTROL-U (CANCEL LINE)? - JP NZ,R.DBUF9 - CALL NEWLINE ; START A NEW LINE. - POP HL - JP R.DBUFF -R.DBUF9: CP CNTRLR ; CONTROL-R? - JP NZ,R.DBUF14 -R.DBUF10:PUSH BC ; YES, START A NEW LINE AND RETYPE THE OLD ONE. - CALL NEWLINE - POP BC - POP HL - PUSH HL - PUSH BC -R.DBUF11:LD A,B ; DONE WHOLE LINE YET? - OR A - JP Z,R.DBUF12 - INC HL ; NOPE, GET NEXT CHARACTER. - LD C,(HL) - DEC B ; COUNT IT. - PUSH BC - PUSH HL - CALL SHOWIT ; AND DISPLAY IT. - POP HL - POP BC - JP R.DBUF11 -R.DBUF12:PUSH HL ; DONE WITH LINE. IF WE WERE DISPLAYING - LD A,(OUTFLAG) ; THEN UPDATE CURSOR POSITION. - OR A - JP Z,R.DBUF2 - LD HL,CURPOS ; BECAUSE THIS LINE IS SHORTER, WE MUST - SUB (HL) ; BACK UP THE CURSOR (NOT THE SCREEN HOWEVER) - LD (OUTFLAG),A ; SOME NUMBER OF POSITIONS. -R.DBUF13:CALL BACKUP ; NOTE THAT AS LONG AS (OUTFLAG) IS NON - LD HL,OUTFLAG ; ZERO, THE SCREEN WILL NOT BE CHANGED. - DEC (HL) - JP NZ,R.DBUF13 - JP R.DBUF2 ; NOW JUST GET THE NEXT CHARACTER. -; -; JUST A NORMAL CHARACTER, PUT THIS IN OUR BUFFER AND ECHO. -; -R.DBUF14:INC HL - LD (HL),A ; STORE CHARACTER. - INC B ; AND COUNT IT. -R.DBUF15:PUSH BC - PUSH HL - LD C,A ; ECHO IT NOW. - CALL SHOWIT - POP HL - POP BC - LD A,(HL) ; WAS IT AN ABORT R.EQUEST? - CP CNTRLC ; CONTROL-C ABORT? - LD A,B - JP NZ,R.DBUF16 - CP 1 ; ONLY IF AT START OF LINE. - JP Z,0 -R.DBUF16:CP C ; NOPE, HAVE WE FILLED THE BUFFER? - JP C,R.DBUF1 -R.DBUF17:POP HL ; YES END THE LINE AND RETURN. - LD (HL),B - LD C,CR - JP OUTCHAR ; OUTPUT (CR) AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE CONSOLE DEVICE. -; -GETCON: CALL GETECHO ; GET AND ECHO. - JP SETSTAT ; SAVE STATUS AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE TAPE READER DEVICE. -; -GETRDR: CALL READER ; GET A CHARACTER FROM READER, SET STATUS AND RETURN. - JP SETSTAT -; -; FUNCTION TO PERFORM DIRECT CONSOLE I/O. IF (C) CONTAINS (FF) -; THEN THIS IS AN INPUT R.EQUEST. IF (C) CONTAINS (FE) THEN -; THIS IS A STATUS R.EQUEST. OTHERWISE WE ARE TO OUTPUT (C). -; -DIRCIO: LD A,C ; TEST FOR (FF). - INC A - JP Z,DIRC1 - INC A ; TEST FOR (FE). - JP Z,CONST - JP CONOUT ; JUST OUTPUT (C). -DIRC1: CALL CONST ; THIS IS AN INPUT R.EQUEST. - OR A - JP Z,GOBACK1 ; NOT READY? JUST RETURN (DIRECTLY). - CALL CONIN ; YES, GET CHARACTER. - JP SETSTAT ; SET STATUS AND RETURN. -; -; FUNCTION TO RETURN THE I/O BYTE. -; -GETIOB: LD A,(IOBYTE) - JP SETSTAT -; -; FUNCTION TO SET THE I/O BYTE. -; -SETIOB: LD HL,IOBYTE - LD (HL),C - RET -; -; FUNCTION TO PRINT THE CHARACTER STRING POINTED TO BY (DE) -; ON THE CONSOLE DEVICE. THE STRING ENDS WITH A '$'. -; -PRTSTR: EX DE,HL - LD C,L - LD B,H ; NOW (BC) POINTS TO IT. - JP PRTMESG -; -; FUNCTION TO INTERIGATE THE CONSOLE DEVICE. -; -GETCSTS:CALL CKCONSOL -; -; GET HERE TO SET THE STATUS AND RETURN TO THE CLEANUP -; SECTION. THEN BACK TO THE USER. -; -SETSTAT:LD (STATUS),A -RTN: RET -; -; SET THE STATUS TO 1 (READ OR WRITE ERROR CODE). -; -IOERR1: LD A,1 - JP SETSTAT -; -OUTFLAG:.DB 0 ; OUTPUT FLAG (NON ZERO MEANS NO OUTPUT). -STARTING: - .DB 2 ; STARTING POSITION FOR CURSOR. -CURPOS: .DB 0 ; CURSOR POSITION (0=START OF LINE). -PRTFLAG:.DB 0 ; PRINTER FLAG (CONTROL-P TOGGLE). LIST IF NON ZERO. -CHARBUF:.DB 0 ; SINGLE INPUT CHARACTER BUFFER. -; -; STACK AREA FOR BDOS CALLS. -; -USRSTACK: - .DW 0 ; SAVE USERS STACK POINTER HERE. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA:.EQU $ ; END OF STACK AREA. -; -USERNO: .DB 0 ; CURRENT USER NUMBER. -ACTIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -PARAMS: .DW 0 ; SAVE (DE) PARAMETERS HERE ON ENTRY. -STATUS: .DW 0 ; STATUS RETURNED FROM BDOS FUNCTION. -; -; SELECT ERROR OCCURED, JUMP TO ERROR ROUTINE. -; -SLCTERR:LD HL,BADSLCT -; -; JUMP TO (HL) INDIRECTLY. -; -JUMPHL: LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE) CONTAIN THE DESIRED ADDRESS. - EX DE,HL - JP (HL) -; -; BLOCK MOVE. (DE) TO (HL), (C) BYTES TOTAL. -; -DE2HL: INC C ; IS COUNT DOWN TO ZERO? -DE2HL1: DEC C - RET Z ; YES, WE ARE DONE. - LD A,(DE) ; NO, MOVE ONE MORE BYTE. - LD (HL),A - INC DE - INC HL - JP DE2HL1 ; AND REPEAT. -; -; SELECT THE DESIRED DRIVE. -; -SELECT: LD A,(ACTIVE) ; GET ACTIVE DISK. - LD C,A - CALL SELDSK ; SELECT IT. - LD A,H ; VALID DRIVE? - OR L ; VALID DRIVE? - RET Z ; RETURN IF NOT. -; -; HERE, THE BIOS RETURNED THE ADDRESS OF THE PARAMETER BLOCK -; IN (HL). WE WILL EXTRACT THE NECESSARY POINTERS AND SAVE THEM. -; - LD E,(HL) ; YES, GET ADDRESS OF TRANSLATION TABLE INTO (DE). - INC HL - LD D,(HL) - INC HL - LD (SCRATCH1),HL ; SAVE POINTERS TO SCRATCH AREAS. - INC HL - INC HL - LD (SCRATCH2),HL ; DITTO. - INC HL - INC HL - LD (SCRATCH3),HL ; DITTO. - INC HL - INC HL - EX DE,HL ; NOW SAVE THE TRANSLATION TABLE ADDRESS. - LD (XLATE),HL - LD HL,DIRBUF ; PUT THE NEXT 8 BYTES HERE. - LD C,8 ; THEY CONSIST OF THE DIRECTORY BUFFER - CALL DE2HL ; POINTER, PARAMETER BLOCK POINTER, - LD HL,(DISKPB) ; CHECK AND ALLOCATION VECTORS. - EX DE,HL - LD HL,SECTORS ; MOVE PARAMETER BLOCK INTO OUR RAM. - LD C,15 ; IT IS 15 BYTES LONG. - CALL DE2HL - LD HL,(DSKSIZE) ; CHECK DISK SIZE. - LD A,H ; MORE THAN 256 BLOCKS ON THIS? - LD HL,BIGDISK - LD (HL),0FFH ; SET TO SAMLL. - OR A - JP Z,SELECT1 - LD (HL),0 ; WRONG, SET TO LARGE. -SELECT1:LD A,0FFH ; CLEAR THE ZERO FLAG. - OR A - RET -; -; ROUTINE TO HOME THE DISK TRACK HEAD AND CLEAR POINTERS. -; -HOMEDRV:CALL HOME ; HOME THE HEAD. - XOR A - LD HL,(SCRATCH2) ; SET OUR TRACK POINTER ALSO. - LD (HL),A - INC HL - LD (HL),A - LD HL,(SCRATCH3) ; AND OUR SECTOR POINTER. - LD (HL),A - INC HL - LD (HL),A - RET -; -; DO THE ACTUAL DISK READ AND CHECK THE ERROR RETURN STATUS. -; -DOREAD: CALL READ - JP IORET -; -; DO THE ACTUAL DISK WRITE AND HANDLE ANY BIOS ERROR. -; -DOWRITE:CALL WRITE -IORET: OR A - RET Z ; RETURN UNLESS AN ERROR OCCURED. - LD HL,BADSCTR ; BAD READ/WRITE ON THIS SECTOR. - JP JUMPHL -; -; ROUTINE TO SELECT THE TRACK AND SECTOR THAT THE DESIRED -; BLOCK NUMBER FALLS IN. -; -TRKSEC: LD HL,(FILEPOS) ; GET POSITION OF LAST ACCESSED FILE - LD C,2 ; IN DIRECTORY AND COMPUTE SECTOR #. - CALL SHIFTR ; SECTOR #=FILE-POSITION/4. - LD (BLKNMBR),HL ; SAVE THIS AS THE BLOCK NUMBER OF INTEREST. - LD (CKSUMTBL),HL ; WHAT'S IT DOING HERE TOO? -; -; IF THE SECTOR NUMBER HAS ALREADY BEEN SET (BLKNMBR), ENTER -; AT THIS POINT. -; -TRKSEC1:LD HL,BLKNMBR - LD C,(HL) ; MOVE SECTOR NUMBER INTO (BC). - INC HL - LD B,(HL) - LD HL,(SCRATCH3) ; GET CURRENT SECTOR NUMBER AND - LD E,(HL) ; MOVE THIS INTO (DE). - INC HL - LD D,(HL) - LD HL,(SCRATCH2) ; GET CURRENT TRACK NUMBER. - LD A,(HL) ; AND THIS INTO (HL). - INC HL - LD H,(HL) - LD L,A -TRKSEC2:LD A,C ; IS DESIRED SECTOR BEFORE CURRENT ONE? - SUB E - LD A,B - SBC A,D - JP NC,TRKSEC3 - PUSH HL ; YES, DECREMENT SECTORS BY ONE TRACK. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - LD A,E - SUB L - LD E,A - LD A,D - SBC A,H - LD D,A ; NOW WE HAVE BACKED UP ONE FULL TRACK. - POP HL - DEC HL ; ADJUST TRACK COUNTER. - JP TRKSEC2 -TRKSEC3:PUSH HL ; DESIRED SECTOR IS AFTER CURRENT ONE. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - ADD HL,DE ; BUMP SECTOR POINTER TO NEXT TRACK. - JP C,TRKSEC4 - LD A,C ; IS DESIRED SECTOR NOW BEFORE CURRENT ONE? - SUB L - LD A,B - SBC A,H - JP C,TRKSEC4 - EX DE,HL ; NOT YES, INCREMENT TRACK COUNTER - POP HL ; AND CONTINUE UNTIL IT IS. - INC HL - JP TRKSEC3 -; -; HERE WE HAVE DETERMINED THE TRACK NUMBER THAT CONTAINS THE -; DESIRED SECTOR. -; -TRKSEC4:POP HL ; GET TRACK NUMBER (HL). - PUSH BC - PUSH DE - PUSH HL - EX DE,HL - LD HL,(OFFSET) ; ADJUST FOR FIRST TRACK OFFSET. - ADD HL,DE - LD B,H - LD C,L - CALL SETTRK ; SELECT THIS TRACK. - POP DE ; RESET CURRENT TRACK POINTER. - LD HL,(SCRATCH2) - LD (HL),E - INC HL - LD (HL),D - POP DE - LD HL,(SCRATCH3) ; RESET THE FIRST SECTOR ON THIS TRACK. - LD (HL),E - INC HL - LD (HL),D - POP BC - LD A,C ; NOW SUBTRACT THE DESIRED ONE. - SUB E ; TO MAKE IT RELATIVE (1-# SECTORS/TRACK). - LD C,A - LD A,B - SBC A,D - LD B,A - LD HL,(XLATE) ; TRANSLATE THIS SECTOR ACCORDING TO THIS TABLE. - EX DE,HL - CALL SECTRN ; LET THE BIOS TRANSLATE IT. - LD C,L - LD B,H - JP SETSEC ; AND SELECT IT. -; -; COMPUTE BLOCK NUMBER FROM RECORD NUMBER (SAVNREC) AND -; EXTENT NUMBER (SAVEXT). -; -GETBLOCK: - LD HL,BLKSHFT ; GET LOGICAL TO PHYSICAL CONVERSION. - LD C,(HL) ; NOTE THAT THIS IS BASE 2 LOG OF RATIO. - LD A,(SAVNREC) ; GET RECORD NUMBER. -GETBLK1:OR A ; COMPUTE (A)=(A)/2^BLKSHFT. - RRA - DEC C - JP NZ,GETBLK1 - LD B,A ; SAVE RESULT IN (B). - LD A,8 - SUB (HL) - LD C,A ; COMPUTE (C)=8-BLKSHFT. - LD A,(SAVEXT) -GETBLK2:DEC C ; COMPUTE (A)=SAVEXT*2^(8-BLKSHFT). - JP Z,GETBLK3 - OR A - RLA - JP GETBLK2 -GETBLK3:ADD A,B - RET -; -; ROUTINE TO EXTRACT THE (BC) BLOCK BYTE FROM THE FCB POINTED -; TO BY (PARAMS). IF THIS IS A BIG-DISK, THEN THESE ARE 16 BIT -; BLOCK NUMBERS, ELSE THEY ARE 8 BIT NUMBERS. -; NUMBER IS RETURNED IN (HL). -; -EXTBLK: LD HL,(PARAMS) ; GET FCB ADDRESS. - LD DE,16 ; BLOCK NUMBERS START 16 BYTES INTO FCB. - ADD HL,DE - ADD HL,BC - LD A,(BIGDISK) ; ARE WE USING A BIG-DISK? - OR A - JP Z,EXTBLK1 - LD L,(HL) ; NO, EXTRACT AN 8 BIT NUMBER FROM THE FCB. - LD H,0 - RET -EXTBLK1:ADD HL,BC ; YES, EXTRACT A 16 BIT NUMBER. - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ; RETURN IN (HL). - RET -; -; COMPUTE BLOCK NUMBER. -; -COMBLK: CALL GETBLOCK - LD C,A - LD B,0 - CALL EXTBLK - LD (BLKNMBR),HL - RET -; -; CHECK FOR A ZERO BLOCK NUMBER (UNUSED). -; -CHKBLK: LD HL,(BLKNMBR) - LD A,L ; IS IT ZERO? - OR H - RET -; -; ADJUST PHYSICAL BLOCK (BLKNMBR) AND CONVERT TO LOGICAL -; SECTOR (LOGSECT). THIS IS THE STARTING SECTOR OF THIS BLOCK. -; THE ACTUAL SECTOR OF INTEREST IS THEN ADDED TO THIS AND THE -; RESULTING SECTOR NUMBER IS STORED BACK IN (BLKNMBR). THIS -; WILL STILL HAVE TO BE ADJUSTED FOR THE TRACK NUMBER. -; -LOGICAL:LD A,(BLKSHFT) ; GET LOG2(PHYSICAL/LOGICAL SECTORS). - LD HL,(BLKNMBR) ; GET PHYSICAL SECTOR DESIRED. -LOGICL1:ADD HL,HL ; COMPUTE LOGICAL SECTOR NUMBER. - DEC A ; NOTE LOGICAL SECTORS ARE 128 BYTES LONG. - JP NZ,LOGICL1 - LD (LOGSECT),HL ; SAVE LOGICAL SECTOR. - LD A,(BLKMASK) ; GET BLOCK MASK. - LD C,A - LD A,(SAVNREC) ; GET NEXT SECTOR TO ACCESS. - AND C ; EXTRACT THE RELATIVE POSITION WITHIN PHYSICAL BLOCK. - OR L ; AND ADD IT TOO LOGICAL SECTOR. - LD L,A - LD (BLKNMBR),HL ; AND STORE. - RET -; -; SET (HL) TO POINT TO EXTENT BYTE IN FCB. -; -SETEXT: LD HL,(PARAMS) - LD DE,12 ; IT IS THE TWELTH BYTE. - ADD HL,DE - RET -; -; SET (HL) TO POINT TO RECORD COUNT BYTE IN FCB AND (DE) TO -; NEXT RECORD NUMBER BYTE. -; -SETHLDE:LD HL,(PARAMS) - LD DE,15 ; RECORD COUNT BYTE (#15). - ADD HL,DE - EX DE,HL - LD HL,17 ; NEXT RECORD NUMBER (#32). - ADD HL,DE - RET -; -; SAVE CURRENT FILE DATA FROM FCB. -; -STRDATA:CALL SETHLDE - LD A,(HL) ; GET AND STORE RECORD COUNT BYTE. - LD (SAVNREC),A - EX DE,HL - LD A,(HL) ; GET AND STORE NEXT RECORD NUMBER BYTE. - LD (SAVNXT),A - CALL SETEXT ; POINT TO EXTENT BYTE. - LD A,(EXTMASK) ; GET EXTENT MASK. - AND (HL) - LD (SAVEXT),A ; AND SAVE EXTENT HERE. - RET -; -; SET THE NEXT RECORD TO ACCESS. IF (MODE) IS SET TO 2, THEN -; THE LAST RECORD BYTE (SAVNREC) HAS THE CORRECT NUMBER TO ACCESS. -; FOR S.EQUENTIAL ACCESS, (MODE) WILL BE .EQUAL TO 1. -; -SETNREC:CALL SETHLDE - LD A,(MODE) ; GET S.EQUENTIAL FLAG (=1). - CP 2 ; A 2 INDICATES THAT NO ADDER IS NEEDED. - JP NZ,STNREC1 - XOR A ; CLEAR ADDER (RANDOM ACCESS?). -STNREC1:LD C,A - LD A,(SAVNREC) ; GET LAST RECORD NUMBER. - ADD A,C ; INCREMENT RECORD COUNT. - LD (HL),A ; AND SET FCB'S NEXT RECORD BYTE. - EX DE,HL - LD A,(SAVNXT) ; GET NEXT RECORD BYTE FROM STORAGE. - LD (HL),A ; AND PUT THIS INTO FCB AS NUMBER OF RECORDS USED. - RET -; -; SHIFT (HL) RIGHT (C) BITS. -; -SHIFTR: INC C -SHIFTR1:DEC C - RET Z - LD A,H - OR A - RRA - LD H,A - LD A,L - RRA - LD L,A - JP SHIFTR1 -; -; COMPUTE THE CHECK-SUM FOR THE DIRECTORY BUFFER. RETURN -; INTEGER SUM IN (A). -; -CHECKSUM: - LD C,128 ; LENGTH OF BUFFER. - LD HL,(DIRBUF) ; GET ITS LOCATION. - XOR A ; CLEAR SUMMATION BYTE. -CHKSUM1:ADD A,(HL) ; AND COMPUTE SUM IGNORING CARRIES. - INC HL - DEC C - JP NZ,CHKSUM1 - RET -; -; SHIFT (HL) LEFT (C) BITS. -; -SHIFTL: INC C -SHIFTL1:DEC C - RET Z - ADD HL,HL ; SHIFT LEFT 1 BIT. - JP SHIFTL1 -; -; ROUTINE TO SET A BIT IN A 16 BIT VALUE CONTAINED IN (BC). -; THE BIT SET DEPENDS ON THE CURRENT DRIVE SELECTION. -; -SETBIT: PUSH BC ; SAVE 16 BIT WORD. - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - LD C,A - LD HL,1 - CALL SHIFTL ; SHIFT BIT 0 INTO PLACE. - POP BC ; NOW 'OR' THIS WITH THE ORIGINAL WORD. - LD A,C - OR L - LD L,A ; LOW BYTE DONE, DO HIGH BYTE. - LD A,B - OR H - LD H,A - RET -; -; EXTRACT THE WRITE PROTECT STATUS BIT FOR THE CURRENT DRIVE. -; THE RESULT IS RETURNED IN (A), BIT 0. -; -GETWPRT:LD HL,(WRTPRT) ; GET STATUS BYTES. - LD A,(ACTIVE) ; WHICH DRIVE IS CURRENT? - LD C,A - CALL SHIFTR ; SHIFT STATUS SUCH THAT BIT 0 IS THE - LD A,L ; ONE OF INTEREST FOR THIS DRIVE. - AND 01H ; AND ISOLATE IT. - RET -; -; FUNCTION TO WRITE PROTECT THE CURRENT DISK. -; -WRTPRTD:LD HL,WRTPRT ; POINT TO STATUS WORD. - LD C,(HL) ; SET (BC) .EQUAL TO THE STATUS. - INC HL - LD B,(HL) - CALL SETBIT ; AND SET THIS BIT ACCORDING TO CURRENT DRIVE. - LD (WRTPRT),HL ; THEN SAVE. - LD HL,(DIRSIZE) ; NOW SAVE DIRECTORY SIZE LIMIT. - INC HL ; REMEMBER THE LAST ONE. - EX DE,HL - LD HL,(SCRATCH1) ; AND STORE IT HERE. - LD (HL),E ; PUT LOW BYTE. - INC HL - LD (HL),D ; THEN HIGH BYTE. - RET -; -; CHECK FOR A READ ONLY FILE. -; -CHKROFL:CALL FCB2HL ; SET (HL) TO FILE ENTRY IN DIRECTORY BUFFER. -CKROF1: LD DE,9 ; LOOK AT BIT 7 OF THE NINTH BYTE. - ADD HL,DE - LD A,(HL) - RLA - RET NC ; RETURN IF OK. - LD HL,ROFILE ; ELSE, PRINT ERROR MESSAGE AND TERMINATE. - JP JUMPHL -; -; CHECK THE WRITE PROTECT STATUS OF THE ACTIVE DISK. -; -CHKWPRT:CALL GETWPRT - RET Z ; RETURN IF OK. - LD HL,RODISK ; ELSE PRINT MESSAGE AND TERMINATE. - JP JUMPHL -; -; ROUTINE TO SET (HL) POINTING TO THE PROPER ENTRY IN THE -; DIRECTORY BUFFER. -; -FCB2HL: LD HL,(DIRBUF) ; GET ADDRESS OF BUFFER. - LD A,(FCBPOS) ; RELATIVE POSITION OF FILE. -; -; ROUTINE TO ADD (A) TO (HL). -; -ADDA2HL:ADD A,L - LD L,A - RET NC - INC H ; TAKE CARE OF ANY CARRY. - RET -; -; ROUTINE TO GET THE 'S2' BYTE FROM THE FCB SUPPLIED IN -; THE INITIAL PARAMETER SPECIFICATION. -; -GETS2: LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD DE,14 ; RELATIVE POSITION OF 'S2'. - ADD HL,DE - LD A,(HL) ; EXTRACT THIS BYTE. - RET -; -; CLEAR THE 'S2' BYTE IN THE FCB. -; -CLEARS2:CALL GETS2 ; THIS SETS (HL) POINTING TO IT. - LD (HL),0 ; NOW CLEAR IT. - RET -; -; SET BIT 7 IN THE 'S2' BYTE OF THE FCB. -; -SETS2B7:CALL GETS2 ; GET THE BYTE. - OR 80H ; AND SET BIT 7. - LD (HL),A ; THEN STORE. - RET -; -; COMPARE (FILEPOS) WITH (SCRATCH1) AND SET FLAGS BASED ON -; THE DIFFERENCE. THIS CHECKS TO SEE IF THERE ARE MORE FILE -; NAMES IN THE DIRECTORY. WE ARE AT (FILEPOS) AND THERE ARE -; (SCRATCH1) OF THEM TO CHECK. -; -MOREFLS:LD HL,(FILEPOS) ; WE ARE HERE. - EX DE,HL - LD HL,(SCRATCH1) ; AND DON'T GO PAST HERE. - LD A,E ; COMPUTE DIFFERENCE BUT DON'T KEEP. - SUB (HL) - INC HL - LD A,D - SBC A,(HL) ; SET CARRY IF NO MORE NAMES. - RET -; -; CALL THIS ROUTINE TO PREVENT (SCRATCH1) FROM BEING GREATER -; THAN (FILEPOS). -; -CHKNMBR:CALL MOREFLS ; SCRATCH1 TOO BIG? - RET C - INC DE ; YES, RESET IT TO (FILEPOS). - LD (HL),D - DEC HL - LD (HL),E - RET -; -; COMPUTE (HL)=(DE)-(HL) -; -SUBHL: LD A,E ; COMPUTE DIFFERENCE. - SUB L - LD L,A ; STORE LOW BYTE. - LD A,D - SBC A,H - LD H,A ; AND THEN HIGH BYTE. - RET -; -; SET THE DIRECTORY CHECKSUM BYTE. -; -SETDIR: LD C,0FFH -; -; ROUTINE TO SET OR COMPARE THE DIRECTORY CHECKSUM BYTE. IF -; (C)=0FFH, THEN THIS WILL SET THE CHECKSUM BYTE. ELSE THE BYTE -; WILL BE CHECKED. IF THE CHECK FAILS (THE DISK HAS BEEN CHANGED), -; THEN THIS DISK WILL BE WRITE PROTECTED. -; -CHECKDIR: - LD HL,(CKSUMTBL) - EX DE,HL - LD HL,(ALLOC1) - CALL SUBHL - RET NC ; OK IF (CKSUMTBL) > (ALLOC1), SO RETURN. - PUSH BC - CALL CHECKSUM ; ELSE COMPUTE CHECKSUM. - LD HL,(CHKVECT) ; GET ADDRESS OF CHECKSUM TABLE. - EX DE,HL - LD HL,(CKSUMTBL) - ADD HL,DE ; SET (HL) TO POINT TO BYTE FOR THIS DRIVE. - POP BC - INC C ; SET OR CHECK ? - JP Z,CHKDIR1 - CP (HL) ; CHECK THEM. - RET Z ; RETURN IF THEY ARE THE SAME. - CALL MOREFLS ; NOT THE SAME, DO WE CARE? - RET NC - CALL WRTPRTD ; YES, MARK THIS AS WRITE PROTECTED. - RET -CHKDIR1:LD (HL),A ; JUST SET THE BYTE. - RET -; -; DO A WRITE TO THE DIRECTORY OF THE CURRENT DISK. -; -DIRWRITE: - CALL SETDIR ; SET CHECKSUM BYTE. - CALL DIRDMA ; SET DIRECTORY DMA ADDRESS. - LD C,1 ; TELL THE BIOS TO ACTUALLY WRITE. - CALL DOWRITE ; THEN DO THE WRITE. - JP DEFDMA -; -; READ FROM THE DIRECTORY. -; -DIRREAD:CALL DIRDMA ; SET THE DIRECTORY DMA ADDRESS. - CALL DOREAD ; AND READ IT. -; -; ROUTINE TO SET THE DMA ADDRESS TO THE USERS CHOICE. -; -DEFDMA: LD HL,USERDMA ; RESET THE DEFAULT DMA ADDRESS AND RETURN. - JP DIRDMA1 -; -; ROUTINE TO SET THE DMA ADDRESS FOR DIRECTORY WORK. -; -DIRDMA: LD HL,DIRBUF -; -; SET THE DMA ADDRESS. ON ENTRY, (HL) POINTS TO -; WORD CONTAINING THE DESIRED DMA ADDRESS. -; -DIRDMA1:LD C,(HL) - INC HL - LD B,(HL) ; SETUP (BC) AND GO TO THE BIOS TO SET IT. - JP SETDMA -; -; MOVE THE DIRECTORY BUFFER INTO USER'S DMA SPACE. -; -MOVEDIR:LD HL,(DIRBUF) ; BUFFER IS LOCATED HERE, AND - EX DE,HL - LD HL,(USERDMA) ; PUT IT HERE. - LD C,128 ; THIS IS ITS LENGTH. - JP DE2HL ; MOVE IT NOW AND RETURN. -; -; CHECK (FILEPOS) AND SET THE ZERO FLAG IF IT .EQUALS 0FFFFH. -; -CKFILPOS: - LD HL,FILEPOS - LD A,(HL) - INC HL - CP (HL) ; ARE BOTH BYTES THE SAME? - RET NZ - INC A ; YES, BUT ARE THEY EACH 0FFH? - RET -; -; SET LOCATION (FILEPOS) TO 0FFFFH. -; -STFILPOS: - LD HL,0FFFFH - LD (FILEPOS),HL - RET -; -; MOVE ON TO THE NEXT FILE POSITION WITHIN THE CURRENT -; DIRECTORY BUFFER. IF NO MORE EXIST, SET POINTER TO 0FFFFH -; AND THE CALLING ROUTINE WILL CHECK FOR THIS. ENTER WITH (C) -; .EQUAL TO 0FFH TO CAUSE THE CHECKSUM BYTE TO BE SET, ELSE WE -; WILL CHECK THIS DISK AND SET WRITE PROTECT IF CHECKSUMS ARE -; NOT THE SAME (APPLIES ONLY IF ANOTHER DIRECTORY SECTOR MUST -; BE READ). -; -NXENTRY:LD HL,(DIRSIZE) ; GET DIRECTORY ENTRY SIZE LIMIT. - EX DE,HL - LD HL,(FILEPOS) ; GET CURRENT COUNT. - INC HL ; GO ON TO THE NEXT ONE. - LD (FILEPOS),HL - CALL SUBHL ; (HL)=(DIRSIZE)-(FILEPOS) - JP NC,NXENT1 ; IS THERE MORE ROOM LEFT? - JP STFILPOS ; NO. SET THIS FLAG AND RETURN. -NXENT1: LD A,(FILEPOS) ; GET FILE POSITION WITHIN DIRECTORY. - AND 03H ; ONLY LOOK WITHIN THIS SECTOR (ONLY 4 ENTRIES FIT). - LD B,5 ; CONVERT TO RELATIVE POSITION (32 BYTES EACH). -NXENT2: ADD A,A ; NOTE THAT THIS IS NOT EFFICIENT CODE. - DEC B ; 5 'ADD A'S WOULD BE BETTER. - JP NZ,NXENT2 - LD (FCBPOS),A ; SAVE IT AS POSITION OF FCB. - OR A - RET NZ ; RETURN IF WE ARE WITHIN BUFFER. - PUSH BC - CALL TRKSEC ; WE NEED THE NEXT DIRECTORY SECTOR. - CALL DIRREAD - POP BC - JP CHECKDIR -; -; ROUTINE TO TO GET A BIT FROM THE DISK SPACE ALLOCATION -; MAP. IT IS RETURNED IN (A), BIT POSITION 0. ON ENTRY TO HERE, -; SET (BC) TO THE BLOCK NUMBER ON THE DISK TO CHECK. -; ON RETURN, (D) WILL CONTAIN THE ORIGINAL BIT POSITION FOR -; THIS BLOCK NUMBER AND (HL) WILL POINT TO THE ADDRESS FOR IT. -; -CKBITMAP: - LD A,C ; DETERMINE BIT NUMBER OF INTEREST. - AND 07H ; COMPUTE (D)=(E)=(C AND 7)+1. - INC A - LD E,A ; SAVE PARTICULAR BIT NUMBER. - LD D,A -; -; COMPUTE (BC)=(BC)/8. -; - LD A,C - RRCA ; NOW SHIFT RIGHT 3 BITS. - RRCA - RRCA - AND 1FH ; AND CLEAR BITS 7,6,5. - LD C,A - LD A,B - ADD A,A ; NOW SHIFT (B) INTO BITS 7,6,5. - ADD A,A - ADD A,A - ADD A,A - ADD A,A - OR C ; AND ADD IN (C). - LD C,A ; OK, (C) HA BEEN COMPLETED. - LD A,B ; IS THERE A BETTER WAY OF DOING THIS? - RRCA - RRCA - RRCA - AND 1FH - LD B,A ; AND NOW (B) IS COMPLETED. -; -; USE THIS AS AN OFFSET INTO THE DISK SPACE ALLOCATION -; TABLE. -; - LD HL,(ALOCVECT) - ADD HL,BC - LD A,(HL) ; NOW GET CORRECT BYTE. -CKBMAP1:RLCA ; GET CORRECT BIT INTO POSITION 0. - DEC E - JP NZ,CKBMAP1 - RET -; -; SET OR CLEAR THE BIT MAP SUCH THAT BLOCK NUMBER (BC) WILL BE MARKED -; AS USED. ON ENTRY, IF (E)=0 THEN THIS BIT WILL BE CLEARED, IF IT .EQUALS -; 1 THEN IT WILL BE SET (DON'T USE ANYOTHER VALUES). -; -STBITMAP: - PUSH DE - CALL CKBITMAP ; GET THE BYTE OF INTEREST. - AND 0FEH ; CLEAR THE AFFECTED BIT. - POP BC - OR C ; AND NOW SET IT ACORDING TO (C). -; -; ENTRY TO RESTORE THE ORIGINAL BIT POSITION AND THEN STORE -; IN TABLE. (A) CONTAINS THE VALUE, (D) CONTAINS THE BIT -; POSITION (1-8), AND (HL) POINTS TO THE ADDRESS WITHIN THE -; SPACE ALLOCATION TABLE FOR THIS BYTE. -; -STBMAP1:RRCA ; RESTORE ORIGINAL BIT POSITION. - DEC D - JP NZ,STBMAP1 - LD (HL),A ; AND STOR BYTE IN TABLE. - RET -; -; SET/CLEAR SPACE USED BITS IN ALLOCATION MAP FOR THIS FILE. -; ON ENTRY, (C)=1 TO SET THE MAP AND (C)=0 TO CLEAR IT. -; -SETFILE:CALL FCB2HL ; GET ADDRESS OF FCB - LD DE,16 - ADD HL,DE ; GET TO BLOCK NUMBER BYTES. - PUSH BC - LD C,17 ; CHECK ALL 17 BYTES (MAX) OF TABLE. -SETFL1: POP DE - DEC C ; DONE ALL BYTES YET? - RET Z - PUSH DE - LD A,(BIGDISK) ; CHECK DISK SIZE FOR 16 BIT BLOCK NUMBERS. - OR A - JP Z,SETFL2 - PUSH BC ; ONLY 8 BIT NUMBERS. SET (BC) TO THIS ONE. - PUSH HL - LD C,(HL) ; GET LOW BYTE FROM TABLE, ALWAYS - LD B,0 ; SET HIGH BYTE TO ZERO. - JP SETFL3 -SETFL2: DEC C ; FOR 16 BIT BLOCK NUMBERS, ADJUST COUNTER. - PUSH BC - LD C,(HL) ; NOW GET BOTH THE LOW AND HIGH BYTES. - INC HL - LD B,(HL) - PUSH HL -SETFL3: LD A,C ; BLOCK USED? - OR B - JP Z,SETFL4 - LD HL,(DSKSIZE) ; IS THIS BLOCK NUMBER WITHIN THE - LD A,L ; SPACE ON THE DISK? - SUB C - LD A,H - SBC A,B - CALL NC,STBITMAP ; YES, SET THE PROPER BIT. -SETFL4: POP HL ; POINT TO NEXT BLOCK NUMBER IN FCB. - INC HL - POP BC - JP SETFL1 -; -; CONSTRUCT THE SPACE USED ALLOCATION BIT MAP FOR THE ACTIVE -; DRIVE. IF A FILE NAME STARTS WITH '$' AND IT IS UNDER THE -; CURRENT USER NUMBER, THEN (STATUS) IS SET TO MINUS 1. OTHERWISE -; IT IS NOT SET AT ALL. -; -BITMAP: LD HL,(DSKSIZE) ; COMPUTE SIZE OF ALLOCATION TABLE. - LD C,3 - CALL SHIFTR ; (HL)=(HL)/8. - INC HL ; AT LEASE 1 BYTE. - LD B,H - LD C,L ; SET (BC) TO THE ALLOCATION TABLE LENGTH. -; -; INITIALIZE THE BITMAP FOR THIS DRIVE. RIGHT NOW, THE FIRST -; TWO BYTES ARE SPECIFIED BY THE DISK PARAMETER BLOCK. HOWEVER -; A PATCH COULD BE ENTERED HERE IF IT WERE NECESSARY TO SETUP -; THIS TABLE IN A SPECIAL MANNOR. FOR EXAMPLE, THE BIOS COULD -; DETERMINE LOCATIONS OF 'BAD BLOCKS' AND SET THEM AS ALREADY -; 'USED' IN THE MAP. -; - LD HL,(ALOCVECT) ; NOW ZERO OUT THE TABLE NOW. -BITMAP1:LD (HL),0 - INC HL - DEC BC - LD A,B - OR C - JP NZ,BITMAP1 - LD HL,(ALLOC0) ; GET INITIAL SPACE USED BY DIRECTORY. - EX DE,HL - LD HL,(ALOCVECT) ; AND PUT THIS INTO MAP. - LD (HL),E - INC HL - LD (HL),D -; -; END OF INITIALIZATION PORTION. -; - CALL HOMEDRV ; NOW HOME THE DRIVE. - LD HL,(SCRATCH1) - LD (HL),3 ; FORCE NEXT DIRECTORY R.EQUEST TO READ - INC HL ; IN A SECTOR. - LD (HL),0 - CALL STFILPOS ; CLEAR INITIAL FILE POSITION ALSO. -BITMAP2:LD C,0FFH ; READ NEXT FILE NAME IN DIRECTORY - CALL NXENTRY ; AND SET CHECKSUM BYTE. - CALL CKFILPOS ; IS THERE ANOTHER FILE? - RET Z - CALL FCB2HL ; YES, GET ITS ADDRESS. - LD A,0E5H - CP (HL) ; EMPTY FILE ENTRY? - JP Z,BITMAP2 - LD A,(USERNO) ; NO, CORRECT USER NUMBER? - CP (HL) - JP NZ,BITMAP3 - INC HL - LD A,(HL) ; YES, DOES NAME START WITH A '$'? - SUB '$' - JP NZ,BITMAP3 - DEC A ; YES, SET ATATUS TO MINUS ONE. - LD (STATUS),A -BITMAP3:LD C,1 ; NOW SET THIS FILE'S SPACE AS USED IN BIT MAP. - CALL SETFILE - CALL CHKNMBR ; KEEP (SCRATCH1) IN BOUNDS. - JP BITMAP2 -; -; SET THE STATUS (STATUS) AND RETURN. -; -STSTATUS: - LD A,(FNDSTAT) - JP SETSTAT -; -; CHECK EXTENTS IN (A) AND (C). SET THE ZERO FLAG IF THEY -; ARE THE SAME. THE NUMBER OF 16K CHUNKS OF DISK SPACE THAT -; THE DIRECTORY EXTENT COVERS IS EXPRESSAD IS (EXTMASK+1). -; NO REGISTERS ARE MODIFIED. -; -SAMEXT: PUSH BC - PUSH AF - LD A,(EXTMASK) ; GET EXTENT MASK AND USE IT TO - CPL ; TO COMPARE BOTH EXTENT NUMBERS. - LD B,A ; SAVE RESULTING MASK HERE. - LD A,C ; MASK FIRST EXTENT AND SAVE IN (C). - AND B - LD C,A - POP AF ; NOW MASK SECOND EXTENT AND COMPARE - AND B ; WITH THE FIRST ONE. - SUB C - AND 1FH ; (* ONLY CHECK BUTS 0-4 *) - POP BC ; THE ZERO FLAG IS SET IF THEY ARE THE SAME. - RET ; RESTORE (BC) AND RETURN. -; -; SEARCH FOR THE FIRST OCCURENCE OF A FILE NAME. ON ENTRY, -; REGISTER (C) SHOULD CONTAIN THE NUMBER OF BYTES OF THE FCB -; THAT MUST MATCH. -; -FINDFST:LD A,0FFH - LD (FNDSTAT),A - LD HL,COUNTER ; SAVE CHARACTER COUNT. - LD (HL),C - LD HL,(PARAMS) ; GET FILENAME TO MATCH. - LD (SAVEFCB),HL ; AND SAVE. - CALL STFILPOS ; CLEAR INITIAL FILE POSITION (SET TO 0FFFFH). - CALL HOMEDRV ; HOME THE DRIVE. -; -; ENTRY TO LOCATE THE NEXT OCCURENCE OF A FILENAME WITHIN THE -; DIRECTORY. THE DISK IS NOT EXPECTED TO HAVE BEEN CHANGED. IF -; IT WAS, THEN IT WILL BE WRITE PROTECTED. -; -FINDNXT:LD C,0 ; WRITE PROTECT THE DISK IF CHANGED. - CALL NXENTRY ; GET NEXT FILENAME ENTRY IN DIRECTORY. - CALL CKFILPOS ; IS FILE POSITION = 0FFFFH? - JP Z,FNDNXT6 ; YES, EXIT NOW THEN. - LD HL,(SAVEFCB) ; SET (DE) POINTING TO FILENAME TO MATCH. - EX DE,HL - LD A,(DE) - CP 0E5H ; EMPTY DIRECTORY ENTRY? - JP Z,FNDNXT1 ; (* ARE WE TRYING TO RESERECT ERASED ENTRIES? *) - PUSH DE - CALL MOREFLS ; MORE FILES IN DIRECTORY? - POP DE - JP NC,FNDNXT6 ; NO MORE. EXIT NOW. -FNDNXT1:CALL FCB2HL ; GET ADDRESS OF THIS FCB IN DIRECTORY. - LD A,(COUNTER) ; GET NUMBER OF BYTES (CHARACTERS) TO CHECK. - LD C,A - LD B,0 ; INITIALIZE BYTE POSITION COUNTER. -FNDNXT2:LD A,C ; ARE WE DONE WITH THE COMPARE? - OR A - JP Z,FNDNXT5 - LD A,(DE) ; NO, CHECK NEXT BYTE. - CP '?' ; DON'T CARE ABOUT THIS CHARACTER? - JP Z,FNDNXT4 - LD A,B ; GET BYTES POSITION IN FCB. - CP 13 ; DON'T CARE ABOUT THE THIRTEENTH BYTE EITHER. - JP Z,FNDNXT4 - CP 12 ; EXTENT BYTE? - LD A,(DE) - JP Z,FNDNXT3 - SUB (HL) ; OTHERWISE COMPARE CHARACTERS. - AND 7FH - JP NZ,FINDNXT ; NOT THE SAME, CHECK NEXT ENTRY. - JP FNDNXT4 ; SO FAR SO GOOD, KEEP CHECKING. -FNDNXT3:PUSH BC ; CHECK THE EXTENT BYTE HERE. - LD C,(HL) - CALL SAMEXT - POP BC - JP NZ,FINDNXT ; NOT THE SAME, LOOK SOME MORE. -; -; SO FAR THE NAMES COMPARE. BUMP POINTERS TO THE NEXT BYTE -; AND CONTINUE UNTIL ALL (C) CHARACTERS HAVE BEEN CHECKED. -; -FNDNXT4:INC DE ; BUMP POINTERS. - INC HL - INC B - DEC C ; ADJUST CHARACTER COUNTER. - JP FNDNXT2 -FNDNXT5:LD A,(FILEPOS) ; RETURN THE POSITION OF THIS ENTRY. - AND 03H - LD (STATUS),A - LD HL,FNDSTAT - LD A,(HL) - RLA - RET NC - XOR A - LD (HL),A - RET -; -; FILENAME WAS NOT FOUND. SET APPROPRIATE STATUS. -; -FNDNXT6:CALL STFILPOS ; SET (FILEPOS) TO 0FFFFH. - LD A,0FFH ; SAY NOT LOCATED. - JP SETSTAT -; -; ERASE FILES FROM THE DIRECTORY. ONLY THE FIRST BYTE OF THE -; FCB WILL BE AFFECTED. IT IS SET TO (E5). -; -ERAFILE:CALL CHKWPRT ; IS DISK WRITE PROTECTED? - LD C,12 ; ONLY COMPARE FILE NAMES. - CALL FINDFST ; GET FIRST FILE NAME. -ERAFIL1:CALL CKFILPOS ; ANY FOUND? - RET Z ; NOPE, WE MUST BE DONE. - CALL CHKROFL ; IS FILE READ ONLY? - CALL FCB2HL ; NOPE, GET ADDRESS OF FCB AND - LD (HL),0E5H ; SET FIRST BYTE TO 'EMPTY'. - LD C,0 ; CLEAR THE SPACE FROM THE BIT MAP. - CALL SETFILE - CALL DIRWRITE ; NOW WRITE THE DIRECTORY SECTOR BACK OUT. - CALL FINDNXT ; FIND THE NEXT FILE NAME. - JP ERAFIL1 ; AND REPEAT PROCESS. -; -; LOOK THROUGH THE SPACE ALLOCATION MAP (BIT MAP) FOR THE -; NEXT AVAILABLE BLOCK. START SEARCHING AT BLOCK NUMBER (BC-1). -; THE SEARCH PROCEDURE IS TO LOOK FOR AN EMPTY BLOCK THAT IS -; BEFORE THE STARTING BLOCK. IF NOT EMPTY, LOOK AT A LATER -; BLOCK NUMBER. IN THIS WAY, WE RETURN THE CLOSEST EMPTY BLOCK -; ON EITHER SIDE OF THE 'TARGET' BLOCK NUMBER. THIS WILL SPEED -; ACCESS ON RANDOM DEVICES. FOR SERIAL DEVICES, THIS SHOULD BE -; CHANGED TO LOOK IN THE FORWARD DIRECTION FIRST AND THEN START -; AT THE FRONT AND SEARCH SOME MORE. -; -; ON RETURN, (DE)= BLOCK NUMBER THAT IS EMPTY AND (HL) =0 -; IF NO EMPRY BLOCK WAS FOUND. -; -FNDSPACE: - LD D,B ; SET (DE) AS THE BLOCK THAT IS CHECKED. - LD E,C -; -; LOOK BEFORE TARGET BLOCK. REGISTERS (BC) ARE USED AS THE LOWER -; POINTER AND (DE) AS THE UPPER POINTER. -; -FNDSPA1:LD A,C ; IS BLOCK 0 SPECIFIED? - OR B - JP Z,FNDSPA2 - DEC BC ; NOPE, CHECK PREVIOUS BLOCK. - PUSH DE - PUSH BC - CALL CKBITMAP - RRA ; IS THIS BLOCK EMPTY? - JP NC,FNDSPA3 ; YES. USE THIS. -; -; NOTE THAT THE ABOVE LOGIC GETS THE FIRST BLOCK THAT IT FINDS -; THAT IS EMPTY. THUS A FILE COULD BE WRITTEN 'BACKWARD' MAKING -; IT VERY SLOW TO ACCESS. THIS COULD BE CHANGED TO LOOK FOR THE -; FIRST EMPTY BLOCK AND THEN CONTINUE UNTIL THE START OF THIS -; EMPTY SPACE IS LOCATED AND THEN USED THAT STARTING BLOCK. -; THIS SHOULD HELP SPEED UP ACCESS TO SOME FILES ESPECIALLY ON -; A WELL USED DISK WITH LOTS OF FAIRLY SMALL 'HOLES'. -; - POP BC ; NOPE, CHECK SOME MORE. - POP DE -; -; NOW LOOK AFTER TARGET BLOCK. -; -FNDSPA2:LD HL,(DSKSIZE) ; IS BLOCK (DE) WITHIN DISK LIMITS? - LD A,E - SUB L - LD A,D - SBC A,H - JP NC,FNDSPA4 - INC DE ; YES, MOVE ON TO NEXT ONE. - PUSH BC - PUSH DE - LD B,D - LD C,E - CALL CKBITMAP ; CHECK IT. - RRA ; EMPTY? - JP NC,FNDSPA3 - POP DE ; NOPE, CONTINUE SEARCHING. - POP BC - JP FNDSPA1 -; -; EMPTY BLOCK FOUND. SET IT AS USED AND RETURN WITH (HL) -; POINTING TO IT (TRUE?). -; -FNDSPA3:RLA ; RESET BYTE. - INC A ; AND SET BIT 0. - CALL STBMAP1 ; UPDATE BIT MAP. - POP HL ; SET RETURN REGISTERS. - POP DE - RET -; -; FREE BLOCK WAS NOT FOUND. IF (BC) IS NOT ZERO, THEN WE HAVE -; NOT CHECKED ALL OF THE DISK SPACE. -; -FNDSPA4:LD A,C - OR B - JP NZ,FNDSPA1 - LD HL,0 ; SET 'NOT FOUND' STATUS. - RET -; -; MOVE A COMPLETE FCB ENTRY INTO THE DIRECTORY AND WRITE IT. -; -FCBSET: LD C,0 - LD E,32 ; LENGTH OF EACH ENTRY. -; -; MOVE (E) BYTES FROM THE FCB POINTED TO BY (PARAMS) INTO -; FCB IN DIRECTORY STARTING AT RELATIVE BYTE (C). THIS UPDATED -; DIRECTORY BUFFER IS THEN WRITTEN TO THE DISK. -; -UPDATE: PUSH DE - LD B,0 ; SET (BC) TO RELATIVE BYTE POSITION. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - ADD HL,BC ; COMPUTE STARTING BYTE. - EX DE,HL - CALL FCB2HL ; GET ADDRESS OF FCB TO UPDATE IN DIRECTORY. - POP BC ; SET (C) TO NUMBER OF BYTES TO CHANGE. - CALL DE2HL -UPDATE1:CALL TRKSEC ; DETERMINE THE TRACK AND SECTOR AFFECTED. - JP DIRWRITE ; THEN WRITE THIS SECTOR OUT. -; -; ROUTINE TO CHANGE THE NAME OF ALL FILES ON THE DISK WITH A -; SPECIFIED NAME. THE FCB CONTAINS THE CURRENT NAME AS THE -; FIRST 12 CHARACTERS AND THE NEW NAME 16 BYTES INTO THE FCB. -; -CHGNAMES: - CALL CHKWPRT ; CHECK FOR A WRITE PROTECTED DISK. - LD C,12 ; MATCH FIRST 12 BYTES OF FCB ONLY. - CALL FINDFST ; GET FIRST NAME. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD A,(HL) ; GET USER NUMBER. - LD DE,16 ; MOVE OVER TO DESIRED NAME. - ADD HL,DE - LD (HL),A ; KEEP SAME USER NUMBER. -CHGNAM1:CALL CKFILPOS ; ANY MATCHING FILE FOUND? - RET Z ; NO, WE MUST BE DONE. - CALL CHKROFL ; CHECK FOR READ ONLY FILE. - LD C,16 ; START 16 BYTES INTO FCB. - LD E,12 ; AND UPDATE THE FIRST 12 BYTES OF DIRECTORY. - CALL UPDATE - CALL FINDNXT ; GET TE NEXT FILE NAME. - JP CHGNAM1 ; AND CONTINUE. -; -; UPDATE A FILES ATTRIBUTES. THE PROCEDURE IS TO SEARCH FOR -; EVERY FILE WITH THE SAME NAME AS SHOWN IN FCB (IGNORING BIT 7) -; AND THEN TO UPDATE IT (WHICH INCLUDES BIT 7). NO OTHER CHANGES -; ARE MADE. -; -SAVEATTR: - LD C,12 ; MATCH FIRST 12 BYTES. - CALL FINDFST ; LOOK FOR FIRST FILENAME. -SAVATR1:CALL CKFILPOS ; WAS ONE FOUND? - RET Z ; NOPE, WE MUST BE DONE. - LD C,0 ; YES, UPDATE THE FIRST 12 BYTES NOW. - LD E,12 - CALL UPDATE ; UPDATE FILENAME AND WRITE DIRECTORY. - CALL FINDNXT ; AND GET THE NEXT FILE. - JP SAVATR1 ; THEN CONTINUE UNTIL DONE. -; -; OPEN A FILE (NAME SPECIFIED IN FCB). -; -OPENIT: LD C,15 ; COMPARE THE FIRST 15 BYTES. - CALL FINDFST ; GET THE FIRST ONE IN DIRECTORY. - CALL CKFILPOS ; ANY AT ALL? - RET Z -OPENIT1:CALL SETEXT ; POINT TO EXTENT BYTE WITHIN USERS FCB. - LD A,(HL) ; AND GET IT. - PUSH AF ; SAVE IT AND ADDRESS. - PUSH HL - CALL FCB2HL ; POINT TO FCB IN DIRECTORY. - EX DE,HL - LD HL,(PARAMS) ; THIS IS THE USERS COPY. - LD C,32 ; MOVE IT INTO USERS SPACE. - PUSH DE - CALL DE2HL - CALL SETS2B7 ; SET BIT 7 IN 'S2' BYTE (UNMODIFIED). - POP DE ; NOW GET THE EXTENT BYTE FROM THIS FCB. - LD HL,12 - ADD HL,DE - LD C,(HL) ; INTO (C). - LD HL,15 ; NOW GET THE RECORD COUNT BYTE INTO (B). - ADD HL,DE - LD B,(HL) - POP HL ; KEEP THE SAME EXTENT AS THE USER HAD ORIGINALLY. - POP AF - LD (HL),A - LD A,C ; IS IT THE SAME AS IN THE DIRECTORY FCB? - CP (HL) - LD A,B ; IF YES, THEN USE THE SAME RECORD COUNT. - JP Z,OPENIT2 - LD A,0 ; IF THE USER SPECIFIED AN EXTENT GREATER THAN - JP C,OPENIT2 ; THE ONE IN THE DIRECTORY, THEN SET RECORD COUNT TO 0. - LD A,128 ; OTHERWISE SET TO MAXIMUM. -OPENIT2:LD HL,(PARAMS) ; SET RECORD COUNT IN USERS FCB TO (A). - LD DE,15 - ADD HL,DE ; COMPUTE RELATIVE POSITION. - LD (HL),A ; AND SET THE RECORD COUNT. - RET -; -; MOVE TWO BYTES FROM (DE) TO (HL) IF (AND ONLY IF) (HL) -; POINT TO A ZERO VALUE (16 BIT). -; RETURN WITH ZERO FLAG SET IT (DE) WAS MOVED. REGISTERS (DE) -; AND (HL) ARE NOT CHANGED. HOWEVER (A) IS. -; -MOVEWORD: - LD A,(HL) ; CHECK FOR A ZERO WORD. - INC HL - OR (HL) ; BOTH BYTES ZERO? - DEC HL - RET NZ ; NOPE, JUST RETURN. - LD A,(DE) ; YES, MOVE TWO BYTES FROM (DE) INTO - LD (HL),A ; THIS ZERO SPACE. - INC DE - INC HL - LD A,(DE) - LD (HL),A - DEC DE ; DON'T DISTURB THESE REGISTERS. - DEC HL - RET -; -; GET HERE TO CLOSE A FILE SPECIFIED BY (FCB). -; -CLOSEIT:XOR A ; CLEAR STATUS AND FILE POSITION BYTES. - LD (STATUS),A - LD (FILEPOS),A - LD (FILEPOS+1),A - CALL GETWPRT ; GET WRITE PROTECT BIT FOR THIS DRIVE. - RET NZ ; JUST RETURN IF IT IS SET. - CALL GETS2 ; ELSE GET THE 'S2' BYTE. - AND 80H ; AND LOOK AT BIT 7 (FILE UNMODIFIED?). - RET NZ ; JUST RETURN IF SET. - LD C,15 ; ELSE LOOK UP THIS FILE IN DIRECTORY. - CALL FINDFST - CALL CKFILPOS ; WAS IT FOUND? - RET Z ; JUST RETURN IF NOT. - LD BC,16 ; SET (HL) POINTING TO RECORDS USED SECTION. - CALL FCB2HL - ADD HL,BC - EX DE,HL - LD HL,(PARAMS) ; DO THE SAME FOR USERS SPECIFIED FCB. - ADD HL,BC - LD C,16 ; THIS MANY BYTES ARE PRESENT IN THIS EXTENT. -CLOSEIT1: - LD A,(BIGDISK) ; 8 OR 16 BIT RECORD NUMBERS? - OR A - JP Z,CLOSEIT4 - LD A,(HL) ; JUST 8 BIT. GET ONE FROM USERS FCB. - OR A - LD A,(DE) ; NOW GET ONE FROM DIRECTORY FCB. - JP NZ,CLOSEIT2 - LD (HL),A ; USERS BYTE WAS ZERO. UPDATE FROM DIRECTORY. -CLOSEIT2: - OR A - JP NZ,CLOSEIT3 - LD A,(HL) ; DIRECTORIES BYTE WAS ZERO, UPDATE FROM USERS FCB. - LD (DE),A -CLOSEIT3: - CP (HL) ; IF NEITHER ONE OF THESE BYTES WERE ZERO, - JP NZ,CLOSEIT7 ; THEN CLOSE ERROR IF THEY ARE NOT THE SAME. - JP CLOSEIT5 ; OK SO FAR, GET TO NEXT BYTE IN FCBS. -CLOSEIT4: - CALL MOVEWORD ; UPDATE USERS FCB IF IT IS ZERO. - EX DE,HL - CALL MOVEWORD ; UPDATE DIRECTORIES FCB IF IT IS ZERO. - EX DE,HL - LD A,(DE) ; IF THESE TWO VALUES ARE NO DIFFERENT, - CP (HL) ; THEN A CLOSE ERROR OCCURED. - JP NZ,CLOSEIT7 - INC DE ; CHECK SECOND BYTE. - INC HL - LD A,(DE) - CP (HL) - JP NZ,CLOSEIT7 - DEC C ; REMEMBER 16 BIT VALUES. -CLOSEIT5: - INC DE ; BUMP TO NEXT ITEM IN TABLE. - INC HL - DEC C ; THERE ARE 16 ENTRIES ONLY. - JP NZ,CLOSEIT1 ; CONTINUE IF MORE TO DO. - LD BC,0FFECH ; BACKUP 20 PLACES (EXTENT BYTE). - ADD HL,BC - EX DE,HL - ADD HL,BC - LD A,(DE) - CP (HL) ; DIRECTORY'S EXTENT ALREADY GREATER THAN THE - JP C,CLOSEIT6 ; USERS EXTENT? - LD (HL),A ; NO, UPDATE DIRECTORY EXTENT. - LD BC,3 ; AND UPDATE THE RECORD COUNT BYTE IN - ADD HL,BC ; DIRECTORIES FCB. - EX DE,HL - ADD HL,BC - LD A,(HL) ; GET FROM USER. - LD (DE),A ; AND PUT IN DIRECTORY. -CLOSEIT6: - LD A,0FFH ; SET 'WAS OPEN AND IS NOW CLOSED' BYTE. - LD (CLOSEFLG),A - JP UPDATE1 ; UPDATE THE DIRECTORY NOW. -CLOSEIT7: - LD HL,STATUS ; SET RETURN STATUS AND THEN RETURN. - DEC (HL) - RET -; -; ROUTINE TO GET THE NEXT EMPTY SPACE IN THE DIRECTORY. IT -; WILL THEN BE CLEARED FOR USE. -; -GETEMPTY: - CALL CHKWPRT ; MAKE SURE DISK IS NOT WRITE PROTECTED. - LD HL,(PARAMS) ; SAVE CURRENT PARAMETERS (FCB). - PUSH HL - LD HL,EMPTYFCB ; USE SPECIAL ONE FOR EMPTY SPACE. - LD (PARAMS),HL - LD C,1 ; SEARCH FOR FIRST EMPTY SPOT IN DIRECTORY. - CALL FINDFST ; (* ONLY CHECK FIRST BYTE *) - CALL CKFILPOS ; NONE? - POP HL - LD (PARAMS),HL ; RESTORE ORIGINAL FCB ADDRESS. - RET Z ; RETURN IF NO MORE SPACE. - EX DE,HL - LD HL,15 ; POINT TO NUMBER OF RECORDS FOR THIS FILE. - ADD HL,DE - LD C,17 ; AND CLEAR ALL OF THIS SPACE. - XOR A -GETMT1: LD (HL),A - INC HL - DEC C - JP NZ,GETMT1 - LD HL,13 ; CLEAR THE 'S1' BYTE ALSO. - ADD HL,DE - LD (HL),A - CALL CHKNMBR ; KEEP (SCRATCH1) WITHIN BOUNDS. - CALL FCBSET ; WRITE OUT THIS FCB ENTRY TO DIRECTORY. - JP SETS2B7 ; SET 'S2' BYTE BIT 7 (UNMODIFIED AT PRESENT). -; -; ROUTINE TO CLOSE THE CURRENT EXTENT AND OPEN THE NEXT ONE -; FOR READING. -; -GETNEXT:XOR A - LD (CLOSEFLG),A ; CLEAR CLOSE FLAG. - CALL CLOSEIT ; CLOSE THIS EXTENT. - CALL CKFILPOS - RET Z ; NOT THERE??? - LD HL,(PARAMS) ; GET EXTENT BYTE. - LD BC,12 - ADD HL,BC - LD A,(HL) ; AND INCREMENT IT. - INC A - AND 1FH ; KEEP WITHIN RANGE 0-31. - LD (HL),A - JP Z,GTNEXT1 ; OVERFLOW? - LD B,A ; MASK EXTENT BYTE. - LD A,(EXTMASK) - AND B - LD HL,CLOSEFLG ; CHECK CLOSE FLAG (0FFH IS OK). - AND (HL) - JP Z,GTNEXT2 ; IF ZERO, WE MUST READ IN NEXT EXTENT. - JP GTNEXT3 ; ELSE, IT IS ALREADY IN MEMORY. -GTNEXT1:LD BC,2 ; POINT TO THE 'S2' BYTE. - ADD HL,BC - INC (HL) ; AND BUMP IT. - LD A,(HL) ; TOO MANY EXTENTS? - AND 0FH - JP Z,GTNEXT5 ; YES, SET ERROR CODE. -; -; GET HERE TO OPEN THE NEXT EXTENT. -; -GTNEXT2:LD C,15 ; SET TO CHECK FIRST 15 BYTES OF FCB. - CALL FINDFST ; FIND THE FIRST ONE. - CALL CKFILPOS ; NONE AVAILABLE? - JP NZ,GTNEXT3 - LD A,(R.DWRTFLG) ; NO EXTENT PRESENT. CAN WE OPEN AN EMPTY ONE? - INC A ; 0FFH MEANS READING (SO NOT POSSIBLE). - JP Z,GTNEXT5 ; OR AN ERROR. - CALL GETEMPTY ; WE ARE WRITING, GET AN EMPTY ENTRY. - CALL CKFILPOS ; NONE? - JP Z,GTNEXT5 ; ERROR IF TRUE. - JP GTNEXT4 ; ELSE WE ARE ALMOST DONE. -GTNEXT3:CALL OPENIT1 ; OPEN THIS EXTENT. -GTNEXT4:CALL STRDATA ; MOVE IN UPDATED DATA (REC #, EXTENT #, ETC.) - XOR A ; CLEAR STATUS AND RETURN. - JP SETSTAT -; -; ERROR IN EXTENDING THE FILE. TOO MANY EXTENTS WERE NEEDED -; OR NOT ENOUGH SPACE ON THE DISK. -; -GTNEXT5:CALL IOERR1 ; SET ERROR CODE, CLEAR BIT 7 OF 'S2' - JP SETS2B7 ; SO THIS IS NOT WRITTEN ON A CLOSE. -; -; READ A S.EQUENTIAL FILE. -; -RDSEQ: LD A,1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -RDSEQ1: LD A,0FFH ; DON'T ALLOW READING UNWRITTEN SPACE. - LD (R.DWRTFLG),A - CALL STRDATA ; PUT REC# AND EXT# INTO FCB. - LD A,(SAVNREC) ; GET NEXT RECORD TO READ. - LD HL,SAVNXT ; GET NUMBER OF RECORDS IN EXTENT. - CP (HL) ; WITHIN THIS EXTENT? - JP C,RDSEQ2 - CP 128 ; NO. IS THIS EXTENT FULLY USED? - JP NZ,RDSEQ3 ; NO. END-OF-FILE. - CALL GETNEXT ; YES, OPEN THE NEXT ONE. - XOR A ; RESET NEXT RECORD TO READ. - LD (SAVNREC),A - LD A,(STATUS) ; CHECK ON OPEN, SUCCESSFUL? - OR A - JP NZ,RDSEQ3 ; NO, ERROR. -RDSEQ2: CALL COMBLK ; OK. COMPUTE BLOCK NUMBER TO READ. - CALL CHKBLK ; CHECK IT. WITHIN BOUNDS? - JP Z,RDSEQ3 ; NO, ERROR. - CALL LOGICAL ; CONVERT (BLKNMBR) TO LOGICAL SECTOR (128 BYTE). - CALL TRKSEC1 ; SET THE TRACK AND SECTOR FOR THIS BLOCK #. - CALL DOREAD ; AND READ IT. - JP SETNREC ; AND SET THE NEXT RECORD TO BE ACCESSED. -; -; READ ERROR OCCURED. SET STATUS AND RETURN. -; -RDSEQ3: JP IOERR1 -; -; WRITE THE NEXT S.EQUENTIAL RECORD. -; -WTSEQ: LD A,1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -WTSEQ1: LD A,0 ; ALLOW AN ADDITION EMPTY EXTENT TO BE OPENED. - LD (R.DWRTFLG),A - CALL CHKWPRT ; CHECK WRITE PROTECT STATUS. - LD HL,(PARAMS) - CALL CKROF1 ; CHECK FOR READ ONLY FILE, (HL) ALREADY SET TO FCB. - CALL STRDATA ; PUT UPDATED DATA INTO FCB. - LD A,(SAVNREC) ; GET RECORD NUMBER TO WRITE. - CP 128 ; WITHIN RANGE? - JP NC,IOERR1 ; NO, ERROR(?). - CALL COMBLK ; COMPUTE BLOCK NUMBER. - CALL CHKBLK ; CHECK NUMBER. - LD C,0 ; IS THERE ONE TO WRITE TO? - JP NZ,WTSEQ6 ; YES, GO DO IT. - CALL GETBLOCK ; GET NEXT BLOCK NUMBER WITHIN FCB TO USE. - LD (RELBLOCK),A ; AND SAVE. - LD BC,0 ; START LOOKING FOR SPACE FROM THE START - OR A ; IF NONE ALLOCATED AS YET. - JP Z,WTSEQ2 - LD C,A ; EXTRACT PREVIOUS BLOCK NUMBER FROM FCB - DEC BC ; SO WE CAN BE CLOSEST TO IT. - CALL EXTBLK - LD B,H - LD C,L -WTSEQ2: CALL FNDSPACE ; FIND THE NEXT EMPTY BLOCK NEAREST NUMBER (BC). - LD A,L ; CHECK FOR A ZERO NUMBER. - OR H - JP NZ,WTSEQ3 - LD A,2 ; NO MORE SPACE? - JP SETSTAT -WTSEQ3: LD (BLKNMBR),HL ; SAVE BLOCK NUMBER TO ACCESS. - EX DE,HL ; PUT BLOCK NUMBER INTO (DE). - LD HL,(PARAMS) ; NOW WE MUST UPDATE THE FCB FOR THIS - LD BC,16 ; NEWLY ALLOCATED BLOCK. - ADD HL,BC - LD A,(BIGDISK) ; 8 OR 16 BIT BLOCK NUMBERS? - OR A - LD A,(RELBLOCK) ; (* UPDATE THIS ENTRY *) - JP Z,WTSEQ4 ; ZERO MEANS 16 BIT ONES. - CALL ADDA2HL ; (HL)=(HL)+(A) - LD (HL),E ; STORE NEW BLOCK NUMBER. - JP WTSEQ5 -WTSEQ4: LD C,A ; COMPUTE SPOT IN THIS 16 BIT TABLE. - LD B,0 - ADD HL,BC - ADD HL,BC - LD (HL),E ; STUFF BLOCK NUMBER (DE) THERE. - INC HL - LD (HL),D -WTSEQ5: LD C,2 ; SET (C) TO INDICATE WRITING TO UN-USED DISK SPACE. -WTSEQ6: LD A,(STATUS) ; ARE WE OK SO FAR? - OR A - RET NZ - PUSH BC ; YES, SAVE WRITE FLAG FOR BIOS (REGISTER C). - CALL LOGICAL ; CONVERT (BLKNMBR) OVER TO LOICAL SECTORS. - LD A,(MODE) ; GET ACCESS MODE FLAG (1=S.EQUENTIAL, - DEC A ; 0=RANDOM, 2=SPECIAL?). - DEC A - JP NZ,WTSEQ9 -; -; SPECIAL RANDOM I/O FROM FUNCTION #40. MAYBE FOR M/PM, BUT THE -; CURRENT BLOCK, IF IT HAS NOT BEEN WRITTEN TO, WILL BE ZEROED -; OUT AND THEN WRITTEN (REASON?). -; - POP BC - PUSH BC - LD A,C ; GET WRITE STATUS FLAG (2=WRITING UNUSED SPACE). - DEC A - DEC A - JP NZ,WTSEQ9 - PUSH HL - LD HL,(DIRBUF) ; ZERO OUT THE DIRECTORY BUFFER. - LD D,A ; NOTE THAT (A) IS ZERO HERE. -WTSEQ7: LD (HL),A - INC HL - INC D ; DO 128 BYTES. - JP P,WTSEQ7 - CALL DIRDMA ; TELL THE BIOS THE DMA ADDRESS FOR DIRECTORY ACCESS. - LD HL,(LOGSECT) ; GET SECTOR THAT STARTS CURRENT BLOCK. - LD C,2 ; SET 'WRITING TO UNUSED SPACE' FLAG. -WTSEQ8: LD (BLKNMBR),HL ; SAVE SECTOR TO WRITE. - PUSH BC - CALL TRKSEC1 ; DETERMINE ITS TRACK AND SECTOR NUMBERS. - POP BC - CALL DOWRITE ; NOW WRITE OUT 128 BYTES OF ZEROS. - LD HL,(BLKNMBR) ; GET SECTOR NUMBER. - LD C,0 ; SET NORMAL WRITE FLAG. - LD A,(BLKMASK) ; DETERMINE IF WE HAVE WRITTEN THE ENTIRE - LD B,A ; PHYSICAL BLOCK. - AND L - CP B - INC HL ; PREPARE FOR THE NEXT ONE. - JP NZ,WTSEQ8 ; CONTINUE UNTIL (BLKMASK+1) SECTORS WRITTEN. - POP HL ; RESET NEXT SECTOR NUMBER. - LD (BLKNMBR),HL - CALL DEFDMA ; AND RESET DMA ADDRESS. -; -; NORMAL DISK WRITE. SET THE DESIRED TRACK AND SECTOR THEN -; DO THE ACTUAL WRITE. -; -WTSEQ9: CALL TRKSEC1 ; DETERMINE TRACK AND SECTOR FOR THIS WRITE. - POP BC ; GET WRITE STATUS FLAG. - PUSH BC - CALL DOWRITE ; AND WRITE THIS OUT. - POP BC - LD A,(SAVNREC) ; GET NUMBER OF RECORDS IN FILE. - LD HL,SAVNXT ; GET LAST RECORD WRITTEN. - CP (HL) - JP C,WTSEQ10 - LD (HL),A ; WE HAVE TO UPDATE RECORD COUNT. - INC (HL) - LD C,2 -; -;* THIS AREA HAS BEEN PATCHED TO CORRECT DISK UPDATE PROBLEM -;* WHEN USING BLOCKING AND DE-BLOCKING IN THE BIOS. -; -WTSEQ10:NOP ; WAS 'DCR C' - NOP ; WAS 'DCR C' - LD HL,0 ; WAS 'JNZ WTSEQ99' -; -; * END OF PATCH. -; - PUSH AF - CALL GETS2 ; SET 'EXTENT WRITTEN TO' FLAG. - AND 7FH ; (* CLEAR BIT 7 *) - LD (HL),A - POP AF ; GET RECORD COUNT FOR THIS EXTENT. -WTSEQ99:CP 127 ; IS IT FULL? - JP NZ,WTSEQ12 - LD A,(MODE) ; YES, ARE WE IN S.EQUENTIAL MODE? - CP 1 - JP NZ,WTSEQ12 - CALL SETNREC ; YES, SET NEXT RECORD NUMBER. - CALL GETNEXT ; AND GET NEXT EMPTY SPACE IN DIRECTORY. - LD HL,STATUS ; OK? - LD A,(HL) - OR A - JP NZ,WTSEQ11 - DEC A ; YES, SET RECORD COUNT TO -1. - LD (SAVNREC),A -WTSEQ11:LD (HL),0 ; CLEAR STATUS. -WTSEQ12:JP SETNREC ; SET NEXT RECORD TO ACCESS. -; -; FOR RANDOM I/O, SET THE FCB FOR THE DESIRED RECORD NUMBER -; BASED ON THE 'R0,R1,R2' BYTES. THESE BYTES IN THE FCB ARE -; USED AS FOLLOWS: -; -; FCB+35 FCB+34 FCB+33 -; | 'R-2' | 'R-1' | 'R-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | OVERFLOW | | EXTRA | EXTENT | RECORD # | -; | ______________| |_EXTENT|__NUMBER___|_____________| -; ALSO 'S2' -; -; ON ENTRY, REGISTER (C) CONTAINS 0FFH IF THIS IS A READ -; AND THUS WE CAN NOT ACCESS UNWRITTEN DISK SPACE. OTHERWISE, -; ANOTHER EXTENT WILL BE OPENED (FOR WRITING) IF R.EQUIRED. -; -POSITION: - XOR A ; SET RANDOM I/O FLAG. - LD (MODE),A -; -; SPECIAL ENTRY (FUNCTION #40). M/PM ? -; -POSITN1:PUSH BC ; SAVE READ/WRITE FLAG. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - EX DE,HL - LD HL,33 ; NOW GET BYTE 'R0'. - ADD HL,DE - LD A,(HL) - AND 7FH ; KEEP BITS 0-6 FOR THE RECORD NUMBER TO ACCESS. - PUSH AF - LD A,(HL) ; NOW GET BIT 7 OF 'R0' AND BITS 0-3 OF 'R1'. - RLA - INC HL - LD A,(HL) - RLA - AND 1FH ; AND SAVE THIS IN BITS 0-4 OF (C). - LD C,A ; THIS IS THE EXTENT BYTE. - LD A,(HL) ; NOW GET THE EXTRA EXTENT BYTE. - RRA - RRA - RRA - RRA - AND 0FH - LD B,A ; AND SAVE IT IN (B). - POP AF ; GET RECORD NUMBER BACK TO (A). - INC HL ; CHECK OVERFLOW BYTE 'R2'. - LD L,(HL) - INC L - DEC L - LD L,6 ; PREPARE FOR ERROR. - JP NZ,POSITN5 ; OUT OF DISK SPACE ERROR. - LD HL,32 ; STORE RECORD NUMBER INTO FCB. - ADD HL,DE - LD (HL),A - LD HL,12 ; AND NOW CHECK THE EXTENT BYTE. - ADD HL,DE - LD A,C - SUB (HL) ; SAME EXTENT AS BEFORE? - JP NZ,POSITN2 - LD HL,14 ; YES, CHECK EXTRA EXTENT BYTE 'S2' ALSO. - ADD HL,DE - LD A,B - SUB (HL) - AND 7FH - JP Z,POSITN3 ; SAME, WE ARE ALMOST DONE THEN. -; -; GET HERE WHEN ANOTHER EXTENT IS R.EQUIRED. -; -POSITN2:PUSH BC - PUSH DE - CALL CLOSEIT ; CLOSE CURRENT EXTENT. - POP DE - POP BC - LD L,3 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; CLOSE ERROR. - LD HL,12 ; PUT DESIRED EXTENT INTO FCB NOW. - ADD HL,DE - LD (HL),C - LD HL,14 ; AND STORE EXTRA EXTENT BYTE 'S2'. - ADD HL,DE - LD (HL),B - CALL OPENIT ; TRY AND GET THIS EXTENT. - LD A,(STATUS) ; WAS IT THERE? - INC A - JP NZ,POSITN3 - POP BC ; NO. CAN WE CREATE A NEW ONE (WRITING?). - PUSH BC - LD L,4 ; PREPARE FOR ERROR. - INC C - JP Z,POSITN4 ; NOPE, READING UNWRITTEN SPACE ERROR. - CALL GETEMPTY ; YES WE CAN, TRY TO FIND SPACE. - LD L,5 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; OUT OF SPACE? -; -; NORMAL RETURN LOCATION. CLEAR ERROR CODE AND RETURN. -; -POSITN3:POP BC ; RESTORE STACK. - XOR A ; AND CLEAR ERROR CODE BYTE. - JP SETSTAT -; -; ERROR. SET THE 'S2' BYTE TO INDICATE THIS (WHY?). -; -POSITN4:PUSH HL - CALL GETS2 - LD (HL),0C0H - POP HL -; -; RETURN WITH ERROR CODE (PRESENTLY IN L). -; -POSITN5:POP BC - LD A,L ; GET ERROR CODE. - LD (STATUS),A - JP SETS2B7 -; -; READ A RANDOM RECORD. -; -READRAN:LD C,0FFH ; SET 'READ' STATUS. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,RDSEQ1 ; AND READ IT AS USUAL (IF NO ERRORS). - RET -; -; WRITE TO A RANDOM RECORD. -; -WRITERAN: - LD C,0 ; SET 'WRITING' FLAG. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,WTSEQ1 ; AND WRITE AS USUAL (IF NO ERRORS). - RET -; -; COMPUTE THE RANDOM RECORD NUMBER. ENTER WITH (HL) POINTING -; TO A FCB AN (DE) CONTAINS A RELATIVE LOCATION OF A RECORD -; NUMBER. ON EXIT, (C) CONTAINS THE 'R0' BYTE, (B) THE 'R1' -; BYTE, AND (A) THE 'R2' BYTE. -; -; ON RETURN, THE ZERO FLAG IS SET IF THE RECORD IS WITHIN -; BOUNDS. OTHERWISE, AN OVERFLOW OCCURED. -; -COMPRAND: - EX DE,HL ; SAVE FCB POINTER IN (DE). - ADD HL,DE ; COMPUTE RELATIVE POSITION OF RECORD #. - LD C,(HL) ; GET RECORD NUMBER INTO (BC). - LD B,0 - LD HL,12 ; NOW GET EXTENT. - ADD HL,DE - LD A,(HL) ; COMPUTE (BC)=(RECORD #)+(EXTENT)*128. - RRCA ; MOVE LOWER BIT INTO BIT 7. - AND 80H ; AND IGNORE ALL OTHER BITS. - ADD A,C ; ADD TO OUR RECORD NUMBER. - LD C,A - LD A,0 ; TAKE CARE OF ANY CARRY. - ADC A,B - LD B,A - LD A,(HL) ; NOW GET THE UPPER BITS OF EXTENT INTO - RRCA ; BIT POSITIONS 0-3. - AND 0FH ; AND IGNORE ALL OTHERS. - ADD A,B ; ADD THIS IN TO 'R1' BYTE. - LD B,A - LD HL,14 ; GET THE 'S2' BYTE (EXTRA EXTENT). - ADD HL,DE - LD A,(HL) - ADD A,A ; AND SHIFT IT LEFT 4 BITS (BITS 4-7). - ADD A,A - ADD A,A - ADD A,A - PUSH AF ; SAVE CARRY FLAG (BIT 0 OF FLAG BYTE). - ADD A,B ; NOW ADD EXTRA EXTENT INTO 'R1'. - LD B,A - PUSH AF ; AND SAVE CARRY (OVERFLOW BYTE 'R2'). - POP HL ; BIT 0 OF (L) IS THE OVERFLOW INDICATOR. - LD A,L - POP HL ; AND SAME FOR FIRST CARRY FLAG. - OR L ; EITHER ONE OF THESE SET? - AND 01H ; ONLY CHECK THE CARRY FLAGS. - RET -; -; ROUTINE TO SETUP THE FCB (BYTES 'R0', 'R1', 'R2') TO -; REFLECT THE LAST RECORD USED FOR A RANDOM (OR OTHER) FILE. -; THIS READS THE DIRECTORY AND LOOKS AT ALL EXTENTS COMPUTING -; THE LARGERST RECORD NUMBER FOR EACH AND KEEPING THE MAXIMUM -; VALUE ONLY. THEN 'R0', 'R1', AND 'R2' WILL REFLECT THIS -; MAXIMUM RECORD NUMBER. THIS IS USED TO COMPUTE THE SPACE USED -; BY A RANDOM FILE. -; -RANSIZE:LD C,12 ; LOOK THRU DIRECTORY FOR FIRST ENTRY WITH - CALL FINDFST ; THIS NAME. - LD HL,(PARAMS) ; ZERO OUT THE 'R0, R1, R2' BYTES. - LD DE,33 - ADD HL,DE - PUSH HL - LD (HL),D ; NOTE THAT (D)=0. - INC HL - LD (HL),D - INC HL - LD (HL),D -RANSIZ1:CALL CKFILPOS ; IS THERE AN EXTENT TO PROCESS? - JP Z,RANSIZ3 ; NO, WE ARE DONE. - CALL FCB2HL ; SET (HL) POINTING TO PROPER FCB IN DIR. - LD DE,15 ; POINT TO LAST RECORD IN EXTENT. - CALL COMPRAND ; AND COMPUTE RANDOM PARAMETERS. - POP HL - PUSH HL ; NOW CHECK THESE VALUES AGAINST THOSE - LD E,A ; ALREADY IN FCB. - LD A,C ; THE CARRY FLAG WILL BE SET IF THOSE - SUB (HL) ; IN THE FCB REPRESENT A LARGER SIZE THAN - INC HL ; THIS EXTENT DOES. - LD A,B - SBC A,(HL) - INC HL - LD A,E - SBC A,(HL) - JP C,RANSIZ2 - LD (HL),E ; WE FOUND A LARGER (IN SIZE) EXTENT. - DEC HL ; STUFF THESE VALUES INTO FCB. - LD (HL),B - DEC HL - LD (HL),C -RANSIZ2:CALL FINDNXT ; NOW GET THE NEXT EXTENT. - JP RANSIZ1 ; CONTINUE TIL ALL DONE. -RANSIZ3:POP HL ; WE ARE DONE, RESTORE THE STACK AND - RET ; RETURN. -; -; FUNCTION TO RETURN THE RANDOM RECORD POSITION OF A GIVEN -; FILE WHICH HAS BEEN READ IN S.EQUENTIAL MODE UP TO NOW. -; -SETRAN: LD HL,(PARAMS) ; POINT TO FCB. - LD DE,32 ; AND TO LAST USED RECORD. - CALL COMPRAND ; COMPUTE RANDOM POSITION. - LD HL,33 ; NOW STUFF THESE VALUES INTO FCB. - ADD HL,DE - LD (HL),C ; MOVE 'R0'. - INC HL - LD (HL),B ; AND 'R1'. - INC HL - LD (HL),A ; AND LASTLY 'R2'. - RET -; -; THIS ROUTINE SELECT THE DRIVE SPECIFIED IN (ACTIVE) AND -; UPDATE THE LOGIN VECTOR AND BITMAP TABLE IF THIS DRIVE WAS -; NOT ALREADY ACTIVE. -; -LOGINDRV: - LD HL,(LOGIN) ; GET THE LOGIN VECTOR. - LD A,(ACTIVE) ; GET THE DEFAULT DRIVE. - LD C,A - CALL SHIFTR ; POSITION ACTIVE BIT FOR THIS DRIVE - PUSH HL ; INTO BIT 0. - EX DE,HL - CALL SELECT ; SELECT THIS DRIVE. - POP HL - CALL Z,SLCTERR ; VALID DRIVE? - LD A,L ; IS THIS A NEWLY ACTIVATED DRIVE? - RRA - RET C - LD HL,(LOGIN) ; YES, UPDATE THE LOGIN VECTOR. - LD C,L - LD B,H - CALL SETBIT - LD (LOGIN),HL ; AND SAVE. - JP BITMAP ; NOW UPDATE THE BITMAP. -; -; FUNCTION TO SET THE ACTIVE DISK NUMBER. -; -SETDSK: LD A,(EPARAM) ; GET PARAMETER PASSED AND SEE IF THIS - LD HL,ACTIVE ; REPRESENTS A CHANGE IN DRIVES. - CP (HL) - RET Z - LD (HL),A ; YES IT DOES, LOG IT IN. - JP LOGINDRV -; -; THIS IS THE 'AUTO DISK SELECT' ROUTINE. THE FIRSST BYTE -; OF THE FCB IS EXAMINED FOR A DRIVE SPECIFICATION. IF NON -; ZERO THEN THE DRIVE WILL BE SELECTED AND LOGED IN. -; -AUTOSEL:LD A,0FFH ; SAY 'AUTO-SELECT ACTIVATED'. - LD (AUTO),A - LD HL,(PARAMS) ; GET DRIVE SPECIFIED. - LD A,(HL) - AND 1FH ; LOOK AT LOWER 5 BITS. - DEC A ; ADJUST FOR (1=A, 2=B) ETC. - LD (EPARAM),A ; AND SAVE FOR THE SELECT ROUTINE. - CP 1EH ; CHECK FOR 'NO CHANGE' CONDITION. - JP NC,AUTOSL1 ; YES, DON'T CHANGE. - LD A,(ACTIVE) ; WE MUST CHANGE, SAVE CURRENTLY ACTIVE - LD (OLDDRV),A ; DRIVE. - LD A,(HL) ; AND SAVE FIRST BYTE OF FCB ALSO. - LD (AUTOFLAG),A ; THIS MUST BE NON-ZERO. - AND 0E0H ; WHATS THIS FOR (BITS 6,7 ARE USED FOR - LD (HL),A ; SOMETHING)? - CALL SETDSK ; SELECT AND LOG IN THIS DRIVE. -AUTOSL1:LD A,(USERNO) ; MOVE USER NUMBER INTO FCB. - LD HL,(PARAMS) ; (* UPPER HALF OF FIRST BYTE *) - OR (HL) - LD (HL),A - RET ; AND RETURN (ALL DONE). -; -; FUNCTION TO RETURN THE CURRENT CP/M VERSION NUMBER. -; -GETVER: LD A,022H ; VERSION 2.2 - JP SETSTAT -; -; FUNCTION TO RESET THE DISK SYSTEM. -; -RSTDSK: LD HL,0 ; CLEAR WRITE PROTECT STATUS AND LOG - LD (WRTPRT),HL ; IN VECTOR. - LD (LOGIN),HL - XOR A ; SELECT DRIVE 'A'. - LD (ACTIVE),A - LD HL,TBUFF ; SETUP DEFAULT DMA ADDRESS. - LD (USERDMA),HL - CALL DEFDMA - JP LOGINDRV ; NOW LOG IN DRIVE 'A'. -; -; FUNCTION TO OPEN A SPECIFIED FILE. -; -OPENFIL:CALL CLEARS2 ; CLEAR 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DISK. - JP OPENIT ; AND OPEN THE FILE. -; -; FUNCTION TO CLOSE A SPECIFIED FILE. -; -CLOSEFIL: - CALL AUTOSEL ; SELECT PROPER DISK. - JP CLOSEIT ; AND CLOSE THE FILE. -; -; FUNCTION TO RETURN THE FIRST OCCURENCE OF A SPECIFIED FILE -; NAME. IF THE FIRST BYTE OF THE FCB IS '?' THEN THE NAME WILL -; NOT BE CHECKED (GET THE FIRST ENTRY NO MATTER WHAT). -; -GETFST: LD C,0 ; PREPARE FOR SPECIAL SEARCH. - EX DE,HL - LD A,(HL) ; IS FIRST BYTE A '?'? - CP '?' - JP Z,GETFST1 ; YES, JUST GET VERY FIRST ENTRY (ZERO LENGTH MATCH). - CALL SETEXT ; GET THE EXTENSION BYTE FROM FCB. - LD A,(HL) ; IS IT '?'? IF YES, THEN WE WANT - CP '?' ; AN ENTRY WITH A SPECIFIC 'S2' BYTE. - CALL NZ,CLEARS2 ; OTHERWISE, LOOK FOR A ZERO 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DRIVE. - LD C,15 ; COMPARE BYTES 0-14 IN FCB (12&13 EXCLUDED). -GETFST1:CALL FINDFST ; FIND AN ENTRY AND THEN MOVE IT INTO - JP MOVEDIR ; THE USERS DMA SPACE. -; -; FUNCTION TO RETURN THE NEXT OCCURENCE OF A FILE NAME. -; -GETNXT: LD HL,(SAVEFCB) ; RESTORE POINTERS. NOTE THAT NO - LD (PARAMS),HL ; OTHER .DBOS CALLS ARE ALLOWED. - CALL AUTOSEL ; NO ERROR WILL BE RETURNED, BUT THE - CALL FINDNXT ; RESULTS WILL BE WRONG. - JP MOVEDIR -; -; FUNCTION TO DELETE A FILE BY NAME. -; -DELFILE:CALL AUTOSEL ; SELECT PROPER DRIVE. - CALL ERAFILE ; ERASE THE FILE. - JP STSTATUS ; SET STATUS AND RETURN. -; -; FUNCTION TO EXECUTE A S.EQUENTIAL READ OF THE SPECIFIED -; RECORD NUMBER. -; -READSEQ:CALL AUTOSEL ; SELECT PROPER DRIVE THEN READ. - JP RDSEQ -; -; FUNCTION TO WRITE THE NET S.EQUENTIAL RECORD. -; -WRTSEQ: CALL AUTOSEL ; SELECT PROPER DRIVE THEN WRITE. - JP WTSEQ -; -; CREATE A FILE FUNCTION. -; -FCREATE:CALL CLEARS2 ; CLEAR THE 'S2' BYTE ON ALL CREATES. - CALL AUTOSEL ; SELECT PROPER DRIVE AND GET THE NEXT - JP GETEMPTY ; EMPTY DIRECTORY SPACE. -; -; FUNCTION TO RENAME A FILE. -; -RENFILE:CALL AUTOSEL ; SELECT PROPER DRIVE AND THEN SWITCH - CALL CHGNAMES ; FILE NAMES. - JP STSTATUS -; -; FUNCTION TO RETURN THE LOGIN VECTOR. -; -GETLOG: LD HL,(LOGIN) - JP GETPRM1 -; -; FUNCTION TO RETURN THE CURRENT DISK ASSIGNMENT. -; -GETCRNT:LD A,(ACTIVE) - JP SETSTAT -; -; FUNCTION TO SET THE DMA ADDRESS. -; -PUTDMA: EX DE,HL - LD (USERDMA),HL ; SAVE IN OUR SPACE AND THEN GET TO - JP DEFDMA ; THE BIOS WITH THIS ALSO. -; -; FUNCTION TO RETURN THE ALLOCATION VECTOR. -; -GETALOC:LD HL,(ALOCVECT) - JP GETPRM1 -; -; FUNCTION TO RETURN THE READ-ONLY STATUS VECTOR. -; -GETROV: LD HL,(WRTPRT) - JP GETPRM1 -; -; FUNCTION TO SET THE FILE ATTRIBUTES (READ-ONLY, SYSTEM). -; -SETATTR:CALL AUTOSEL ; SELECT PROPER DRIVE THEN SAVE ATTRIBUTES. - CALL SAVEATTR - JP STSTATUS -; -; FUNCTION TO RETURN THE ADDRESS OF THE DISK PARAMETER BLOCK -; FOR THE CURRENT DRIVE. -; -GETPARM:LD HL,(DISKPB) -GETPRM1:LD (STATUS),HL - RET -; -; FUNCTION TO GET OR SET THE USER NUMBER. IF (E) WAS (FF) -; THEN THIS IS A R.EQUEST TO RETURN THE CURRENT USER NUMBER. -; ELSE SET THE USER NUMBER FROM (E). -; -GETUSER:LD A,(EPARAM) ; GET PARAMETER. - CP 0FFH ; GET USER NUMBER? - JP NZ,SETUSER - LD A,(USERNO) ; YES, JUST DO IT. - JP SETSTAT -SETUSER:AND 1FH ; NO, WE SHOULD SET IT INSTEAD. KEEP LOW - LD (USERNO),A ; BITS (0-4) ONLY. - RET -; -; FUNCTION TO READ A RANDOM RECORD FROM A FILE. -; -RDRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND READ. - JP READRAN -; -; FUNCTION TO COMPUTE THE FILE SIZE FOR RANDOM FILES. -; -WTRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND WRITE. - JP WRITERAN -; -; FUNCTION TO COMPUTE THE SIZE OF A RANDOM FILE. -; -FILESIZE: - CALL AUTOSEL ; SELECT PROPER DRIVE AND CHECK FILE LENGTH - JP RANSIZE -; -; FUNCTION #37. THIS ALLOWS A PROGRAM TO LOG OFF ANY DRIVES. -; ON ENTRY, SET (DE) TO CONTAIN A WORD WITH BITS SET FOR THOSE -; DRIVES THAT ARE TO BE LOGGED OFF. THE LOG-IN VECTOR AND THE -; WRITE PROTECT VECTOR WILL BE UPDATED. THIS MUST BE A M/PM -; SPECIAL FUNCTION. -; -LOGOFF: LD HL,(PARAMS) ; GET DRIVES TO LOG OFF. - LD A,L ; FOR EACH BIT THAT IS SET, WE WANT - CPL ; TO CLEAR THAT BIT IN (LOGIN) - LD E,A ; AND (WRTPRT). - LD A,H - CPL - LD HL,(LOGIN) ; RESET THE LOGIN VECTOR. - AND H - LD D,A - LD A,L - AND E - LD E,A - LD HL,(WRTPRT) - EX DE,HL - LD (LOGIN),HL ; AND SAVE. - LD A,L ; NOW DO THE WRITE PROTECT VECTOR. - AND E - LD L,A - LD A,H - AND D - LD H,A - LD (WRTPRT),HL ; AND SAVE. ALL DONE. - RET -; -; GET HERE TO RETURN TO THE USER. -; -GOBACK: LD A,(AUTO) ; WAS AUTO SELECT ACTIVATED? - OR A - JP Z,GOBACK1 - LD HL,(PARAMS) ; YES, BUT WAS A CHANGE MADE? - LD (HL),0 ; (* RESET FIRST BYTE OF FCB *) - LD A,(AUTOFLAG) - OR A - JP Z,GOBACK1 - LD (HL),A ; YES, RESET FIRST BYTE PROPERLY. - LD A,(OLDDRV) ; AND GET THE OLD DRIVE AND SELECT IT. - LD (EPARAM),A - CALL SETDSK -GOBACK1:LD HL,(USRSTACK) ; RESET THE USERS STACK POINTER. - LD SP,HL - LD HL,(STATUS) ; GET RETURN STATUS. - LD A,L ; FORCE VERSION 1.4 COMPATABILITY. - LD B,H - RET ; AND GO BACK TO USER. -; -; FUNCTION #40. THIS IS A SPECIAL ENTRY TO DO RANDOM I/O. -; FOR THE CASE WHERE WE ARE WRITING TO UNUSED DISK SPACE, THIS -; SPACE WILL BE ZEROED OUT FIRST. THIS MUST BE A M/PM SPECIAL -; PURPOSE FUNCTION, BECAUSE WHY WOULD ANY NORMAL PROGRAM EVEN -; CARE ABOUT THE PREVIOUS CONTENTS OF A SECTOR ABOUT TO BE -; WRITTEN OVER. -; -WTSPECL:CALL AUTOSEL ; SELECT PROPER DRIVE. - LD A,2 ; USE SPECIAL WRITE MODE. - LD (MODE),A - LD C,0 ; SET WRITE INDICATOR. - CALL POSITN1 ; POSITION THE FILE. - CALL Z,WTSEQ1 ; AND WRITE (IF NO ERRORS). - RET -; -;************************************************************** -;* -;* BDOS DATA STORAGE POOL. -;* -;************************************************************** -; -EMPTYFCB: - .DB 0E5H ; EMPTY DIRECTORY SEGMENT INDICATOR. -WRTPRT: .DW 0 ; WRITE PROTECT STATUS FOR ALL 16 DRIVES. -LOGIN: .DW 0 ; DRIVE ACTIVE WORD (1 BIT PER DRIVE). -USERDMA:.DW 080H ; USER'S DMA ADDRESS (DEFAULTS TO 80H). -; -; SCRATCH AREAS FROM PARAMETER BLOCK. -; -SCRATCH1: - .DW 0 ; RELATIVE POSITION WITHIN DIR SEGMENT FOR FILE (0-3). -SCRATCH2: - .DW 0 ; LAST SELECTED TRACK NUMBER. -SCRATCH3: - .DW 0 ; LAST SELECTED SECTOR NUMBER. -; -; DISK STORAGE AREAS FROM PARAMETER BLOCK. -; -DIRBUF: .DW 0 ; ADDRESS OF DIRECTORY BUFFER TO USE. -DISKPB: .DW 0 ; CONTAINS ADDRESS OF DISK PARAMETER BLOCK. -CHKVECT:.DW 0 ; ADDRESS OF CHECK VECTOR. -ALOCVECT: - .DW 0 ; ADDRESS OF ALLOCATION VECTOR (BIT MAP). -; -; PARAMETER BLOCK RETURNED FROM THE BIOS. -; -SECTORS:.DW 0 ; SECTORS PER TRACK FROM BIOS. -BLKSHFT:.DB 0 ; BLOCK SHIFT. -BLKMASK:.DB 0 ; BLOCK MASK. -EXTMASK:.DB 0 ; EXTENT MASK. -DSKSIZE:.DW 0 ; DISK SIZE FROM BIOS (NUMBER OF BLOCKS-1). -DIRSIZE:.DW 0 ; DIRECTORY SIZE. -ALLOC0: .DW 0 ; STORAGE FOR FIRST BYTES OF BIT MAP (DIR SPACE USED). -ALLOC1: .DW 0 -OFFSET: .DW 0 ; FIRST USABLE TRACK NUMBER. -XLATE: .DW 0 ; SECTOR TRANSLATION TABLE ADDRESS. -; -; -CLOSEFLG: - .DB 0 ; CLOSE FLAG (=0FFH IS EXTENT WRITTEN OK). -R.DWRTFLG: - .DB 0 ; READ/WRITE FLAG (0FFH=READ, 0=WRITE). -FNDSTAT:.DB 0 ; FILENAME FOUND STATUS (0=FOUND FIRST ENTRY). -MODE: .DB 0 ; I/O MODE SELECT (0=RANDOM, 1=S.EQUENTIAL, 2=SPECIAL RANDOM). -EPARAM: .DB 0 ; STORAGE FOR REGISTER (E) ON ENTRY TO BDOS. -RELBLOCK: - .DB 0 ; RELATIVE POSITION WITHIN FCB OF BLOCK NUMBER WRITTEN. -COUNTER:.DB 0 ; BYTE COUNTER FOR DIRECTORY NAME SEARCHES. -SAVEFCB:.DW 0,0 ; SAVE SPACE FOR ADDRESS OF FCB (FOR DIRECTORY SEARCHES). -BIGDISK:.DB 0 ; IF =0 THEN DISK IS > 256 BLOCKS LONG. -AUTO: .DB 0 ; IF NON-ZERO, THEN AUTO SELECT ACTIVATED. -OLDDRV: .DB 0 ; ON AUTO SELECT, STORAGE FOR PREVIOUS DRIVE. -AUTOFLAG: - .DB 0 ; IF NON-ZERO, THEN AUTO SELECT CHANGED DRIVES. -SAVNXT: .DB 0 ; STORAGE FOR NEXT RECORD NUMBER TO ACCESS. -SAVEXT: .DB 0 ; STORAGE FOR EXTENT NUMBER OF FILE. -SAVNREC:.DW 0 ; STORAGE FOR NUMBER OF RECORDS IN FILE. -BLKNMBR:.DW 0 ; BLOCK NUMBER (PHYSICAL SECTOR) USED WITHIN A FILE OR LOGICAL SEC -LOGSECT:.DW 0 ; STARTING LOGICAL (128 BYTE) SECTOR OF BLOCK (PHYSICAL SECTOR). -FCBPOS: .DB 0 ; RELATIVE POSITION WITHIN BUFFER FOR FCB OF FILE OF INTEREST. -FILEPOS:.DW 0 ; FILES POSITION WITHIN DIRECTORY (0 TO MAX ENTRIES -1). -; -; DISK DIRECTORY BUFFER CHECKSUM BYTES. ONE FOR EACH OF THE -; 16 POSSIBLE DRIVES. -; -CKSUMTBL: - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; - -BIOS: .EQU BIOSO ;BIOS ORIGIN -; -BOOT: .EQU BIOS ;(BOOT) Cold boot entry -WBOOT: .EQU BIOS+3 ;Warm boot entry -CONST: .EQU BIOS+6 ;Console status -CONIN: .EQU BIOS+9 ;Console char in -CONOUT: .EQU BIOS+12 ;Console char out -LIST: .EQU BIOS+15 ;List char out -PUNCH: .EQU BIOS+18 ;Punch char out -READER: .EQU BIOS+21 ;Reader char in -HOME: .EQU BIOS+24 ;Home disk -SELDSK: .EQU BIOS+27 ;Select disk -SETTRK: .EQU BIOS+30 ;Set disk track addr -SETSEC: .EQU BIOS+33 ;Set disk sector addr -SETDMA: .EQU BIOS+36 ;Set DMA buffer addr -READ: .EQU BIOS+39 ;Read sector -WRITE: .EQU BIOS+42 ;Write sector -SECTRN: .EQU BIOS+48 ;Sector translation routine -; - .IF ENDFIL - .ORG BDOSO+0DFFH - .DB 55H - .ENDIF - .END diff --git a/branches/s100/cpurom/ref/n8-romim.ref b/branches/s100/cpurom/ref/n8-romim.ref deleted file mode 100644 index 33dfdad8..00000000 Binary files a/branches/s100/cpurom/ref/n8-romim.ref and /dev/null differ diff --git a/branches/s100/cpurom/src/baseline.c b/branches/s100/cpurom/src/baseline.c deleted file mode 100644 index 34b1b2c3..00000000 --- a/branches/s100/cpurom/src/baseline.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * baseline.c - Diagnostic EPROM for the N8VEM SBC V2 - * - */ - -#include -#include -#include -#include "portab.h" -#include "sbcv2.h" -#include "ns16550.h" - -/* #include "cpmbdos.h" */ - -/* THESE ARE USED BY THE LIBRARY ROUTINES */ -char getchar(void) -{ -/* - struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - return cpmbdos(&cread); -*/ - return 0; -} -void outchar(char c) -{ - if(c) ; -/* - struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)c } }; - cpmbdos(&cwrite); -*/ -} - - -void xdisable(void) -{ -} - -void xenable(void) -{ -} - -void intmode(U8 xmode) -{ - if(xmode); -} - -int main(void) -{ - pMPCL_ROM = 0x80; - pMPCL_RAM = 0x81; - - memcpy(0,0x0E5,0x2000); - - pMPCL_ROM = 0x80; - pMPCL_RAM = 0x00; - - xdisable(); - intmode(1); - pMPCL_ROM = 0x00; - pMPCL_RAM = 0x00; - - memcpy(RAMTARG_CPM,ROMSTART_CPM,CCPSIZ_CPM); - - pMPCL_ROM = 0x80; - pMPCL_RAM = 0x00; - return (0); -} - diff --git a/branches/s100/cpurom/src/bdosb01.s b/branches/s100/cpurom/src/bdosb01.s deleted file mode 100644 index 1cb003b2..00000000 --- a/branches/s100/cpurom/src/bdosb01.s +++ /dev/null @@ -1,2654 +0,0 @@ - .title bdosb01.s derived from bdosb01.asm - .sbttl by Douglas Goodall for N8VEM use '11 - - .module bdosb01 - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _bdos -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _CODE -;bdos.c:1: void bdos(void) -; --------------------------------- -; Function bdos -; --------------------------------- -_bdos_start:: -_bdos: - -;dwg-start; - .area _DATA -;dwg-end; - -ENDFIL = 1 ;FILL FULL BDOS LENGTH -; -IOBYTE = 3 ; I/O DEFINITION BYTE. -TDRIVE = 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY = 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB = 0x5C ; DEFAULT FILE CONTROL BLOCK. -TBUFF = 0x80 ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE = 0x100 ; TRANSIANT PROGRAM STORAGE AREA. -; -; SET CONTROL CHARACTER .EQUATES. -; -ASCIIA = 0x41 -AT = 0x40 -CNTRLC = 3 ; CONTROL-C -CNTRLE = 05 ; CONTROL-E -BS = 08 ; BACKSPACE -TAB = 09 ; TAB -LF = 0x0A ; LINE FEED -FF = 0x0C ; FORM FEED -CR = 0x0D ; CARRIAGE RETURN -CNTRLP = 0x10 ; CONTROL-P -CNTRLR = 0x12 ; CONTROL-R -CNTRLS = 0x13 ; CONTROL-S -CNTRLU = 0x15 ; CONTROL-U -CNTRLX = 0x18 ; CONTROL-X -CNTRLZ = 0x1A ; CONTROL-Z (END-OF-FILE MARK) -SPACE = 0x20 -POUND = 0x23 -DOLLAR = 0x24 -QUESTION = 0x3f -UP = 0x5E -DEL = 0x7F ; RUBOUT - -; CPM ORIGIN CALCULATE - -NK = 59 ;SYSTEM SIZE -BASE = (NK*1024)-0x5000 -CCPO = BASE+0x3400 ;CCP ORIGIN -BDOSO = BASE+0x3C00 ;BDOS ORIGIN -BIOSO = BASE+0x4A00 ;BIOS ORIGIN - -;dwg-begin; - -; .area _CODE - .area _BDOSB01 - -;dwg-end; - -;dwg; .ORG BDOSO - .DB 0,0,0,0,0,0 ;OLD SERIAL NUMBER -; -;************************************************************** -;* -;* B D O S E N T R Y -;* -;************************************************************** -; -FBASE: JP FBASE1 -; -; BDOS ERROR TABLE. -; -BADSCTR:.DW ERROR1 ; BAD SECTOR ON READ OR WRITE. -BADSLCT:.DW ERROR2 ; BAD DISK SELECT. -RODISK: .DW ERROR3 ; DISK IS READ ONLY. -ROFILE: .DW ERROR4 ; FILE IS READ ONLY. -; -; ENTRY INTO BDOS. (DE) OR (E) ARE THE PARAMETERS PASSED. THE -; FUNCTION NUMBER DESIRED IS IN REGISTER (C). -; E contains drive number if passing this -FBASE1: EX DE,HL ; SAVE THE (DE) PARAMETERS. - LD (PARAMS),HL - EX DE,HL - LD A,E ; AND SAVE REGISTER (E) IN PARTICULAR. - LD (EPARAM),A - LD HL,#0 - LD (STATUS),HL ; CLEAR RETURN STATUS. - ADD HL,SP - LD (USRSTACK),HL ; SAVE USERS STACK POINTER. - LD SP,#STKAREA ; AND SET OUR OWN. - XOR A ; CLEAR AUTO SELECT STORAGE SPACE. - LD (AUTOFLAG),A - LD (AUTO),A - LD HL,#GOBACK ; SET RETURN ADDRESS. - PUSH HL - LD A,C ; GET FUNCTION NUMBER. - CP #NFUNCTS ; VALID FUNCTION NUMBER? - RET NC - LD C,E ; KEEP SINGLE REGISTER FUNCTION HERE. - LD HL,#FUNCTNS ; NOW LOOK THRU THE FUNCTION TABLE. - LD E,A - LD D,#0 ; (DE)=FUNCTION NUMBER. - ADD HL,DE - ADD HL,DE ; (HL)=(START OF TABLE)+2*(FUNCTION NUMBER). - LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE)=ADDRESS FOR THIS FUNCTION. - LD HL,(PARAMS) ; RETRIEVE PARAMETERS. - EX DE,HL ; NOW (DE) HAS THE ORIGINAL PARAMETERS. - JP (HL) ; EXECUTE DESIRED FUNCTION. -; -; BDOS FUNCTION JUMP TABLE. -; -NFUNCTS = 41 ; NUMBER OF FUNCTIONS IN FOLLOWIN TABLE. -; -FUNCTNS:.DW WBOOT,GETCON,OUTCON,GETRDR,PUNCH,LIST,DIRCIO,GETIOB - .DW SETIOB,PRTSTR,R.DBUFF,GETCSTS,GETVER,RSTDSK,SETDSK,OPENFIL - .DW CLOSEFIL,GETFST,GETNXT,DELFILE,READSEQ,WRTSEQ,FCREATE - .DW RENFILE,GETLOG,GETCRNT,PUTDMA,GETALOC,WRTPRTD,GETROV,SETATTR - .DW GETPARM,GETUSER,RDRANDOM,WTRANDOM,FILESIZE,SETRAN,LOGOFF,RTN - .DW RTN,WTSPECL -; -; BDOS ERROR MESSAGE SECTION. -; -ERROR1: LD HL,#BADSEC ; BAD SECTOR MESSAGE. - CALL PRTERR ; PRINT IT AND GET A 1 CHAR RESPONCE. - CP #CNTRLC ; RE-BOOT R.EQUEST (CONTROL-C)? - JP Z,0 ; YES. - RET ; NO, RETURN TO RETRY I/O FUNCTION. -; -ERROR2: LD HL,#BADSEL ; BAD DRIVE SELECTED. - JP ERROR5 -; -ERROR3: LD HL,#DISKRO ; DISK IS READ ONLY. - JP ERROR5 -; -ERROR4: LD HL,#FILERO ; FILE IS READ ONLY. -; -ERROR5: CALL PRTERR - JP 0 ; ALWAYS REBOOT ON THESE ERRORS. -; -BDOSERR: .ascii "BDOS ERR ON " -BDOSDRV: .ascii " : $" -BADSEC: .ascii "BAD SECTOR$" -BADSEL: .ascii "SELECT$" -FILERO: .ascii "FILE " -DISKRO: .ascii "R/O$" -; -; PRINT BDOS ERROR MESSAGE. -; -PRTERR: PUSH HL ; SAVE SECOND MESSAGE POINTER. - CALL OUTCRLF ; SEND (CR)(LF). - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - ADD A,#ASCIIA ; MAKE ASCII. - LD (BDOSDRV),A ; AND PUT IN MESSAGE. - LD BC,#BDOSERR ; AND PRINT IT. - CALL PRTMESG - POP BC ; PRINT SECOND MESSAGE LINE NOW. - CALL PRTMESG -; -; GET AN INPUT CHARACTER. WE WILL CHECK OUR 1 CHARACTER -; BUFFER FIRST. THIS MAY BE SET BY THE CONSOLE STATUS ROUTINE. -; -GETCHAR:LD HL,#CHARBUF ; CHECK CHARACTER BUFFER. - LD A,(HL) ; ANYTHING PRESENT ALREADY? - LD (HL),#0 ; ...EITHER CASE CLEAR IT. - OR A - RET NZ ; YES, USE IT. - JP CONIN ; NOPE, GO GET A CHARACTER RESPONCE. -; -; INPUT AND ECHO A CHARACTER. -; -GETECHO:CALL GETCHAR ; INPUT A CHARACTER. - CALL CHKCHAR ; CARRIAGE CONTROL? - RET C ; NO, A REGULAR CONTROL CHAR SO DON'T ECHO. - PUSH AF ; OK, SAVE CHARACTER NOW. - LD C,A - CALL OUTCON ; AND ECHO IT. - POP AF ; GET CHARACTER AND RETURN. - RET -; -; CHECK CHARACTER IN (A). SET THE ZERO FLAG ON A CARRIAGE -; CONTROL CHARACTER AND THE CARRY FLAG ON ANY OTHER CONTROL -; CHARACTER. -; -CHKCHAR:CP #CR ; CHECK FOR CARRIAGE RETURN, LINE FEED, BACKSPACE, - RET Z ; OR A TAB. - CP #LF - RET Z - CP #TAB - RET Z - CP #BS - RET Z - CP #SPACE ; OTHER CONTROL CHAR? SET CARRY FLAG. - RET -; -; CHECK THE CONSOLE DURING OUTPUT. HALT ON A CONTROL-S, THEN -; REBOOT ON A CONTROL-C. IF ANYTHING ELSE IS READY, CLEAR THE -; ZERO FLAG AND RETURN (THE CALLING ROUTINE MAY WANT TO DO -; SOMETHING). -; -CKCONSOL: - LD A,(CHARBUF) ; CHECK BUFFER. - OR A ; IF ANYTHING, JUST RETURN WITHOUT CHECKING. - JP NZ,CKCON2 - CALL CONST ; NOTHING IN BUFFER. CHECK CONSOLE. - AND #0x01 ; LOOK AT BIT 0. - RET Z ; RETURN IF NOTHING. - CALL CONIN ; OK, GET IT. - CP #CNTRLS ; IF NOT CONTROL-S, RETURN WITH ZERO CLEARED. - JP NZ,CKCON1 - CALL CONIN ; HALT PROCESSING UNTIL ANOTHER CHAR - CP #CNTRLC ; IS TYPED. CONTROL-C? - JP Z,0 ; YES, REBOOT NOW. - XOR A ; NO, JUST PRETEND NOTHING WAS EVER READY. - RET -CKCON1: LD (CHARBUF),A ; SAVE CHARACTER IN BUFFER FOR LATER PROCESSING. -CKCON2: LD A,#1 ; SET (A) TO NON ZERO TO MEAN SOMETHING IS READY. - RET -; -; OUTPUT (C) TO THE SCREEN. IF THE PRINTER FLIP-FLOP FLAG -; IS SET, WE WILL SEND CHARACTER TO PRINTER ALSO. THE CONSOLE -; WILL BE CHECKED IN THE PROCESS. -; -OUTCHAR:LD A,(OUTFLAG) ; CHECK OUTPUT FLAG. - OR A ; ANYTHING AND WE WON'T GENERATE OUTPUT. - JP NZ,OUTCHR1 - PUSH BC - CALL CKCONSOL ; CHECK CONSOLE (WE DON'T CARE WHATS THERE). - POP BC - PUSH BC - CALL CONOUT ; OUTPUT (C) TO THE SCREEN. - POP BC - PUSH BC - LD A,(PRTFLAG) ; CHECK PRINTER FLIP-FLOP FLAG. - OR A - CALL NZ,LIST ; PRINT IT ALSO IF NON-ZERO. - POP BC -OUTCHR1:LD A,C ; UPDATE CURSORS POSITION. - LD HL,#CURPOS - CP #DEL ; RUBOUTS DON'T DO ANYTHING HERE. - RET Z - INC (HL) ; BUMP LINE POINTER. - CP #SPACE ; AND RETURN IF A NORMAL CHARACTER. - RET NC - DEC (HL) ; RESTORE AND CHECK FOR THE START OF THE LINE. - LD A,(HL) - OR A - RET Z ; INGNORE CONTROL CHARACTERS AT THE START OF THE LINE. - LD A,C - CP #BS ; IS IT A BACKSPACE? - JP NZ,OUTCHR2 - DEC (HL) ; YES, BACKUP POINTER. - RET -OUTCHR2:CP #LF ; IS IT A LINE FEED? - RET NZ ; IGNORE ANYTHING ELSE. - LD (HL),#0 ; RESET POINTER TO START OF LINE. - RET -; -; OUTPUT (A) TO THE SCREEN. IF IT IS A CONTROL CHARACTER -; (OTHER THAN CARRIAGE CONTROL), USE ^X FORMAT. -; -SHOWIT: LD A,C - CALL CHKCHAR ; CHECK CHARACTER. - JP NC,OUTCON ; NOT A CONTROL, USE NORMAL OUTPUT. - PUSH AF - LD C,#UP ; FOR A CONTROL CHARACTER, PRECEED IT WITH '^'. - CALL OUTCHAR - POP AF - OR #AT ; AND THEN USE THE LETTER .EQUIVELANT. - LD C,A -; -; FUNCTION TO OUTPUT (C) TO THE CONSOLE DEVICE AND EXPAND TABS -; IF NECESSARY. -; -OUTCON: LD A,C - CP #TAB ; IS IT A TAB? - JP NZ,OUTCHAR ; USE REGULAR OUTPUT. -OUTCON1:LD C,#SPACE ; YES IT IS, USE SPACES INSTEAD. - CALL OUTCHAR - LD A,(CURPOS) ; GO UNTIL THE CURSOR IS AT A MULTIPLE OF 8 - - AND #7 ; POSITION. - JP NZ,OUTCON1 - RET -; -; ECHO A BACKSPACE CHARACTER. ERASE THE PREVOIUS CHARACTER -; ON THE SCREEN. -; -BACKUP: CALL BACKUP1 ; BACKUP THE SCREEN 1 PLACE. - LD C,#SPACE ; THEN BLANK THAT CHARACTER. - CALL CONOUT -BACKUP1:LD C,#BS ; THEN BACK SPACE ONCE MORE. - JP CONOUT -; -; SIGNAL A DELETED LINE. PRINT A '#' AT THE END AND START -; OVER. -; -NEWLINE:LD C,#POUND - CALL OUTCHAR ; PRINT THIS. - CALL OUTCRLF ; START NEW LINE. -NEWLN1: LD A,(CURPOS) ; MOVE THE CURSOR TO THE STARTING POSITION. - LD HL,#STARTING - CP (HL) - RET NC ; THERE YET? - LD C,#SPACE - CALL OUTCHAR ; NOPE, KEEP GOING. - JP NEWLN1 -; -; OUTPUT A (CR) (LF) TO THE CONSOLE DEVICE (SCREEN). -; -OUTCRLF:LD C,#CR - CALL OUTCHAR - LD C,#LF - JP OUTCHAR -; -; PRINT MESSAGE POINTED TO BY (BC). IT WILL END WITH A '$'. -; -PRTMESG:LD A,(BC) ; CHECK FOR TERMINATING CHARACTER. - CP #DOLLAR - RET Z - INC BC - PUSH BC ; OTHERWISE, BUMP POINTER AND PRINT IT. - LD C,A - CALL OUTCON - POP BC - JP PRTMESG -; -; FUNCTION TO EXECUTE A BUFFERED READ. -; -R.DBUFF: LD A,(CURPOS) ; USE PRESENT LOCATION AS STARTING ONE. - LD (STARTING),A - LD HL,(PARAMS) ; GET THE MAXIMUM BUFFER SPACE. - LD C,(HL) - INC HL ; POINT TO FIRST AVAILABLE SPACE. - PUSH HL ; AND SAVE. - LD B,#0 ; KEEP A CHARACTER COUNT. -R.DBUF1: PUSH BC - PUSH HL -R.DBUF2: CALL GETCHAR ; GET THE NEXT INPUT CHARACTER. - AND #0x7F ; STRIP BIT 7. - POP HL ; RESET REGISTERS. - POP BC - CP #CR ; EN OF THE LINE? - JP Z,R.DBUF17 - CP #LF - JP Z,R.DBUF17 - CP #BS ; HOW ABOUT A BACKSPACE? - JP NZ,R.DBUF3 - LD A,B ; YES, BUT IGNORE AT THE BEGINNING OF THE LINE. - OR A - JP Z,R.DBUF1 - DEC B ; OK, UPDATE COUNTER. - LD A,(CURPOS) ; IF WE BACKSPACE TO THE START OF THE LINE, - LD (OUTFLAG),A ; TREAT AS A CANCEL (CONTROL-X). - JP R.DBUF10 -R.DBUF3: CP #DEL ; USER TYPED A RUBOUT? - JP NZ,R.DBUF4 - LD A,B ; IGNORE AT THE START OF THE LINE. - OR A - JP Z,R.DBUF1 - LD A,(HL) ; OK, ECHO THE PREVOIUS CHARACTER. - DEC B ; AND RESET POINTERS (COUNTERS). - DEC HL - JP R.DBUF15 -R.DBUF4: CP #CNTRLE ; PHYSICAL END OF LINE? - JP NZ,R.DBUF5 - PUSH BC ; YES, DO IT. - PUSH HL - CALL OUTCRLF - XOR A ; AND UPDATE STARTING POSITION. - LD (STARTING),A - JP R.DBUF2 -R.DBUF5: CP #CNTRLP ; CONTROL-P? - JP NZ,R.DBUF6 - PUSH HL ; YES, FLIP THE PRINT FLAG FILP-FLOP BYTE. - LD HL,#PRTFLAG - LD A,#1 ; PRTFLAG=1-PRTFLAG - SUB (HL) - LD (HL),A - POP HL - JP R.DBUF1 -R.DBUF6: CP #CNTRLX ; CONTROL-X (CANCEL)? - JP NZ,R.DBUF8 - POP HL -R.DBUF7: LD A,(STARTING) ; YES, BACKUP THE CURSOR TO HERE. - LD HL,#CURPOS - CP (HL) - JP NC,R.DBUFF ; DONE YET? - DEC (HL) ; NO, DECREMENT POINTER AND OUTPUT BACK UP ONE SPACE. - CALL BACKUP - JP R.DBUF7 -R.DBUF8: CP #CNTRLU ; CNTROL-U (CANCEL LINE)? - JP NZ,R.DBUF9 - CALL NEWLINE ; START A NEW LINE. - POP HL - JP R.DBUFF -R.DBUF9: CP #CNTRLR ; CONTROL-R? - JP NZ,R.DBUF14 -R.DBUF10:PUSH BC ; YES, START A NEW LINE AND RETYPE THE OLD ONE. - CALL NEWLINE - POP BC - POP HL - PUSH HL - PUSH BC -R.DBUF11:LD A,B ; DONE WHOLE LINE YET? - OR A - JP Z,R.DBUF12 - INC HL ; NOPE, GET NEXT CHARACTER. - LD C,(HL) - DEC B ; COUNT IT. - PUSH BC - PUSH HL - CALL SHOWIT ; AND DISPLAY IT. - POP HL - POP BC - JP R.DBUF11 -R.DBUF12:PUSH HL ; DONE WITH LINE. IF WE WERE DISPLAYING - LD A,(OUTFLAG) ; THEN UPDATE CURSOR POSITION. - OR A - JP Z,R.DBUF2 - LD HL,#CURPOS ; BECAUSE THIS LINE IS SHORTER, WE MUST - SUB (HL) ; BACK UP THE CURSOR (NOT THE SCREEN HOWEVER) - LD (OUTFLAG),A ; SOME NUMBER OF POSITIONS. -R.DBUF13:CALL BACKUP ; NOTE THAT AS LONG AS (OUTFLAG) IS NON - LD HL,#OUTFLAG ; ZERO, THE SCREEN WILL NOT BE CHANGED. - DEC (HL) - JP NZ,R.DBUF13 - JP R.DBUF2 ; NOW JUST GET THE NEXT CHARACTER. -; -; JUST A NORMAL CHARACTER, PUT THIS IN OUR BUFFER AND ECHO. -; -R.DBUF14:INC HL - LD (HL),A ; STORE CHARACTER. - INC B ; AND COUNT IT. -R.DBUF15:PUSH BC - PUSH HL - LD C,A ; ECHO IT NOW. - CALL SHOWIT - POP HL - POP BC - LD A,(HL) ; WAS IT AN ABORT R.EQUEST? - CP #CNTRLC ; CONTROL-C ABORT? - LD A,B - JP NZ,R.DBUF16 - CP #1 ; ONLY IF AT START OF LINE. - JP Z,0 -R.DBUF16:CP C ; NOPE, HAVE WE FILLED THE BUFFER? - JP C,R.DBUF1 -R.DBUF17:POP HL ; YES END THE LINE AND RETURN. - LD (HL),B - LD C,#CR - JP OUTCHAR ; OUTPUT (CR) AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE CONSOLE DEVICE. -; -GETCON: CALL GETECHO ; GET AND ECHO. - JP SETSTAT ; SAVE STATUS AND RETURN. -; -; FUNCTION TO GET A CHARACTER FROM THE TAPE READER DEVICE. -; -GETRDR: CALL READER ; GET A CHARACTER FROM READER, SET STATUS AND RETURN. - JP SETSTAT -; -; FUNCTION TO PERFORM DIRECT CONSOLE I/O. IF (C) CONTAINS (FF) -; THEN THIS IS AN INPUT R.EQUEST. IF (C) CONTAINS (FE) THEN -; THIS IS A STATUS R.EQUEST. OTHERWISE WE ARE TO OUTPUT (C). -; -DIRCIO: LD A,C ; TEST FOR (FF). - INC A - JP Z,DIRC1 - INC A ; TEST FOR (FE). - JP Z,CONST - JP CONOUT ; JUST OUTPUT (C). -DIRC1: CALL CONST ; THIS IS AN INPUT R.EQUEST. - OR A - JP Z,GOBACK1 ; NOT READY? JUST RETURN (DIRECTLY). - CALL CONIN ; YES, GET CHARACTER. - JP SETSTAT ; SET STATUS AND RETURN. -; -; FUNCTION TO RETURN THE I/O BYTE. -; -GETIOB: LD A,(IOBYTE) - JP SETSTAT -; -; FUNCTION TO SET THE I/O BYTE. -; -SETIOB: LD HL,#IOBYTE - LD (HL),C - RET -; -; FUNCTION TO PRINT THE CHARACTER STRING POINTED TO BY (DE) -; ON THE CONSOLE DEVICE. THE STRING ENDS WITH A '$'. -; -PRTSTR: EX DE,HL - LD C,L - LD B,H ; NOW (BC) POINTS TO IT. - JP PRTMESG -; -; FUNCTION TO INTERIGATE THE CONSOLE DEVICE. -; -GETCSTS:CALL CKCONSOL -; -; GET HERE TO SET THE STATUS AND RETURN TO THE CLEANUP -; SECTION. THEN BACK TO THE USER. -; -SETSTAT:LD (STATUS),A -RTN: RET -; -; SET THE STATUS TO 1 (READ OR WRITE ERROR CODE). -; -IOERR1: LD A,#1 - JP SETSTAT -; -OUTFLAG:.DB 0 ; OUTPUT FLAG (NON ZERO MEANS NO OUTPUT). -STARTING: - .DB 2 ; STARTING POSITION FOR CURSOR. -CURPOS: .DB 0 ; CURSOR POSITION (0=START OF LINE). -PRTFLAG:.DB 0 ; PRINTER FLAG (CONTROL-P TOGGLE). LIST IF NON ZERO. -CHARBUF:.DB 0 ; SINGLE INPUT CHARACTER BUFFER. -; -; STACK AREA FOR BDOS CALLS. -; -USRSTACK: - .DW 0 ; SAVE USERS STACK POINTER HERE. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -STKAREA: ; END OF STACK AREA. -; -USERNO: .DB 0 ; CURRENT USER NUMBER. -ACTIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -PARAMS: .DW 0 ; SAVE (DE) PARAMETERS HERE ON ENTRY. -STATUS: .DW 0 ; STATUS RETURNED FROM BDOS FUNCTION. -; -; SELECT ERROR OCCURED, JUMP TO ERROR ROUTINE. -; -SLCTERR:LD HL,#BADSLCT -; -; JUMP TO (HL) INDIRECTLY. -; -JUMPHL: LD E,(HL) - INC HL - LD D,(HL) ; NOW (DE) CONTAIN THE DESIRED ADDRESS. - EX DE,HL - JP (HL) -; -; BLOCK MOVE. (DE) TO (HL), (C) BYTES TOTAL. -; -DE2HL: INC C ; IS COUNT DOWN TO ZERO? -DE2HL1: DEC C - RET Z ; YES, WE ARE DONE. - LD A,(DE) ; NO, MOVE ONE MORE BYTE. - LD (HL),A - INC DE - INC HL - JP DE2HL1 ; AND REPEAT. -; -; SELECT THE DESIRED DRIVE. -; -SELECT: LD A,(ACTIVE) ; GET ACTIVE DISK. - LD C,A - CALL SELDSK ; SELECT IT. - LD A,H ; VALID DRIVE? - OR L ; VALID DRIVE? - RET Z ; RETURN IF NOT. -; -; HERE, THE BIOS RETURNED THE ADDRESS OF THE PARAMETER BLOCK -; IN (HL). WE WILL EXTRACT THE NECESSARY POINTERS AND SAVE THEM. -; - LD E,(HL) ; YES, GET ADDRESS OF TRANSLATION TABLE INTO (DE). - INC HL - LD D,(HL) - INC HL - LD (SCRATCH1),HL ; SAVE POINTERS TO SCRATCH AREAS. - INC HL - INC HL - LD (SCRATCH2),HL ; DITTO. - INC HL - INC HL - LD (SCRATCH3),HL ; DITTO. - INC HL - INC HL - EX DE,HL ; NOW SAVE THE TRANSLATION TABLE ADDRESS. - LD (XLATE),HL - LD HL,#DIRBUF ; PUT THE NEXT 8 BYTES HERE. - LD C,#8 ; THEY CONSIST OF THE DIRECTORY BUFFER - CALL DE2HL ; POINTER, PARAMETER BLOCK POINTER, - LD HL,(DISKPB) ; CHECK AND ALLOCATION VECTORS. - EX DE,HL - LD HL,#SECTORS ; MOVE PARAMETER BLOCK INTO OUR RAM. - LD C,#15 ; IT IS 15 BYTES LONG. - CALL DE2HL - LD HL,(DSKSIZE) ; CHECK DISK SIZE. - LD A,H ; MORE THAN 256 BLOCKS ON THIS? - LD HL,#BIGDISK - LD (HL),#0x0FF ; SET TO SAMLL. - OR A - JP Z,SELECT1 - LD (HL),#0 ; WRONG, SET TO LARGE. -SELECT1:LD A,#0x0FF ; CLEAR THE ZERO FLAG. - OR A - RET -; -; ROUTINE TO HOME THE DISK TRACK HEAD AND CLEAR POINTERS. -; -HOMEDRV:CALL HOME ; HOME THE HEAD. - XOR A - LD HL,(SCRATCH2) ; SET OUR TRACK POINTER ALSO. - LD (HL),A - INC HL - LD (HL),A - LD HL,(SCRATCH3) ; AND OUR SECTOR POINTER. - LD (HL),A - INC HL - LD (HL),A - RET -; -; DO THE ACTUAL DISK READ AND CHECK THE ERROR RETURN STATUS. -; -DOREAD: CALL READ - JP IORET -; -; DO THE ACTUAL DISK WRITE AND HANDLE ANY BIOS ERROR. -; -DOWRITE:CALL WRITE -IORET: OR A - RET Z ; RETURN UNLESS AN ERROR OCCURED. - LD HL,#BADSCTR ; BAD READ/WRITE ON THIS SECTOR. - JP JUMPHL -; -; ROUTINE TO SELECT THE TRACK AND SECTOR THAT THE DESIRED -; BLOCK NUMBER FALLS IN. -; -TRKSEC: LD HL,(FILEPOS) ; GET POSITION OF LAST ACCESSED FILE - LD C,#2 ; IN DIRECTORY AND COMPUTE SECTOR #. - CALL SHIFTR ; SECTOR #=FILE-POSITION/4. - LD (BLKNMBR),HL ; SAVE THIS AS THE BLOCK NUMBER OF INTEREST. - LD (CKSUMTBL),HL ; WHAT'S IT DOING HERE TOO? -; -; IF THE SECTOR NUMBER HAS ALREADY BEEN SET (BLKNMBR), ENTER -; AT THIS POINT. -; -TRKSEC1:LD HL,#BLKNMBR - LD C,(HL) ; MOVE SECTOR NUMBER INTO (BC). - INC HL - LD B,(HL) - LD HL,(SCRATCH3) ; GET CURRENT SECTOR NUMBER AND - LD E,(HL) ; MOVE THIS INTO (DE). - INC HL - LD D,(HL) - LD HL,(SCRATCH2) ; GET CURRENT TRACK NUMBER. - LD A,(HL) ; AND THIS INTO (HL). - INC HL - LD H,(HL) - LD L,A -TRKSEC2:LD A,C ; IS DESIRED SECTOR BEFORE CURRENT ONE? - SUB E - LD A,B - SBC A,D - JP NC,TRKSEC3 - PUSH HL ; YES, DECREMENT SECTORS BY ONE TRACK. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - LD A,E - SUB L - LD E,A - LD A,D - SBC A,H - LD D,A ; NOW WE HAVE BACKED UP ONE FULL TRACK. - POP HL - DEC HL ; ADJUST TRACK COUNTER. - JP TRKSEC2 -TRKSEC3:PUSH HL ; DESIRED SECTOR IS AFTER CURRENT ONE. - LD HL,(SECTORS) ; GET SECTORS PER TRACK. - ADD HL,DE ; BUMP SECTOR POINTER TO NEXT TRACK. - JP C,TRKSEC4 - LD A,C ; IS DESIRED SECTOR NOW BEFORE CURRENT ONE? - SUB L - LD A,B - SBC A,H - JP C,TRKSEC4 - EX DE,HL ; NOT YES, INCREMENT TRACK COUNTER - POP HL ; AND CONTINUE UNTIL IT IS. - INC HL - JP TRKSEC3 -; -; HERE WE HAVE DETERMINED THE TRACK NUMBER THAT CONTAINS THE -; DESIRED SECTOR. -; -TRKSEC4:POP HL ; GET TRACK NUMBER (HL). - PUSH BC - PUSH DE - PUSH HL - EX DE,HL - LD HL,(OFFSET) ; ADJUST FOR FIRST TRACK OFFSET. - ADD HL,DE - LD B,H - LD C,L - CALL SETTRK ; SELECT THIS TRACK. - POP DE ; RESET CURRENT TRACK POINTER. - LD HL,(SCRATCH2) - LD (HL),E - INC HL - LD (HL),D - POP DE - LD HL,(SCRATCH3) ; RESET THE FIRST SECTOR ON THIS TRACK. - LD (HL),E - INC HL - LD (HL),D - POP BC - LD A,C ; NOW SUBTRACT THE DESIRED ONE. - SUB E ; TO MAKE IT RELATIVE (1-# SECTORS/TRACK). - LD C,A - LD A,B - SBC A,D - LD B,A - LD HL,(XLATE) ; TRANSLATE THIS SECTOR ACCORDING TO THIS TABLE. - EX DE,HL - CALL SECTRN ; LET THE BIOS TRANSLATE IT. - LD C,L - LD B,H - JP SETSEC ; AND SELECT IT. -; -; COMPUTE BLOCK NUMBER FROM RECORD NUMBER (SAVNREC) AND -; EXTENT NUMBER (SAVEXT). -; -GETBLOCK: - LD HL,#BLKSHFT ; GET LOGICAL TO PHYSICAL CONVERSION. - LD C,(HL) ; NOTE THAT THIS IS BASE 2 LOG OF RATIO. - LD A,(SAVNREC) ; GET RECORD NUMBER. -GETBLK1:OR A ; COMPUTE (A)=(A)/2^BLKSHFT. - RRA - DEC C - JP NZ,GETBLK1 - LD B,A ; SAVE RESULT IN (B). - LD A,#8 - SUB (HL) - LD C,A ; COMPUTE (C)=8-BLKSHFT. - LD A,(SAVEXT) -GETBLK2:DEC C ; COMPUTE (A)=SAVEXT*2^(8-BLKSHFT). - JP Z,GETBLK3 - OR A - RLA - JP GETBLK2 -GETBLK3:ADD A,B - RET -; -; ROUTINE TO EXTRACT THE (BC) BLOCK BYTE FROM THE FCB POINTED -; TO BY (PARAMS). IF THIS IS A BIG-DISK, THEN THESE ARE 16 BIT -; BLOCK NUMBERS, ELSE THEY ARE 8 BIT NUMBERS. -; NUMBER IS RETURNED IN (HL). -; -EXTBLK: LD HL,(PARAMS) ; GET FCB ADDRESS. - LD DE,#16 ; BLOCK NUMBERS START 16 BYTES INTO FCB. - ADD HL,DE - ADD HL,BC - LD A,(BIGDISK) ; ARE WE USING A BIG-DISK? - OR A - JP Z,EXTBLK1 - LD L,(HL) ; NO, EXTRACT AN 8 BIT NUMBER FROM THE FCB. - LD H,#0 - RET -EXTBLK1:ADD HL,BC ; YES, EXTRACT A 16 BIT NUMBER. - LD E,(HL) - INC HL - LD D,(HL) - EX DE,HL ; RETURN IN (HL). - RET -; -; COMPUTE BLOCK NUMBER. -; -COMBLK: CALL GETBLOCK - LD C,A - LD B,#0 - CALL EXTBLK - LD (BLKNMBR),HL - RET -; -; CHECK FOR A ZERO BLOCK NUMBER (UNUSED). -; -CHKBLK: LD HL,(BLKNMBR) - LD A,L ; IS IT ZERO? - OR H - RET -; -; ADJUST PHYSICAL BLOCK (BLKNMBR) AND CONVERT TO LOGICAL -; SECTOR (LOGSECT). THIS IS THE STARTING SECTOR OF THIS BLOCK. -; THE ACTUAL SECTOR OF INTEREST IS THEN ADDED TO THIS AND THE -; RESULTING SECTOR NUMBER IS STORED BACK IN (BLKNMBR). THIS -; WILL STILL HAVE TO BE ADJUSTED FOR THE TRACK NUMBER. -; -LOGICAL:LD A,(BLKSHFT) ; GET LOG2(PHYSICAL/LOGICAL SECTORS). - LD HL,(BLKNMBR) ; GET PHYSICAL SECTOR DESIRED. -LOGICL1:ADD HL,HL ; COMPUTE LOGICAL SECTOR NUMBER. - DEC A ; NOTE LOGICAL SECTORS ARE 128 BYTES LONG. - JP NZ,LOGICL1 - LD (LOGSECT),HL ; SAVE LOGICAL SECTOR. - LD A,(BLKMASK) ; GET BLOCK MASK. - LD C,A - LD A,(SAVNREC) ; GET NEXT SECTOR TO ACCESS. - AND C ; EXTRACT THE RELATIVE POSITION WITHIN PHYSICAL BLOCK. - OR L ; AND ADD IT TOO LOGICAL SECTOR. - LD L,A - LD (BLKNMBR),HL ; AND STORE. - RET -; -; SET (HL) TO POINT TO EXTENT BYTE IN FCB. -; -SETEXT: LD HL,(PARAMS) - LD DE,#12 ; IT IS THE TWELTH BYTE. - ADD HL,DE - RET -; -; SET (HL) TO POINT TO RECORD COUNT BYTE IN FCB AND (DE) TO -; NEXT RECORD NUMBER BYTE. -; -SETHLDE:LD HL,(PARAMS) - LD DE,#15 ; RECORD COUNT BYTE (#15). - ADD HL,DE - EX DE,HL - LD HL,#17 ; NEXT RECORD NUMBER (#32). - ADD HL,DE - RET -; -; SAVE CURRENT FILE DATA FROM FCB. -; -STRDATA:CALL SETHLDE - LD A,(HL) ; GET AND STORE RECORD COUNT BYTE. - LD (SAVNREC),A - EX DE,HL - LD A,(HL) ; GET AND STORE NEXT RECORD NUMBER BYTE. - LD (SAVNXT),A - CALL SETEXT ; POINT TO EXTENT BYTE. - LD A,(EXTMASK) ; GET EXTENT MASK. - AND (HL) - LD (SAVEXT),A ; AND SAVE EXTENT HERE. - RET -; -; SET THE NEXT RECORD TO ACCESS. IF (MODE) IS SET TO 2, THEN -; THE LAST RECORD BYTE (SAVNREC) HAS THE CORRECT NUMBER TO ACCESS. -; FOR S.EQUENTIAL ACCESS, (MODE) WILL BE .EQUAL TO 1. -; -SETNREC:CALL SETHLDE - LD A,(MODE) ; GET S.EQUENTIAL FLAG (=1). - CP #2 ; A 2 INDICATES THAT NO ADDER IS NEEDED. - JP NZ,STNREC1 - XOR A ; CLEAR ADDER (RANDOM ACCESS?). -STNREC1:LD C,A - LD A,(SAVNREC) ; GET LAST RECORD NUMBER. - ADD A,C ; INCREMENT RECORD COUNT. - LD (HL),A ; AND SET FCB'S NEXT RECORD BYTE. - EX DE,HL - LD A,(SAVNXT) ; GET NEXT RECORD BYTE FROM STORAGE. - LD (HL),A ; AND PUT THIS INTO FCB AS NUMBER OF RECORDS USED. - RET -; -; SHIFT (HL) RIGHT (C) BITS. -; -SHIFTR: INC C -SHIFTR1:DEC C - RET Z - LD A,H - OR A - RRA - LD H,A - LD A,L - RRA - LD L,A - JP SHIFTR1 -; -; COMPUTE THE CHECK-SUM FOR THE DIRECTORY BUFFER. RETURN -; INTEGER SUM IN (A). -; -CHECKSUM: - LD C,#128 ; LENGTH OF BUFFER. - LD HL,(DIRBUF) ; GET ITS LOCATION. - XOR A ; CLEAR SUMMATION BYTE. -CHKSUM1:ADD A,(HL) ; AND COMPUTE SUM IGNORING CARRIES. - INC HL - DEC C - JP NZ,CHKSUM1 - RET -; -; SHIFT (HL) LEFT (C) BITS. -; -SHIFTL: INC C -SHIFTL1:DEC C - RET Z - ADD HL,HL ; SHIFT LEFT 1 BIT. - JP SHIFTL1 -; -; ROUTINE TO SET A BIT IN A 16 BIT VALUE CONTAINED IN (BC). -; THE BIT SET DEPENDS ON THE CURRENT DRIVE SELECTION. -; -SETBIT: PUSH BC ; SAVE 16 BIT WORD. - LD A,(ACTIVE) ; GET ACTIVE DRIVE. - LD C,A - LD HL,#1 - CALL SHIFTL ; SHIFT BIT 0 INTO PLACE. - POP BC ; NOW 'OR' THIS WITH THE ORIGINAL WORD. - LD A,C - OR L - LD L,A ; LOW BYTE DONE, DO HIGH BYTE. - LD A,B - OR H - LD H,A - RET -; -; EXTRACT THE WRITE PROTECT STATUS BIT FOR THE CURRENT DRIVE. -; THE RESULT IS RETURNED IN (A), BIT 0. -; -GETWPRT:LD HL,(WRTPRT) ; GET STATUS BYTES. - LD A,(ACTIVE) ; WHICH DRIVE IS CURRENT? - LD C,A - CALL SHIFTR ; SHIFT STATUS SUCH THAT BIT 0 IS THE - LD A,L ; ONE OF INTEREST FOR THIS DRIVE. - AND #1 ; AND ISOLATE IT. - RET -; -; FUNCTION TO WRITE PROTECT THE CURRENT DISK. -; -WRTPRTD:LD HL,#WRTPRT ; POINT TO STATUS WORD. - LD C,(HL) ; SET (BC) .EQUAL TO THE STATUS. - INC HL - LD B,(HL) - CALL SETBIT ; AND SET THIS BIT ACCORDING TO CURRENT DRIVE. - LD (WRTPRT),HL ; THEN SAVE. - LD HL,(DIRSIZE) ; NOW SAVE DIRECTORY SIZE LIMIT. - INC HL ; REMEMBER THE LAST ONE. - EX DE,HL - LD HL,(SCRATCH1) ; AND STORE IT HERE. - LD (HL),E ; PUT LOW BYTE. - INC HL - LD (HL),D ; THEN HIGH BYTE. - RET -; -; CHECK FOR A READ ONLY FILE. -; -CHKROFL:CALL FCB2HL ; SET (HL) TO FILE ENTRY IN DIRECTORY BUFFER. -CKROF1: LD DE,#9 ; LOOK AT BIT 7 OF THE NINTH BYTE. - ADD HL,DE - LD A,(HL) - RLA - RET NC ; RETURN IF OK. - LD HL,#ROFILE ; ELSE, PRINT ERROR MESSAGE AND TERMINATE. - JP JUMPHL -; -; CHECK THE WRITE PROTECT STATUS OF THE ACTIVE DISK. -; -CHKWPRT:CALL GETWPRT - RET Z ; RETURN IF OK. - LD HL,#RODISK ; ELSE PRINT MESSAGE AND TERMINATE. - JP JUMPHL -; -; ROUTINE TO SET (HL) POINTING TO THE PROPER ENTRY IN THE -; DIRECTORY BUFFER. -; -FCB2HL: LD HL,(DIRBUF) ; GET ADDRESS OF BUFFER. - LD A,(FCBPOS) ; RELATIVE POSITION OF FILE. -; -; ROUTINE TO ADD (A) TO (HL). -; -ADDA2HL:ADD A,L - LD L,A - RET NC - INC H ; TAKE CARE OF ANY CARRY. - RET -; -; ROUTINE TO GET THE 'S2' BYTE FROM THE FCB SUPPLIED IN -; THE INITIAL PARAMETER SPECIFICATION. -; -GETS2: LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD DE,#14 ; RELATIVE POSITION OF 'S2'. - ADD HL,DE - LD A,(HL) ; EXTRACT THIS BYTE. - RET -; -; CLEAR THE 'S2' BYTE IN THE FCB. -; -CLEARS2:CALL GETS2 ; THIS SETS (HL) POINTING TO IT. - LD (HL),#0 ; NOW CLEAR IT. - RET -; -; SET BIT 7 IN THE 'S2' BYTE OF THE FCB. -; -SETS2B7:CALL GETS2 ; GET THE BYTE. - OR #0x80 ; AND SET BIT 7. - LD (HL),A ; THEN STORE. - RET -; -; COMPARE (FILEPOS) WITH (SCRATCH1) AND SET FLAGS BASED ON -; THE DIFFERENCE. THIS CHECKS TO SEE IF THERE ARE MORE FILE -; NAMES IN THE DIRECTORY. WE ARE AT (FILEPOS) AND THERE ARE -; (SCRATCH1) OF THEM TO CHECK. -; -MOREFLS:LD HL,(FILEPOS) ; WE ARE HERE. - EX DE,HL - LD HL,(SCRATCH1) ; AND DON'T GO PAST HERE. - LD A,E ; COMPUTE DIFFERENCE BUT DON'T KEEP. - SUB (HL) - INC HL - LD A,D - SBC A,(HL) ; SET CARRY IF NO MORE NAMES. - RET -; -; CALL THIS ROUTINE TO PREVENT (SCRATCH1) FROM BEING GREATER -; THAN (FILEPOS). -; -CHKNMBR:CALL MOREFLS ; SCRATCH1 TOO BIG? - RET C - INC DE ; YES, RESET IT TO (FILEPOS). - LD (HL),D - DEC HL - LD (HL),E - RET -; -; COMPUTE (HL)=(DE)-(HL) -; -SUBHL: LD A,E ; COMPUTE DIFFERENCE. - SUB L - LD L,A ; STORE LOW BYTE. - LD A,D - SBC A,H - LD H,A ; AND THEN HIGH BYTE. - RET -; -; SET THE DIRECTORY CHECKSUM BYTE. -; -SETDIR: LD C,#0xFF -; -; ROUTINE TO SET OR COMPARE THE DIRECTORY CHECKSUM BYTE. IF -; (C)=0FFH, THEN THIS WILL SET THE CHECKSUM BYTE. ELSE THE BYTE -; WILL BE CHECKED. IF THE CHECK FAILS (THE DISK HAS BEEN CHANGED), -; THEN THIS DISK WILL BE WRITE PROTECTED. -; -CHECKDIR: - LD HL,(CKSUMTBL) - EX DE,HL - LD HL,(ALLOC1) - CALL SUBHL - RET NC ; OK IF (CKSUMTBL) > (ALLOC1), SO RETURN. - PUSH BC - CALL CHECKSUM ; ELSE COMPUTE CHECKSUM. - LD HL,(CHKVECT) ; GET ADDRESS OF CHECKSUM TABLE. - EX DE,HL - LD HL,(CKSUMTBL) - ADD HL,DE ; SET (HL) TO POINT TO BYTE FOR THIS DRIVE. - POP BC - INC C ; SET OR CHECK ? - JP Z,CHKDIR1 - CP (HL) ; CHECK THEM. - RET Z ; RETURN IF THEY ARE THE SAME. - CALL MOREFLS ; NOT THE SAME, DO WE CARE? - RET NC - CALL WRTPRTD ; YES, MARK THIS AS WRITE PROTECTED. - RET -CHKDIR1:LD (HL),A ; JUST SET THE BYTE. - RET -; -; DO A WRITE TO THE DIRECTORY OF THE CURRENT DISK. -; -DIRWRITE: - CALL SETDIR ; SET CHECKSUM BYTE. - CALL DIRDMA ; SET DIRECTORY DMA ADDRESS. - LD C,#1 ; TELL THE BIOS TO ACTUALLY WRITE. - CALL DOWRITE ; THEN DO THE WRITE. - JP DEFDMA -; -; READ FROM THE DIRECTORY. -; -DIRREAD:CALL DIRDMA ; SET THE DIRECTORY DMA ADDRESS. - CALL DOREAD ; AND READ IT. -; -; ROUTINE TO SET THE DMA ADDRESS TO THE USERS CHOICE. -; -DEFDMA: LD HL,#USERDMA ; RESET THE DEFAULT DMA ADDRESS AND RETURN. - JP DIRDMA1 -; -; ROUTINE TO SET THE DMA ADDRESS FOR DIRECTORY WORK. -; -DIRDMA: LD HL,#DIRBUF -; -; SET THE DMA ADDRESS. ON ENTRY, (HL) POINTS TO -; WORD CONTAINING THE DESIRED DMA ADDRESS. -; -DIRDMA1:LD C,(HL) - INC HL - LD B,(HL) ; SETUP (BC) AND GO TO THE BIOS TO SET IT. - JP SETDMA -; -; MOVE THE DIRECTORY BUFFER INTO USER'S DMA SPACE. -; -MOVEDIR:LD HL,(DIRBUF) ; BUFFER IS LOCATED HERE, AND - EX DE,HL - LD HL,(USERDMA) ; PUT IT HERE. - LD C,#128 ; THIS IS ITS LENGTH. - JP DE2HL ; MOVE IT NOW AND RETURN. -; -; CHECK (FILEPOS) AND SET THE ZERO FLAG IF IT .EQUALS 0FFFFH. -; -CKFILPOS: - LD HL,#FILEPOS - LD A,(HL) - INC HL - CP (HL) ; ARE BOTH BYTES THE SAME? - RET NZ - INC A ; YES, BUT ARE THEY EACH 0FFH? - RET -; -; SET LOCATION (FILEPOS) TO 0FFFFH. -; -STFILPOS: - LD HL,#0x0FFFF - LD (FILEPOS),HL - RET -; -; MOVE ON TO THE NEXT FILE POSITION WITHIN THE CURRENT -; DIRECTORY BUFFER. IF NO MORE EXIST, SET POINTER TO 0FFFFH -; AND THE CALLING ROUTINE WILL CHECK FOR THIS. ENTER WITH (C) -; .EQUAL TO 0FFH TO CAUSE THE CHECKSUM BYTE TO BE SET, ELSE WE -; WILL CHECK THIS DISK AND SET WRITE PROTECT IF CHECKSUMS ARE -; NOT THE SAME (APPLIES ONLY IF ANOTHER DIRECTORY SECTOR MUST -; BE READ). -; -NXENTRY:LD HL,(DIRSIZE) ; GET DIRECTORY ENTRY SIZE LIMIT. - EX DE,HL - LD HL,(FILEPOS) ; GET CURRENT COUNT. - INC HL ; GO ON TO THE NEXT ONE. - LD (FILEPOS),HL - CALL SUBHL ; (HL)=(DIRSIZE)-(FILEPOS) - JP NC,NXENT1 ; IS THERE MORE ROOM LEFT? - JP STFILPOS ; NO. SET THIS FLAG AND RETURN. -NXENT1: LD A,(FILEPOS) ; GET FILE POSITION WITHIN DIRECTORY. - AND #3 ; ONLY LOOK WITHIN THIS SECTOR (ONLY 4 ENTRIES FIT). - LD B,#5 ; CONVERT TO RELATIVE POSITION (32 BYTES EACH). -NXENT2: ADD A,A ; NOTE THAT THIS IS NOT EFFICIENT CODE. - DEC B ; 5 'ADD A'S WOULD BE BETTER. - JP NZ,NXENT2 - LD (FCBPOS),A ; SAVE IT AS POSITION OF FCB. - OR A - RET NZ ; RETURN IF WE ARE WITHIN BUFFER. - PUSH BC - CALL TRKSEC ; WE NEED THE NEXT DIRECTORY SECTOR. - CALL DIRREAD - POP BC - JP CHECKDIR -; -; ROUTINE TO TO GET A BIT FROM THE DISK SPACE ALLOCATION -; MAP. IT IS RETURNED IN (A), BIT POSITION 0. ON ENTRY TO HERE, -; SET (BC) TO THE BLOCK NUMBER ON THE DISK TO CHECK. -; ON RETURN, (D) WILL CONTAIN THE ORIGINAL BIT POSITION FOR -; THIS BLOCK NUMBER AND (HL) WILL POINT TO THE ADDRESS FOR IT. -; -CKBITMAP: - LD A,C ; DETERMINE BIT NUMBER OF INTEREST. - AND #7 ; COMPUTE (D)=(E)=(C AND 7)+1. - INC A - LD E,A ; SAVE PARTICULAR BIT NUMBER. - LD D,A -; -; COMPUTE (BC)=(BC)/8. -; - LD A,C - RRCA ; NOW SHIFT RIGHT 3 BITS. - RRCA - RRCA - AND #0x1F ; AND CLEAR BITS 7,6,5. - LD C,A - LD A,B - ADD A,A ; NOW SHIFT (B) INTO BITS 7,6,5. - ADD A,A - ADD A,A - ADD A,A - ADD A,A - OR C ; AND ADD IN (C). - LD C,A ; OK, (C) HA BEEN COMPLETED. - LD A,B ; IS THERE A BETTER WAY OF DOING THIS? - RRCA - RRCA - RRCA - AND #0x1F - LD B,A ; AND NOW (B) IS COMPLETED. -; -; USE THIS AS AN OFFSET INTO THE DISK SPACE ALLOCATION -; TABLE. -; - LD HL,(ALOCVECT) - ADD HL,BC - LD A,(HL) ; NOW GET CORRECT BYTE. -CKBMAP1:RLCA ; GET CORRECT BIT INTO POSITION 0. - DEC E - JP NZ,CKBMAP1 - RET -; -; SET OR CLEAR THE BIT MAP SUCH THAT BLOCK NUMBER (BC) WILL BE MARKED -; AS USED. ON ENTRY, IF (E)=0 THEN THIS BIT WILL BE CLEARED, IF IT .EQUALS -; 1 THEN IT WILL BE SET (DON'T USE ANYOTHER VALUES). -; -STBITMAP: - PUSH DE - CALL CKBITMAP ; GET THE BYTE OF INTEREST. - AND #0x0FE ; CLEAR THE AFFECTED BIT. - POP BC - OR C ; AND NOW SET IT ACORDING TO (C). -; -; ENTRY TO RESTORE THE ORIGINAL BIT POSITION AND THEN STORE -; IN TABLE. (A) CONTAINS THE VALUE, (D) CONTAINS THE BIT -; POSITION (1-8), AND (HL) POINTS TO THE ADDRESS WITHIN THE -; SPACE ALLOCATION TABLE FOR THIS BYTE. -; -STBMAP1:RRCA ; RESTORE ORIGINAL BIT POSITION. - DEC D - JP NZ,STBMAP1 - LD (HL),A ; AND STOR BYTE IN TABLE. - RET -; -; SET/CLEAR SPACE USED BITS IN ALLOCATION MAP FOR THIS FILE. -; ON ENTRY, (C)=1 TO SET THE MAP AND (C)=0 TO CLEAR IT. -; -SETFILE:CALL FCB2HL ; GET ADDRESS OF FCB - LD DE,#16 - ADD HL,DE ; GET TO BLOCK NUMBER BYTES. - PUSH BC - LD C,#17 ; CHECK ALL 17 BYTES (MAX) OF TABLE. -SETFL1: POP DE - DEC C ; DONE ALL BYTES YET? - RET Z - PUSH DE - LD A,(BIGDISK) ; CHECK DISK SIZE FOR 16 BIT BLOCK NUMBERS. - OR A - JP Z,SETFL2 - PUSH BC ; ONLY 8 BIT NUMBERS. SET (BC) TO THIS ONE. - PUSH HL - LD C,(HL) ; GET LOW BYTE FROM TABLE, ALWAYS - LD B,#0 ; SET HIGH BYTE TO ZERO. - JP SETFL3 -SETFL2: DEC C ; FOR 16 BIT BLOCK NUMBERS, ADJUST COUNTER. - PUSH BC - LD C,(HL) ; NOW GET BOTH THE LOW AND HIGH BYTES. - INC HL - LD B,(HL) - PUSH HL -SETFL3: LD A,C ; BLOCK USED? - OR B - JP Z,SETFL4 - LD HL,(DSKSIZE) ; IS THIS BLOCK NUMBER WITHIN THE - LD A,L ; SPACE ON THE DISK? - SUB C - LD A,H - SBC A,B - CALL NC,STBITMAP ; YES, SET THE PROPER BIT. -SETFL4: POP HL ; POINT TO NEXT BLOCK NUMBER IN FCB. - INC HL - POP BC - JP SETFL1 -; -; CONSTRUCT THE SPACE USED ALLOCATION BIT MAP FOR THE ACTIVE -; DRIVE. IF A FILE NAME STARTS WITH '$' AND IT IS UNDER THE -; CURRENT USER NUMBER, THEN (STATUS) IS SET TO MINUS 1. OTHERWISE -; IT IS NOT SET AT ALL. -; -BITMAP: LD HL,(DSKSIZE) ; COMPUTE SIZE OF ALLOCATION TABLE. - LD C,#3 - CALL SHIFTR ; (HL)=(HL)/8. - INC HL ; AT LEASE 1 BYTE. - LD B,H - LD C,L ; SET (BC) TO THE ALLOCATION TABLE LENGTH. -; -; INITIALIZE THE BITMAP FOR THIS DRIVE. RIGHT NOW, THE FIRST -; TWO BYTES ARE SPECIFIED BY THE DISK PARAMETER BLOCK. HOWEVER -; A PATCH COULD BE ENTERED HERE IF IT WERE NECESSARY TO SETUP -; THIS TABLE IN A SPECIAL MANNOR. FOR EXAMPLE, THE BIOS COULD -; DETERMINE LOCATIONS OF 'BAD BLOCKS' AND SET THEM AS ALREADY -; 'USED' IN THE MAP. -; - LD HL,(ALOCVECT) ; NOW ZERO OUT THE TABLE NOW. -BITMAP1:LD (HL),#0 - INC HL - DEC BC - LD A,B - OR C - JP NZ,BITMAP1 - LD HL,(ALLOC0) ; GET INITIAL SPACE USED BY DIRECTORY. - EX DE,HL - LD HL,(ALOCVECT) ; AND PUT THIS INTO MAP. - LD (HL),E - INC HL - LD (HL),D -; -; END OF INITIALIZATION PORTION. -; - CALL HOMEDRV ; NOW HOME THE DRIVE. - LD HL,(SCRATCH1) - LD (HL),#3 ; FORCE NEXT DIRECTORY R.EQUEST TO READ - INC HL ; IN A SECTOR. - LD (HL),#0 - CALL STFILPOS ; CLEAR INITIAL FILE POSITION ALSO. -BITMAP2:LD C,#0x0FF ; READ NEXT FILE NAME IN DIRECTORY - CALL NXENTRY ; AND SET CHECKSUM BYTE. - CALL CKFILPOS ; IS THERE ANOTHER FILE? - RET Z - CALL FCB2HL ; YES, GET ITS ADDRESS. - LD A,#0x0E5 - CP (HL) ; EMPTY FILE ENTRY? - JP Z,BITMAP2 - LD A,(USERNO) ; NO, CORRECT USER NUMBER? - CP (HL) - JP NZ,BITMAP3 - INC HL - LD A,(HL) ; YES, DOES NAME START WITH A '$'? - SUB #DOLLAR - JP NZ,BITMAP3 - DEC A ; YES, SET ATATUS TO MINUS ONE. - LD (STATUS),A -BITMAP3:LD C,#1 ; NOW SET THIS FILE'S SPACE AS USED IN BIT MAP. - CALL SETFILE - CALL CHKNMBR ; KEEP (SCRATCH1) IN BOUNDS. - JP BITMAP2 -; -; SET THE STATUS (STATUS) AND RETURN. -; -STSTATUS: - LD A,(FNDSTAT) - JP SETSTAT -; -; CHECK EXTENTS IN (A) AND (C). SET THE ZERO FLAG IF THEY -; ARE THE SAME. THE NUMBER OF 16K CHUNKS OF DISK SPACE THAT -; THE DIRECTORY EXTENT COVERS IS EXPRESSAD IS (EXTMASK+1). -; NO REGISTERS ARE MODIFIED. -; -SAMEXT: PUSH BC - PUSH AF - LD A,(EXTMASK) ; GET EXTENT MASK AND USE IT TO - CPL ; TO COMPARE BOTH EXTENT NUMBERS. - LD B,A ; SAVE RESULTING MASK HERE. - LD A,C ; MASK FIRST EXTENT AND SAVE IN (C). - AND B - LD C,A - POP AF ; NOW MASK SECOND EXTENT AND COMPARE - AND B ; WITH THE FIRST ONE. - SUB C - AND #0x1F ; (* ONLY CHECK BUTS 0-4 *) - POP BC ; THE ZERO FLAG IS SET IF THEY ARE THE SAME. - RET ; RESTORE (BC) AND RETURN. -; -; SEARCH FOR THE FIRST OCCURENCE OF A FILE NAME. ON ENTRY, -; REGISTER (C) SHOULD CONTAIN THE NUMBER OF BYTES OF THE FCB -; THAT MUST MATCH. -; -FINDFST:LD A,#0x0FF - LD (FNDSTAT),A - LD HL,#COUNTER ; SAVE CHARACTER COUNT. - LD (HL),C - LD HL,(PARAMS) ; GET FILENAME TO MATCH. - LD (SAVEFCB),HL ; AND SAVE. - CALL STFILPOS ; CLEAR INITIAL FILE POSITION (SET TO 0FFFFH). - CALL HOMEDRV ; HOME THE DRIVE. -; -; ENTRY TO LOCATE THE NEXT OCCURENCE OF A FILENAME WITHIN THE -; DIRECTORY. THE DISK IS NOT EXPECTED TO HAVE BEEN CHANGED. IF -; IT WAS, THEN IT WILL BE WRITE PROTECTED. -; -FINDNXT:LD C,#0 ; WRITE PROTECT THE DISK IF CHANGED. - CALL NXENTRY ; GET NEXT FILENAME ENTRY IN DIRECTORY. - CALL CKFILPOS ; IS FILE POSITION = 0FFFFH? - JP Z,FNDNXT6 ; YES, EXIT NOW THEN. - LD HL,(SAVEFCB) ; SET (DE) POINTING TO FILENAME TO MATCH. - EX DE,HL - LD A,(DE) - CP #0x0E5 ; EMPTY DIRECTORY ENTRY? - JP Z,FNDNXT1 ; (* ARE WE TRYING TO RESERECT ERASED ENTRIES? *) - PUSH DE - CALL MOREFLS ; MORE FILES IN DIRECTORY? - POP DE - JP NC,FNDNXT6 ; NO MORE. EXIT NOW. -FNDNXT1:CALL FCB2HL ; GET ADDRESS OF THIS FCB IN DIRECTORY. - LD A,(COUNTER) ; GET NUMBER OF BYTES (CHARACTERS) TO CHECK. - LD C,A - LD B,#0 ; INITIALIZE BYTE POSITION COUNTER. -FNDNXT2:LD A,C ; ARE WE DONE WITH THE COMPARE? - OR A - JP Z,FNDNXT5 - LD A,(DE) ; NO, CHECK NEXT BYTE. - CP #QUESTION ; DON'T CARE ABOUT THIS CHARACTER? - JP Z,FNDNXT4 - LD A,B ; GET BYTES POSITION IN FCB. - CP #13 ; DON'T CARE ABOUT THE THIRTEENTH BYTE EITHER. - JP Z,FNDNXT4 - CP #12 ; EXTENT BYTE? - LD A,(DE) - JP Z,FNDNXT3 - SUB (HL) ; OTHERWISE COMPARE CHARACTERS. - AND #0x7F - JP NZ,FINDNXT ; NOT THE SAME, CHECK NEXT ENTRY. - JP FNDNXT4 ; SO FAR SO GOOD, KEEP CHECKING. -FNDNXT3:PUSH BC ; CHECK THE EXTENT BYTE HERE. - LD C,(HL) - CALL SAMEXT - POP BC - JP NZ,FINDNXT ; NOT THE SAME, LOOK SOME MORE. -; -; SO FAR THE NAMES COMPARE. BUMP POINTERS TO THE NEXT BYTE -; AND CONTINUE UNTIL ALL (C) CHARACTERS HAVE BEEN CHECKED. -; -FNDNXT4:INC DE ; BUMP POINTERS. - INC HL - INC B - DEC C ; ADJUST CHARACTER COUNTER. - JP FNDNXT2 -FNDNXT5:LD A,(FILEPOS) ; RETURN THE POSITION OF THIS ENTRY. - AND #3 - LD (STATUS),A - LD HL,#FNDSTAT - LD A,(HL) - RLA - RET NC - XOR A - LD (HL),A - RET -; -; FILENAME WAS NOT FOUND. SET APPROPRIATE STATUS. -; -FNDNXT6:CALL STFILPOS ; SET (FILEPOS) TO 0FFFFH. - LD A,#0x0FF ; SAY NOT LOCATED. - JP SETSTAT -; -; ERASE FILES FROM THE DIRECTORY. ONLY THE FIRST BYTE OF THE -; FCB WILL BE AFFECTED. IT IS SET TO (E5). -; -ERAFILE:CALL CHKWPRT ; IS DISK WRITE PROTECTED? - LD C,#12 ; ONLY COMPARE FILE NAMES. - CALL FINDFST ; GET FIRST FILE NAME. -ERAFIL1:CALL CKFILPOS ; ANY FOUND? - RET Z ; NOPE, WE MUST BE DONE. - CALL CHKROFL ; IS FILE READ ONLY? - CALL FCB2HL ; NOPE, GET ADDRESS OF FCB AND - LD (HL),#0x0E5 ; SET FIRST BYTE TO 'EMPTY'. - LD C,#0 ; CLEAR THE SPACE FROM THE BIT MAP. - CALL SETFILE - CALL DIRWRITE ; NOW WRITE THE DIRECTORY SECTOR BACK OUT. - CALL FINDNXT ; FIND THE NEXT FILE NAME. - JP ERAFIL1 ; AND REPEAT PROCESS. -; -; LOOK THROUGH THE SPACE ALLOCATION MAP (BIT MAP) FOR THE -; NEXT AVAILABLE BLOCK. START SEARCHING AT BLOCK NUMBER (BC-1). -; THE SEARCH PROCEDURE IS TO LOOK FOR AN EMPTY BLOCK THAT IS -; BEFORE THE STARTING BLOCK. IF NOT EMPTY, LOOK AT A LATER -; BLOCK NUMBER. IN THIS WAY, WE RETURN THE CLOSEST EMPTY BLOCK -; ON EITHER SIDE OF THE 'TARGET' BLOCK NUMBER. THIS WILL SPEED -; ACCESS ON RANDOM DEVICES. FOR SERIAL DEVICES, THIS SHOULD BE -; CHANGED TO LOOK IN THE FORWARD DIRECTION FIRST AND THEN START -; AT THE FRONT AND SEARCH SOME MORE. -; -; ON RETURN, (DE)= BLOCK NUMBER THAT IS EMPTY AND (HL) =0 -; IF NO EMPRY BLOCK WAS FOUND. -; -FNDSPACE: - LD D,B ; SET (DE) AS THE BLOCK THAT IS CHECKED. - LD E,C -; -; LOOK BEFORE TARGET BLOCK. REGISTERS (BC) ARE USED AS THE LOWER -; POINTER AND (DE) AS THE UPPER POINTER. -; -FNDSPA1:LD A,C ; IS BLOCK 0 SPECIFIED? - OR B - JP Z,FNDSPA2 - DEC BC ; NOPE, CHECK PREVIOUS BLOCK. - PUSH DE - PUSH BC - CALL CKBITMAP - RRA ; IS THIS BLOCK EMPTY? - JP NC,FNDSPA3 ; YES. USE THIS. -; -; NOTE THAT THE ABOVE LOGIC GETS THE FIRST BLOCK THAT IT FINDS -; THAT IS EMPTY. THUS A FILE COULD BE WRITTEN 'BACKWARD' MAKING -; IT VERY SLOW TO ACCESS. THIS COULD BE CHANGED TO LOOK FOR THE -; FIRST EMPTY BLOCK AND THEN CONTINUE UNTIL THE START OF THIS -; EMPTY SPACE IS LOCATED AND THEN USED THAT STARTING BLOCK. -; THIS SHOULD HELP SPEED UP ACCESS TO SOME FILES ESPECIALLY ON -; A WELL USED DISK WITH LOTS OF FAIRLY SMALL 'HOLES'. -; - POP BC ; NOPE, CHECK SOME MORE. - POP DE -; -; NOW LOOK AFTER TARGET BLOCK. -; -FNDSPA2:LD HL,(DSKSIZE) ; IS BLOCK (DE) WITHIN DISK LIMITS? - LD A,E - SUB L - LD A,D - SBC A,H - JP NC,FNDSPA4 - INC DE ; YES, MOVE ON TO NEXT ONE. - PUSH BC - PUSH DE - LD B,D - LD C,E - CALL CKBITMAP ; CHECK IT. - RRA ; EMPTY? - JP NC,FNDSPA3 - POP DE ; NOPE, CONTINUE SEARCHING. - POP BC - JP FNDSPA1 -; -; EMPTY BLOCK FOUND. SET IT AS USED AND RETURN WITH (HL) -; POINTING TO IT (TRUE?). -; -FNDSPA3:RLA ; RESET BYTE. - INC A ; AND SET BIT 0. - CALL STBMAP1 ; UPDATE BIT MAP. - POP HL ; SET RETURN REGISTERS. - POP DE - RET -; -; FREE BLOCK WAS NOT FOUND. IF (BC) IS NOT ZERO, THEN WE HAVE -; NOT CHECKED ALL OF THE DISK SPACE. -; -FNDSPA4:LD A,C - OR B - JP NZ,FNDSPA1 - LD HL,#0 ; SET 'NOT FOUND' STATUS. - RET -; -; MOVE A COMPLETE FCB ENTRY INTO THE DIRECTORY AND WRITE IT. -; -FCBSET: LD C,#0 - LD E,#32 ; LENGTH OF EACH ENTRY. -; -; MOVE (E) BYTES FROM THE FCB POINTED TO BY (PARAMS) INTO -; FCB IN DIRECTORY STARTING AT RELATIVE BYTE (C). THIS UPDATED -; DIRECTORY BUFFER IS THEN WRITTEN TO THE DISK. -; -UPDATE: PUSH DE - LD B,#0 ; SET (BC) TO RELATIVE BYTE POSITION. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - ADD HL,BC ; COMPUTE STARTING BYTE. - EX DE,HL - CALL FCB2HL ; GET ADDRESS OF FCB TO UPDATE IN DIRECTORY. - POP BC ; SET (C) TO NUMBER OF BYTES TO CHANGE. - CALL DE2HL -UPDATE1:CALL TRKSEC ; DETERMINE THE TRACK AND SECTOR AFFECTED. - JP DIRWRITE ; THEN WRITE THIS SECTOR OUT. -; -; ROUTINE TO CHANGE THE NAME OF ALL FILES ON THE DISK WITH A -; SPECIFIED NAME. THE FCB CONTAINS THE CURRENT NAME AS THE -; FIRST 12 CHARACTERS AND THE NEW NAME 16 BYTES INTO THE FCB. -; -CHGNAMES: - CALL CHKWPRT ; CHECK FOR A WRITE PROTECTED DISK. - LD C,#12 ; MATCH FIRST 12 BYTES OF FCB ONLY. - CALL FINDFST ; GET FIRST NAME. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - LD A,(HL) ; GET USER NUMBER. - LD DE,#16 ; MOVE OVER TO DESIRED NAME. - ADD HL,DE - LD (HL),A ; KEEP SAME USER NUMBER. -CHGNAM1:CALL CKFILPOS ; ANY MATCHING FILE FOUND? - RET Z ; NO, WE MUST BE DONE. - CALL CHKROFL ; CHECK FOR READ ONLY FILE. - LD C,#16 ; START 16 BYTES INTO FCB. - LD E,#12 ; AND UPDATE THE FIRST 12 BYTES OF DIRECTORY. - CALL UPDATE - CALL FINDNXT ; GET TE NEXT FILE NAME. - JP CHGNAM1 ; AND CONTINUE. -; -; UPDATE A FILES ATTRIBUTES. THE PROCEDURE IS TO SEARCH FOR -; EVERY FILE WITH THE SAME NAME AS SHOWN IN FCB (IGNORING BIT 7) -; AND THEN TO UPDATE IT (WHICH INCLUDES BIT 7). NO OTHER CHANGES -; ARE MADE. -; -SAVEATTR: - LD C,#12 ; MATCH FIRST 12 BYTES. - CALL FINDFST ; LOOK FOR FIRST FILENAME. -SAVATR1:CALL CKFILPOS ; WAS ONE FOUND? - RET Z ; NOPE, WE MUST BE DONE. - LD C,#0 ; YES, UPDATE THE FIRST 12 BYTES NOW. - LD E,#12 - CALL UPDATE ; UPDATE FILENAME AND WRITE DIRECTORY. - CALL FINDNXT ; AND GET THE NEXT FILE. - JP SAVATR1 ; THEN CONTINUE UNTIL DONE. -; -; OPEN A FILE (NAME SPECIFIED IN FCB). -; -OPENIT: LD C,#15 ; COMPARE THE FIRST 15 BYTES. - CALL FINDFST ; GET THE FIRST ONE IN DIRECTORY. - CALL CKFILPOS ; ANY AT ALL? - RET Z -OPENIT1:CALL SETEXT ; POINT TO EXTENT BYTE WITHIN USERS FCB. - LD A,(HL) ; AND GET IT. - PUSH AF ; SAVE IT AND ADDRESS. - PUSH HL - CALL FCB2HL ; POINT TO FCB IN DIRECTORY. - EX DE,HL - LD HL,(PARAMS) ; THIS IS THE USERS COPY. - LD C,#32 ; MOVE IT INTO USERS SPACE. - PUSH DE - CALL DE2HL - CALL SETS2B7 ; SET BIT 7 IN 'S2' BYTE (UNMODIFIED). - POP DE ; NOW GET THE EXTENT BYTE FROM THIS FCB. - LD HL,#12 - ADD HL,DE - LD C,(HL) ; INTO (C). - LD HL,#15 ; NOW GET THE RECORD COUNT BYTE INTO (B). - ADD HL,DE - LD B,(HL) - POP HL ; KEEP THE SAME EXTENT AS THE USER HAD ORIGINALLY. - POP AF - LD (HL),A - LD A,C ; IS IT THE SAME AS IN THE DIRECTORY FCB? - CP (HL) - LD A,B ; IF YES, THEN USE THE SAME RECORD COUNT. - JP Z,OPENIT2 - LD A,#0 ; IF THE USER SPECIFIED AN EXTENT GREATER THAN - JP C,OPENIT2 ; THE ONE IN THE DIRECTORY, THEN SET RECORD COUNT TO 0. - LD A,#128 ; OTHERWISE SET TO MAXIMUM. -OPENIT2:LD HL,(PARAMS) ; SET RECORD COUNT IN USERS FCB TO (A). - LD DE,#15 - ADD HL,DE ; COMPUTE RELATIVE POSITION. - LD (HL),A ; AND SET THE RECORD COUNT. - RET -; -; MOVE TWO BYTES FROM (DE) TO (HL) IF (AND ONLY IF) (HL) -; POINT TO A ZERO VALUE (16 BIT). -; RETURN WITH ZERO FLAG SET IT (DE) WAS MOVED. REGISTERS (DE) -; AND (HL) ARE NOT CHANGED. HOWEVER (A) IS. -; -MOVEWORD: - LD A,(HL) ; CHECK FOR A ZERO WORD. - INC HL - OR (HL) ; BOTH BYTES ZERO? - DEC HL - RET NZ ; NOPE, JUST RETURN. - LD A,(DE) ; YES, MOVE TWO BYTES FROM (DE) INTO - LD (HL),A ; THIS ZERO SPACE. - INC DE - INC HL - LD A,(DE) - LD (HL),A - DEC DE ; DON'T DISTURB THESE REGISTERS. - DEC HL - RET -; -; GET HERE TO CLOSE A FILE SPECIFIED BY (FCB). -; -CLOSEIT:XOR A ; CLEAR STATUS AND FILE POSITION BYTES. - LD (STATUS),A - LD (FILEPOS),A - LD (FILEPOS+1),A - CALL GETWPRT ; GET WRITE PROTECT BIT FOR THIS DRIVE. - RET NZ ; JUST RETURN IF IT IS SET. - CALL GETS2 ; ELSE GET THE 'S2' BYTE. - AND #0x80 ; AND LOOK AT BIT 7 (FILE UNMODIFIED?). - RET NZ ; JUST RETURN IF SET. - LD C,#15 ; ELSE LOOK UP THIS FILE IN DIRECTORY. - CALL FINDFST - CALL CKFILPOS ; WAS IT FOUND? - RET Z ; JUST RETURN IF NOT. - LD BC,#16 ; SET (HL) POINTING TO RECORDS USED SECTION. - CALL FCB2HL - ADD HL,BC - EX DE,HL - LD HL,(PARAMS) ; DO THE SAME FOR USERS SPECIFIED FCB. - ADD HL,BC - LD C,#16 ; THIS MANY BYTES ARE PRESENT IN THIS EXTENT. -CLOSEIT1: - LD A,(BIGDISK) ; 8 OR 16 BIT RECORD NUMBERS? - OR A - JP Z,CLOSEIT4 - LD A,(HL) ; JUST 8 BIT. GET ONE FROM USERS FCB. - OR A - LD A,(DE) ; NOW GET ONE FROM DIRECTORY FCB. - JP NZ,CLOSEIT2 - LD (HL),A ; USERS BYTE WAS ZERO. UPDATE FROM DIRECTORY. -CLOSEIT2: - OR A - JP NZ,CLOSEIT3 - LD A,(HL) ; DIRECTORIES BYTE WAS ZERO, UPDATE FROM USERS FCB. - LD (DE),A -CLOSEIT3: - CP (HL) ; IF NEITHER ONE OF THESE BYTES WERE ZERO, - JP NZ,CLOSEIT7 ; THEN CLOSE ERROR IF THEY ARE NOT THE SAME. - JP CLOSEIT5 ; OK SO FAR, GET TO NEXT BYTE IN FCBS. -CLOSEIT4: - CALL MOVEWORD ; UPDATE USERS FCB IF IT IS ZERO. - EX DE,HL - CALL MOVEWORD ; UPDATE DIRECTORIES FCB IF IT IS ZERO. - EX DE,HL - LD A,(DE) ; IF THESE TWO VALUES ARE NO DIFFERENT, - CP (HL) ; THEN A CLOSE ERROR OCCURED. - JP NZ,CLOSEIT7 - INC DE ; CHECK SECOND BYTE. - INC HL - LD A,(DE) - CP (HL) - JP NZ,CLOSEIT7 - DEC C ; REMEMBER 16 BIT VALUES. -CLOSEIT5: - INC DE ; BUMP TO NEXT ITEM IN TABLE. - INC HL - DEC C ; THERE ARE 16 ENTRIES ONLY. - JP NZ,CLOSEIT1 ; CONTINUE IF MORE TO DO. - LD BC,#0x0FFEC ; BACKUP 20 PLACES (EXTENT BYTE). - ADD HL,BC - EX DE,HL - ADD HL,BC - LD A,(DE) - CP (HL) ; DIRECTORY'S EXTENT ALREADY GREATER THAN THE - JP C,CLOSEIT6 ; USERS EXTENT? - LD (HL),A ; NO, UPDATE DIRECTORY EXTENT. - LD BC,#3 ; AND UPDATE THE RECORD COUNT BYTE IN - ADD HL,BC ; DIRECTORIES FCB. - EX DE,HL - ADD HL,BC - LD A,(HL) ; GET FROM USER. - LD (DE),A ; AND PUT IN DIRECTORY. -CLOSEIT6: - LD A,#0x0FF ; SET 'WAS OPEN AND IS NOW CLOSED' BYTE. - LD (CLOSEFLG),A - JP UPDATE1 ; UPDATE THE DIRECTORY NOW. -CLOSEIT7: - LD HL,#STATUS ; SET RETURN STATUS AND THEN RETURN. - DEC (HL) - RET -; -; ROUTINE TO GET THE NEXT EMPTY SPACE IN THE DIRECTORY. IT -; WILL THEN BE CLEARED FOR USE. -; -GETEMPTY: - CALL CHKWPRT ; MAKE SURE DISK IS NOT WRITE PROTECTED. - LD HL,(PARAMS) ; SAVE CURRENT PARAMETERS (FCB). - PUSH HL - LD HL,#EMPTYFCB ; USE SPECIAL ONE FOR EMPTY SPACE. - LD (PARAMS),HL - LD C,#1 ; SEARCH FOR FIRST EMPTY SPOT IN DIRECTORY. - CALL FINDFST ; (* ONLY CHECK FIRST BYTE *) - CALL CKFILPOS ; NONE? - POP HL - LD (PARAMS),HL ; RESTORE ORIGINAL FCB ADDRESS. - RET Z ; RETURN IF NO MORE SPACE. - EX DE,HL - LD HL,#15 ; POINT TO NUMBER OF RECORDS FOR THIS FILE. - ADD HL,DE - LD C,#17 ; AND CLEAR ALL OF THIS SPACE. - XOR A -GETMT1: LD (HL),A - INC HL - DEC C - JP NZ,GETMT1 - LD HL,#13 ; CLEAR THE 'S1' BYTE ALSO. - ADD HL,DE - LD (HL),A - CALL CHKNMBR ; KEEP (SCRATCH1) WITHIN BOUNDS. - CALL FCBSET ; WRITE OUT THIS FCB ENTRY TO DIRECTORY. - JP SETS2B7 ; SET 'S2' BYTE BIT 7 (UNMODIFIED AT PRESENT). -; -; ROUTINE TO CLOSE THE CURRENT EXTENT AND OPEN THE NEXT ONE -; FOR READING. -; -GETNEXT:XOR A - LD (CLOSEFLG),A ; CLEAR CLOSE FLAG. - CALL CLOSEIT ; CLOSE THIS EXTENT. - CALL CKFILPOS - RET Z ; NOT THERE??? - LD HL,(PARAMS) ; GET EXTENT BYTE. - LD BC,#12 - ADD HL,BC - LD A,(HL) ; AND INCREMENT IT. - INC A - AND #0x1F ; KEEP WITHIN RANGE 0-31. - LD (HL),A - JP Z,GTNEXT1 ; OVERFLOW? - LD B,A ; MASK EXTENT BYTE. - LD A,(EXTMASK) - AND B - LD HL,#CLOSEFLG ; CHECK CLOSE FLAG (0FFH IS OK). - AND (HL) - JP Z,GTNEXT2 ; IF ZERO, WE MUST READ IN NEXT EXTENT. - JP GTNEXT3 ; ELSE, IT IS ALREADY IN MEMORY. -GTNEXT1:LD BC,#2 ; POINT TO THE 'S2' BYTE. - ADD HL,BC - INC (HL) ; AND BUMP IT. - LD A,(HL) ; TOO MANY EXTENTS? - AND #0x0F - JP Z,GTNEXT5 ; YES, SET ERROR CODE. -; -; GET HERE TO OPEN THE NEXT EXTENT. -; -GTNEXT2:LD C,#15 ; SET TO CHECK FIRST 15 BYTES OF FCB. - CALL FINDFST ; FIND THE FIRST ONE. - CALL CKFILPOS ; NONE AVAILABLE? - JP NZ,GTNEXT3 - LD A,(R.DWRTFLG) ; NO EXTENT PRESENT. CAN WE OPEN AN EMPTY ONE? - INC A ; 0FFH MEANS READING (SO NOT POSSIBLE). - JP Z,GTNEXT5 ; OR AN ERROR. - CALL GETEMPTY ; WE ARE WRITING, GET AN EMPTY ENTRY. - CALL CKFILPOS ; NONE? - JP Z,GTNEXT5 ; ERROR IF TRUE. - JP GTNEXT4 ; ELSE WE ARE ALMOST DONE. -GTNEXT3:CALL OPENIT1 ; OPEN THIS EXTENT. -GTNEXT4:CALL STRDATA ; MOVE IN UPDATED DATA (REC #, EXTENT #, ETC.) - XOR A ; CLEAR STATUS AND RETURN. - JP SETSTAT -; -; ERROR IN EXTENDING THE FILE. TOO MANY EXTENTS WERE NEEDED -; OR NOT ENOUGH SPACE ON THE DISK. -; -GTNEXT5:CALL IOERR1 ; SET ERROR CODE, CLEAR BIT 7 OF 'S2' - JP SETS2B7 ; SO THIS IS NOT WRITTEN ON A CLOSE. -; -; READ A S.EQUENTIAL FILE. -; -RDSEQ: LD A,#1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -RDSEQ1: LD A,#0x0FF ; DON'T ALLOW READING UNWRITTEN SPACE. - LD (R.DWRTFLG),A - CALL STRDATA ; PUT REC# AND EXT# INTO FCB. - LD A,(SAVNREC) ; GET NEXT RECORD TO READ. - LD HL,#SAVNXT ; GET NUMBER OF RECORDS IN EXTENT. - CP (HL) ; WITHIN THIS EXTENT? - JP C,RDSEQ2 - CP #128 ; NO. IS THIS EXTENT FULLY USED? - JP NZ,RDSEQ3 ; NO. END-OF-FILE. - CALL GETNEXT ; YES, OPEN THE NEXT ONE. - XOR A ; RESET NEXT RECORD TO READ. - LD (SAVNREC),A - LD A,(STATUS) ; CHECK ON OPEN, SUCCESSFUL? - OR A - JP NZ,RDSEQ3 ; NO, ERROR. -RDSEQ2: CALL COMBLK ; OK. COMPUTE BLOCK NUMBER TO READ. - CALL CHKBLK ; CHECK IT. WITHIN BOUNDS? - JP Z,RDSEQ3 ; NO, ERROR. - CALL LOGICAL ; CONVERT (BLKNMBR) TO LOGICAL SECTOR (128 BYTE). - CALL TRKSEC1 ; SET THE TRACK AND SECTOR FOR THIS BLOCK #. - CALL DOREAD ; AND READ IT. - JP SETNREC ; AND SET THE NEXT RECORD TO BE ACCESSED. -; -; READ ERROR OCCURED. SET STATUS AND RETURN. -; -RDSEQ3: JP IOERR1 -; -; WRITE THE NEXT S.EQUENTIAL RECORD. -; -WTSEQ: LD A,#1 ; SET S.EQUENTIAL ACCESS MODE. - LD (MODE),A -WTSEQ1: LD A,#0 ; ALLOW AN ADDITION EMPTY EXTENT TO BE OPENED. - LD (R.DWRTFLG),A - CALL CHKWPRT ; CHECK WRITE PROTECT STATUS. - LD HL,(PARAMS) - CALL CKROF1 ; CHECK FOR READ ONLY FILE, (HL) ALREADY SET TO FCB. - CALL STRDATA ; PUT UPDATED DATA INTO FCB. - LD A,(SAVNREC) ; GET RECORD NUMBER TO WRITE. - CP #128 ; WITHIN RANGE? - JP NC,IOERR1 ; NO, ERROR(?). - CALL COMBLK ; COMPUTE BLOCK NUMBER. - CALL CHKBLK ; CHECK NUMBER. - LD C,#0 ; IS THERE ONE TO WRITE TO? - JP NZ,WTSEQ6 ; YES, GO DO IT. - CALL GETBLOCK ; GET NEXT BLOCK NUMBER WITHIN FCB TO USE. - LD (RELBLOCK),A ; AND SAVE. - LD BC,#0 ; START LOOKING FOR SPACE FROM THE START - OR A ; IF NONE ALLOCATED AS YET. - JP Z,WTSEQ2 - LD C,A ; EXTRACT PREVIOUS BLOCK NUMBER FROM FCB - DEC BC ; SO WE CAN BE CLOSEST TO IT. - CALL EXTBLK - LD B,H - LD C,L -WTSEQ2: CALL FNDSPACE ; FIND THE NEXT EMPTY BLOCK NEAREST NUMBER (BC). - LD A,L ; CHECK FOR A ZERO NUMBER. - OR H - JP NZ,WTSEQ3 - LD A,#2 ; NO MORE SPACE? - JP SETSTAT -WTSEQ3: LD (BLKNMBR),HL ; SAVE BLOCK NUMBER TO ACCESS. - EX DE,HL ; PUT BLOCK NUMBER INTO (DE). - LD HL,(PARAMS) ; NOW WE MUST UPDATE THE FCB FOR THIS - LD BC,#16 ; NEWLY ALLOCATED BLOCK. - ADD HL,BC - LD A,(BIGDISK) ; 8 OR 16 BIT BLOCK NUMBERS? - OR A - LD A,(RELBLOCK) ; (* UPDATE THIS ENTRY *) - JP Z,WTSEQ4 ; ZERO MEANS 16 BIT ONES. - CALL ADDA2HL ; (HL)=(HL)+(A) - LD (HL),E ; STORE NEW BLOCK NUMBER. - JP WTSEQ5 -WTSEQ4: LD C,A ; COMPUTE SPOT IN THIS 16 BIT TABLE. - LD B,#0 - ADD HL,BC - ADD HL,BC - LD (HL),E ; STUFF BLOCK NUMBER (DE) THERE. - INC HL - LD (HL),D -WTSEQ5: LD C,#2 ; SET (C) TO INDICATE WRITING TO UN-USED DISK SPACE. -WTSEQ6: LD A,(STATUS) ; ARE WE OK SO FAR? - OR A - RET NZ - PUSH BC ; YES, SAVE WRITE FLAG FOR BIOS (REGISTER C). - CALL LOGICAL ; CONVERT (BLKNMBR) OVER TO LOICAL SECTORS. - LD A,(MODE) ; GET ACCESS MODE FLAG (1=S.EQUENTIAL, - DEC A ; 0=RANDOM, 2=SPECIAL?). - DEC A - JP NZ,WTSEQ9 -; -; SPECIAL RANDOM I/O FROM FUNCTION #40. MAYBE FOR M/PM, BUT THE -; CURRENT BLOCK, IF IT HAS NOT BEEN WRITTEN TO, WILL BE ZEROED -; OUT AND THEN WRITTEN (REASON?). -; - POP BC - PUSH BC - LD A,C ; GET WRITE STATUS FLAG (2=WRITING UNUSED SPACE). - DEC A - DEC A - JP NZ,WTSEQ9 - PUSH HL - LD HL,(DIRBUF) ; ZERO OUT THE DIRECTORY BUFFER. - LD D,A ; NOTE THAT (A) IS ZERO HERE. -WTSEQ7: LD (HL),A - INC HL - INC D ; DO 128 BYTES. - JP P,WTSEQ7 - CALL DIRDMA ; TELL THE BIOS THE DMA ADDRESS FOR DIRECTORY ACCESS. - LD HL,(LOGSECT) ; GET SECTOR THAT STARTS CURRENT BLOCK. - LD C,#2 ; SET 'WRITING TO UNUSED SPACE' FLAG. -WTSEQ8: LD (BLKNMBR),HL ; SAVE SECTOR TO WRITE. - PUSH BC - CALL TRKSEC1 ; DETERMINE ITS TRACK AND SECTOR NUMBERS. - POP BC - CALL DOWRITE ; NOW WRITE OUT 128 BYTES OF ZEROS. - LD HL,(BLKNMBR) ; GET SECTOR NUMBER. - LD C,#0 ; SET NORMAL WRITE FLAG. - LD A,(BLKMASK) ; DETERMINE IF WE HAVE WRITTEN THE ENTIRE - LD B,A ; PHYSICAL BLOCK. - AND L - CP B - INC HL ; PREPARE FOR THE NEXT ONE. - JP NZ,WTSEQ8 ; CONTINUE UNTIL (BLKMASK+1) SECTORS WRITTEN. - POP HL ; RESET NEXT SECTOR NUMBER. - LD (BLKNMBR),HL - CALL DEFDMA ; AND RESET DMA ADDRESS. -; -; NORMAL DISK WRITE. SET THE DESIRED TRACK AND SECTOR THEN -; DO THE ACTUAL WRITE. -; -WTSEQ9: CALL TRKSEC1 ; DETERMINE TRACK AND SECTOR FOR THIS WRITE. - POP BC ; GET WRITE STATUS FLAG. - PUSH BC - CALL DOWRITE ; AND WRITE THIS OUT. - POP BC - LD A,(SAVNREC) ; GET NUMBER OF RECORDS IN FILE. - LD HL,#SAVNXT ; GET LAST RECORD WRITTEN. - CP (HL) - JP C,WTSEQ10 - LD (HL),A ; WE HAVE TO UPDATE RECORD COUNT. - INC (HL) - LD C,#2 -; -;* THIS AREA HAS BEEN PATCHED TO CORRECT DISK UPDATE PROBLEM -;* WHEN USING BLOCKING AND DE-BLOCKING IN THE BIOS. -; -WTSEQ10:NOP ; WAS 'DCR C' - NOP ; WAS 'DCR C' - LD HL,#0 ; WAS 'JNZ WTSEQ99' -; -; * END OF PATCH. -; - PUSH AF - CALL GETS2 ; SET 'EXTENT WRITTEN TO' FLAG. - AND #0x7F ; (* CLEAR BIT 7 *) - LD (HL),A - POP AF ; GET RECORD COUNT FOR THIS EXTENT. -WTSEQ99:CP #127 ; IS IT FULL? - JP NZ,WTSEQ12 - LD A,(MODE) ; YES, ARE WE IN S.EQUENTIAL MODE? - CP #1 - JP NZ,WTSEQ12 - CALL SETNREC ; YES, SET NEXT RECORD NUMBER. - CALL GETNEXT ; AND GET NEXT EMPTY SPACE IN DIRECTORY. - LD HL,#STATUS ; OK? - LD A,(HL) - OR A - JP NZ,WTSEQ11 - DEC A ; YES, SET RECORD COUNT TO -1. - LD (SAVNREC),A -WTSEQ11:LD (HL),#0 ; CLEAR STATUS. -WTSEQ12:JP SETNREC ; SET NEXT RECORD TO ACCESS. -; -; FOR RANDOM I/O, SET THE FCB FOR THE DESIRED RECORD NUMBER -; BASED ON THE 'R0,R1,R2' BYTES. THESE BYTES IN THE FCB ARE -; USED AS FOLLOWS: -; -; FCB+35 FCB+34 FCB+33 -; | 'R-2' | 'R-1' | 'R-0' | -; |7 0 | 7 0 | 7 0| -; |0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0| -; | OVERFLOW | | EXTRA | EXTENT | RECORD # | -; | ______________| |_EXTENT|__NUMBER___|_____________| -; ALSO 'S2' -; -; ON ENTRY, REGISTER (C) CONTAINS 0FFH IF THIS IS A READ -; AND THUS WE CAN NOT ACCESS UNWRITTEN DISK SPACE. OTHERWISE, -; ANOTHER EXTENT WILL BE OPENED (FOR WRITING) IF R.EQUIRED. -; -POSITION: - XOR A ; SET RANDOM I/O FLAG. - LD (MODE),A -; -; SPECIAL ENTRY (FUNCTION #40). M/PM ? -; -POSITN1:PUSH BC ; SAVE READ/WRITE FLAG. - LD HL,(PARAMS) ; GET ADDRESS OF FCB. - EX DE,HL - LD HL,#33 ; NOW GET BYTE 'R0'. - ADD HL,DE - LD A,(HL) - AND #0x7F ; KEEP BITS 0-6 FOR THE RECORD NUMBER TO ACCESS. - PUSH AF - LD A,(HL) ; NOW GET BIT 7 OF 'R0' AND BITS 0-3 OF 'R1'. - RLA - INC HL - LD A,(HL) - RLA - AND #0x1F ; AND SAVE THIS IN BITS 0-4 OF (C). - LD C,A ; THIS IS THE EXTENT BYTE. - LD A,(HL) ; NOW GET THE EXTRA EXTENT BYTE. - RRA - RRA - RRA - RRA - AND #0x0F - LD B,A ; AND SAVE IT IN (B). - POP AF ; GET RECORD NUMBER BACK TO (A). - INC HL ; CHECK OVERFLOW BYTE 'R2'. - LD L,(HL) - INC L - DEC L - LD L,#6 ; PREPARE FOR ERROR. - JP NZ,POSITN5 ; OUT OF DISK SPACE ERROR. - LD HL,#32 ; STORE RECORD NUMBER INTO FCB. - ADD HL,DE - LD (HL),A - LD HL,#12 ; AND NOW CHECK THE EXTENT BYTE. - ADD HL,DE - LD A,C - SUB (HL) ; SAME EXTENT AS BEFORE? - JP NZ,POSITN2 - LD HL,#14 ; YES, CHECK EXTRA EXTENT BYTE 'S2' ALSO. - ADD HL,DE - LD A,B - SUB (HL) - AND #0x7F - JP Z,POSITN3 ; SAME, WE ARE ALMOST DONE THEN. -; -; GET HERE WHEN ANOTHER EXTENT IS R.EQUIRED. -; -POSITN2:PUSH BC - PUSH DE - CALL CLOSEIT ; CLOSE CURRENT EXTENT. - POP DE - POP BC - LD L,#3 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; CLOSE ERROR. - LD HL,#12 ; PUT DESIRED EXTENT INTO FCB NOW. - ADD HL,DE - LD (HL),C - LD HL,#14 ; AND STORE EXTRA EXTENT BYTE 'S2'. - ADD HL,DE - LD (HL),B - CALL OPENIT ; TRY AND GET THIS EXTENT. - LD A,(STATUS) ; WAS IT THERE? - INC A - JP NZ,POSITN3 - POP BC ; NO. CAN WE CREATE A NEW ONE (WRITING?). - PUSH BC - LD L,#4 ; PREPARE FOR ERROR. - INC C - JP Z,POSITN4 ; NOPE, READING UNWRITTEN SPACE ERROR. - CALL GETEMPTY ; YES WE CAN, TRY TO FIND SPACE. - LD L,#5 ; PREPARE FOR ERROR. - LD A,(STATUS) - INC A - JP Z,POSITN4 ; OUT OF SPACE? -; -; NORMAL RETURN LOCATION. CLEAR ERROR CODE AND RETURN. -; -POSITN3:POP BC ; RESTORE STACK. - XOR A ; AND CLEAR ERROR CODE BYTE. - JP SETSTAT -; -; ERROR. SET THE 'S2' BYTE TO INDICATE THIS (WHY?). -; -POSITN4:PUSH HL - CALL GETS2 - LD (HL),#0x0C0 - POP HL -; -; RETURN WITH ERROR CODE (PRESENTLY IN L). -; -POSITN5:POP BC - LD A,L ; GET ERROR CODE. - LD (STATUS),A - JP SETS2B7 -; -; READ A RANDOM RECORD. -; -READRAN:LD C,#0x0FF ; SET 'READ' STATUS. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,RDSEQ1 ; AND READ IT AS USUAL (IF NO ERRORS). - RET -; -; WRITE TO A RANDOM RECORD. -; -WRITERAN: - LD C,#0 ; SET 'WRITING' FLAG. - CALL POSITION ; POSITION THE FILE TO PROPER RECORD. - CALL Z,WTSEQ1 ; AND WRITE AS USUAL (IF NO ERRORS). - RET -; -; COMPUTE THE RANDOM RECORD NUMBER. ENTER WITH (HL) POINTING -; TO A FCB AN (DE) CONTAINS A RELATIVE LOCATION OF A RECORD -; NUMBER. ON EXIT, (C) CONTAINS THE 'R0' BYTE, (B) THE 'R1' -; BYTE, AND (A) THE 'R2' BYTE. -; -; ON RETURN, THE ZERO FLAG IS SET IF THE RECORD IS WITHIN -; BOUNDS. OTHERWISE, AN OVERFLOW OCCURED. -; -COMPRAND: - EX DE,HL ; SAVE FCB POINTER IN (DE). - ADD HL,DE ; COMPUTE RELATIVE POSITION OF RECORD #. - LD C,(HL) ; GET RECORD NUMBER INTO (BC). - LD B,#0 - LD HL,#12 ; NOW GET EXTENT. - ADD HL,DE - LD A,(HL) ; COMPUTE (BC)=(RECORD #)+(EXTENT)*128. - RRCA ; MOVE LOWER BIT INTO BIT 7. - AND #0x80 ; AND IGNORE ALL OTHER BITS. - ADD A,C ; ADD TO OUR RECORD NUMBER. - LD C,A - LD A,#0 ; TAKE CARE OF ANY CARRY. - ADC A,B - LD B,A - LD A,(HL) ; NOW GET THE UPPER BITS OF EXTENT INTO - RRCA ; BIT POSITIONS 0-3. - AND #0x0F ; AND IGNORE ALL OTHERS. - ADD A,B ; ADD THIS IN TO 'R1' BYTE. - LD B,A - LD HL,#14 ; GET THE 'S2' BYTE (EXTRA EXTENT). - ADD HL,DE - LD A,(HL) - ADD A,A ; AND SHIFT IT LEFT 4 BITS (BITS 4-7). - ADD A,A - ADD A,A - ADD A,A - PUSH AF ; SAVE CARRY FLAG (BIT 0 OF FLAG BYTE). - ADD A,B ; NOW ADD EXTRA EXTENT INTO 'R1'. - LD B,A - PUSH AF ; AND SAVE CARRY (OVERFLOW BYTE 'R2'). - POP HL ; BIT 0 OF (L) IS THE OVERFLOW INDICATOR. - LD A,L - POP HL ; AND SAME FOR FIRST CARRY FLAG. - OR L ; EITHER ONE OF THESE SET? - AND #1 ; ONLY CHECK THE CARRY FLAGS. - RET -; -; ROUTINE TO SETUP THE FCB (BYTES 'R0', 'R1', 'R2') TO -; REFLECT THE LAST RECORD USED FOR A RANDOM (OR OTHER) FILE. -; THIS READS THE DIRECTORY AND LOOKS AT ALL EXTENTS COMPUTING -; THE LARGERST RECORD NUMBER FOR EACH AND KEEPING THE MAXIMUM -; VALUE ONLY. THEN 'R0', 'R1', AND 'R2' WILL REFLECT THIS -; MAXIMUM RECORD NUMBER. THIS IS USED TO COMPUTE THE SPACE USED -; BY A RANDOM FILE. -; -RANSIZE:LD C,#12 ; LOOK THRU DIRECTORY FOR FIRST ENTRY WITH - CALL FINDFST ; THIS NAME. - LD HL,(PARAMS) ; ZERO OUT THE 'R0, R1, R2' BYTES. - LD DE,#33 - ADD HL,DE - PUSH HL - LD (HL),D ; NOTE THAT (D)=0. - INC HL - LD (HL),D - INC HL - LD (HL),D -RANSIZ1:CALL CKFILPOS ; IS THERE AN EXTENT TO PROCESS? - JP Z,RANSIZ3 ; NO, WE ARE DONE. - CALL FCB2HL ; SET (HL) POINTING TO PROPER FCB IN DIR. - LD DE,#15 ; POINT TO LAST RECORD IN EXTENT. - CALL COMPRAND ; AND COMPUTE RANDOM PARAMETERS. - POP HL - PUSH HL ; NOW CHECK THESE VALUES AGAINST THOSE - LD E,A ; ALREADY IN FCB. - LD A,C ; THE CARRY FLAG WILL BE SET IF THOSE - SUB (HL) ; IN THE FCB REPRESENT A LARGER SIZE THAN - INC HL ; THIS EXTENT DOES. - LD A,B - SBC A,(HL) - INC HL - LD A,E - SBC A,(HL) - JP C,RANSIZ2 - LD (HL),E ; WE FOUND A LARGER (IN SIZE) EXTENT. - DEC HL ; STUFF THESE VALUES INTO FCB. - LD (HL),B - DEC HL - LD (HL),C -RANSIZ2:CALL FINDNXT ; NOW GET THE NEXT EXTENT. - JP RANSIZ1 ; CONTINUE TIL ALL DONE. -RANSIZ3:POP HL ; WE ARE DONE, RESTORE THE STACK AND - RET ; RETURN. -; -; FUNCTION TO RETURN THE RANDOM RECORD POSITION OF A GIVEN -; FILE WHICH HAS BEEN READ IN S.EQUENTIAL MODE UP TO NOW. -; -SETRAN: LD HL,(PARAMS) ; POINT TO FCB. - LD DE,#32 ; AND TO LAST USED RECORD. - CALL COMPRAND ; COMPUTE RANDOM POSITION. - LD HL,#33 ; NOW STUFF THESE VALUES INTO FCB. - ADD HL,DE - LD (HL),C ; MOVE 'R0'. - INC HL - LD (HL),B ; AND 'R1'. - INC HL - LD (HL),A ; AND LASTLY 'R2'. - RET -; -; THIS ROUTINE SELECT THE DRIVE SPECIFIED IN (ACTIVE) AND -; UPDATE THE LOGIN VECTOR AND BITMAP TABLE IF THIS DRIVE WAS -; NOT ALREADY ACTIVE. -; -LOGINDRV: - LD HL,(LOGIN) ; GET THE LOGIN VECTOR. - LD A,(ACTIVE) ; GET THE DEFAULT DRIVE. - LD C,A - CALL SHIFTR ; POSITION ACTIVE BIT FOR THIS DRIVE - PUSH HL ; INTO BIT 0. - EX DE,HL - CALL SELECT ; SELECT THIS DRIVE. - POP HL - CALL Z,SLCTERR ; VALID DRIVE? - LD A,L ; IS THIS A NEWLY ACTIVATED DRIVE? - RRA - RET C - LD HL,(LOGIN) ; YES, UPDATE THE LOGIN VECTOR. - LD C,L - LD B,H - CALL SETBIT - LD (LOGIN),HL ; AND SAVE. - JP BITMAP ; NOW UPDATE THE BITMAP. -; -; FUNCTION TO SET THE ACTIVE DISK NUMBER. -; -SETDSK: LD A,(EPARAM) ; GET PARAMETER PASSED AND SEE IF THIS - LD HL,#ACTIVE ; REPRESENTS A CHANGE IN DRIVES. - CP (HL) - RET Z - LD (HL),A ; YES IT DOES, LOG IT IN. - JP LOGINDRV -; -; THIS IS THE 'AUTO DISK SELECT' ROUTINE. THE FIRSST BYTE -; OF THE FCB IS EXAMINED FOR A DRIVE SPECIFICATION. IF NON -; ZERO THEN THE DRIVE WILL BE SELECTED AND LOGED IN. -; -AUTOSEL:LD A,#0x0FF ; SAY 'AUTO-SELECT ACTIVATED'. - LD (AUTO),A - LD HL,(PARAMS) ; GET DRIVE SPECIFIED. - LD A,(HL) - AND #0x1F ; LOOK AT LOWER 5 BITS. - DEC A ; ADJUST FOR (1=A, 2=B) ETC. - LD (EPARAM),A ; AND SAVE FOR THE SELECT ROUTINE. - CP #0x1E ; CHECK FOR 'NO CHANGE' CONDITION. - JP NC,AUTOSL1 ; YES, DON'T CHANGE. - LD A,(ACTIVE) ; WE MUST CHANGE, SAVE CURRENTLY ACTIVE - LD (OLDDRV),A ; DRIVE. - LD A,(HL) ; AND SAVE FIRST BYTE OF FCB ALSO. - LD (AUTOFLAG),A ; THIS MUST BE NON-ZERO. - AND #0x0E0 ; WHATS THIS FOR (BITS 6,7 ARE USED FOR - LD (HL),A ; SOMETHING)? - CALL SETDSK ; SELECT AND LOG IN THIS DRIVE. -AUTOSL1:LD A,(USERNO) ; MOVE USER NUMBER INTO FCB. - LD HL,(PARAMS) ; (* UPPER HALF OF FIRST BYTE *) - OR (HL) - LD (HL),A - RET ; AND RETURN (ALL DONE). -; -; FUNCTION TO RETURN THE CURRENT CP/M VERSION NUMBER. -; -GETVER: LD A,#0x022 ; VERSION 2.2 - JP SETSTAT -; -; FUNCTION TO RESET THE DISK SYSTEM. -; -RSTDSK: LD HL,#0 ; CLEAR WRITE PROTECT STATUS AND LOG - LD (WRTPRT),HL ; IN VECTOR. - LD (LOGIN),HL - XOR A ; SELECT DRIVE 'A'. - LD (ACTIVE),A - LD HL,#TBUFF ; SETUP DEFAULT DMA ADDRESS. - LD (USERDMA),HL - CALL DEFDMA - JP LOGINDRV ; NOW LOG IN DRIVE 'A'. -; -; FUNCTION TO OPEN A SPECIFIED FILE. -; -OPENFIL:CALL CLEARS2 ; CLEAR 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DISK. - JP OPENIT ; AND OPEN THE FILE. -; -; FUNCTION TO CLOSE A SPECIFIED FILE. -; -CLOSEFIL: - CALL AUTOSEL ; SELECT PROPER DISK. - JP CLOSEIT ; AND CLOSE THE FILE. -; -; FUNCTION TO RETURN THE FIRST OCCURENCE OF A SPECIFIED FILE -; NAME. IF THE FIRST BYTE OF THE FCB IS '?' THEN THE NAME WILL -; NOT BE CHECKED (GET THE FIRST ENTRY NO MATTER WHAT). -; -GETFST: LD C,#0 ; PREPARE FOR SPECIAL SEARCH. - EX DE,HL - LD A,(HL) ; IS FIRST BYTE A '?'? - CP #QUESTION - JP Z,GETFST1 ; YES, JUST GET VERY FIRST ENTRY (ZERO LENGTH MATCH). - CALL SETEXT ; GET THE EXTENSION BYTE FROM FCB. - LD A,(HL) ; IS IT '?'? IF YES, THEN WE WANT - CP #QUESTION ; AN ENTRY WITH A SPECIFIC 'S2' BYTE. - CALL NZ,CLEARS2 ; OTHERWISE, LOOK FOR A ZERO 'S2' BYTE. - CALL AUTOSEL ; SELECT PROPER DRIVE. - LD C,#15 ; COMPARE BYTES 0-14 IN FCB (12&13 EXCLUDED). -GETFST1:CALL FINDFST ; FIND AN ENTRY AND THEN MOVE IT INTO - JP MOVEDIR ; THE USERS DMA SPACE. -; -; FUNCTION TO RETURN THE NEXT OCCURENCE OF A FILE NAME. -; -GETNXT: LD HL,(SAVEFCB) ; RESTORE POINTERS. NOTE THAT NO - LD (PARAMS),HL ; OTHER .DBOS CALLS ARE ALLOWED. - CALL AUTOSEL ; NO ERROR WILL BE RETURNED, BUT THE - CALL FINDNXT ; RESULTS WILL BE WRONG. - JP MOVEDIR -; -; FUNCTION TO DELETE A FILE BY NAME. -; -DELFILE:CALL AUTOSEL ; SELECT PROPER DRIVE. - CALL ERAFILE ; ERASE THE FILE. - JP STSTATUS ; SET STATUS AND RETURN. -; -; FUNCTION TO EXECUTE A S.EQUENTIAL READ OF THE SPECIFIED -; RECORD NUMBER. -; -READSEQ:CALL AUTOSEL ; SELECT PROPER DRIVE THEN READ. - JP RDSEQ -; -; FUNCTION TO WRITE THE NET S.EQUENTIAL RECORD. -; -WRTSEQ: CALL AUTOSEL ; SELECT PROPER DRIVE THEN WRITE. - JP WTSEQ -; -; CREATE A FILE FUNCTION. -; -FCREATE:CALL CLEARS2 ; CLEAR THE 'S2' BYTE ON ALL CREATES. - CALL AUTOSEL ; SELECT PROPER DRIVE AND GET THE NEXT - JP GETEMPTY ; EMPTY DIRECTORY SPACE. -; -; FUNCTION TO RENAME A FILE. -; -RENFILE:CALL AUTOSEL ; SELECT PROPER DRIVE AND THEN SWITCH - CALL CHGNAMES ; FILE NAMES. - JP STSTATUS -; -; FUNCTION TO RETURN THE LOGIN VECTOR. -; -GETLOG: LD HL,(LOGIN) - JP GETPRM1 -; -; FUNCTION TO RETURN THE CURRENT DISK ASSIGNMENT. -; -GETCRNT:LD A,(ACTIVE) - JP SETSTAT -; -; FUNCTION TO SET THE DMA ADDRESS. -; -PUTDMA: EX DE,HL - LD (USERDMA),HL ; SAVE IN OUR SPACE AND THEN GET TO - JP DEFDMA ; THE BIOS WITH THIS ALSO. -; -; FUNCTION TO RETURN THE ALLOCATION VECTOR. -; -GETALOC:LD HL,(ALOCVECT) - JP GETPRM1 -; -; FUNCTION TO RETURN THE READ-ONLY STATUS VECTOR. -; -GETROV: LD HL,(WRTPRT) - JP GETPRM1 -; -; FUNCTION TO SET THE FILE ATTRIBUTES (READ-ONLY, SYSTEM). -; -SETATTR:CALL AUTOSEL ; SELECT PROPER DRIVE THEN SAVE ATTRIBUTES. - CALL SAVEATTR - JP STSTATUS -; -; FUNCTION TO RETURN THE ADDRESS OF THE DISK PARAMETER BLOCK -; FOR THE CURRENT DRIVE. -; -GETPARM:LD HL,(DISKPB) -GETPRM1:LD (STATUS),HL - RET -; -; FUNCTION TO GET OR SET THE USER NUMBER. IF (E) WAS (FF) -; THEN THIS IS A R.EQUEST TO RETURN THE CURRENT USER NUMBER. -; ELSE SET THE USER NUMBER FROM (E). -; -GETUSER:LD A,(EPARAM) ; GET PARAMETER. - CP #0x0FF ; GET USER NUMBER? - JP NZ,SETUSER - LD A,(USERNO) ; YES, JUST DO IT. - JP SETSTAT -SETUSER:AND #0x1F ; NO, WE SHOULD SET IT INSTEAD. KEEP LOW - LD (USERNO),A ; BITS (0-4) ONLY. - RET -; -; FUNCTION TO READ A RANDOM RECORD FROM A FILE. -; -RDRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND READ. - JP READRAN -; -; FUNCTION TO COMPUTE THE FILE SIZE FOR RANDOM FILES. -; -WTRANDOM: - CALL AUTOSEL ; SELECT PROPER DRIVE AND WRITE. - JP WRITERAN -; -; FUNCTION TO COMPUTE THE SIZE OF A RANDOM FILE. -; -FILESIZE: - CALL AUTOSEL ; SELECT PROPER DRIVE AND CHECK FILE LENGTH - JP RANSIZE -; -; FUNCTION #37. THIS ALLOWS A PROGRAM TO LOG OFF ANY DRIVES. -; ON ENTRY, SET (DE) TO CONTAIN A WORD WITH BITS SET FOR THOSE -; DRIVES THAT ARE TO BE LOGGED OFF. THE LOG-IN VECTOR AND THE -; WRITE PROTECT VECTOR WILL BE UPDATED. THIS MUST BE A M/PM -; SPECIAL FUNCTION. -; -LOGOFF: LD HL,(PARAMS) ; GET DRIVES TO LOG OFF. - LD A,L ; FOR EACH BIT THAT IS SET, WE WANT - CPL ; TO CLEAR THAT BIT IN (LOGIN) - LD E,A ; AND (WRTPRT). - LD A,H - CPL - LD HL,(LOGIN) ; RESET THE LOGIN VECTOR. - AND H - LD D,A - LD A,L - AND E - LD E,A - LD HL,(WRTPRT) - EX DE,HL - LD (LOGIN),HL ; AND SAVE. - LD A,L ; NOW DO THE WRITE PROTECT VECTOR. - AND E - LD L,A - LD A,H - AND D - LD H,A - LD (WRTPRT),HL ; AND SAVE. ALL DONE. - RET -; -; GET HERE TO RETURN TO THE USER. -; -GOBACK: LD A,(AUTO) ; WAS AUTO SELECT ACTIVATED? - OR A - JP Z,GOBACK1 - LD HL,(PARAMS) ; YES, BUT WAS A CHANGE MADE? - LD (HL),#0 ; (* RESET FIRST BYTE OF FCB *) - LD A,(AUTOFLAG) - OR A - JP Z,GOBACK1 - LD (HL),A ; YES, RESET FIRST BYTE PROPERLY. - LD A,(OLDDRV) ; AND GET THE OLD DRIVE AND SELECT IT. - LD (EPARAM),A - CALL SETDSK -GOBACK1:LD HL,(USRSTACK) ; RESET THE USERS STACK POINTER. - LD SP,HL - LD HL,(STATUS) ; GET RETURN STATUS. - LD A,L ; FORCE VERSION 1.4 COMPATABILITY. - LD B,H - RET ; AND GO BACK TO USER. -; -; FUNCTION #40. THIS IS A SPECIAL ENTRY TO DO RANDOM I/O. -; FOR THE CASE WHERE WE ARE WRITING TO UNUSED DISK SPACE, THIS -; SPACE WILL BE ZEROED OUT FIRST. THIS MUST BE A M/PM SPECIAL -; PURPOSE FUNCTION, BECAUSE WHY WOULD ANY NORMAL PROGRAM EVEN -; CARE ABOUT THE PREVIOUS CONTENTS OF A SECTOR ABOUT TO BE -; WRITTEN OVER. -; -WTSPECL:CALL AUTOSEL ; SELECT PROPER DRIVE. - LD A,#2 ; USE SPECIAL WRITE MODE. - LD (MODE),A - LD C,#0 ; SET WRITE INDICATOR. - CALL POSITN1 ; POSITION THE FILE. - CALL Z,WTSEQ1 ; AND WRITE (IF NO ERRORS). - RET -; -;************************************************************** -;* -;* BDOS DATA STORAGE POOL. -;* -;************************************************************** -; -EMPTYFCB: - .DB 0x0E5 ; EMPTY DIRECTORY SEGMENT INDICATOR. -WRTPRT: .DW 0 ; WRITE PROTECT STATUS FOR ALL 16 DRIVES. -LOGIN: .DW 0 ; DRIVE ACTIVE WORD (1 BIT PER DRIVE). -USERDMA:.DW 0x80 ; USER'S DMA ADDRESS (DEFAULTS TO 80H). -; -; SCRATCH AREAS FROM PARAMETER BLOCK. -; -SCRATCH1: - .DW 0 ; RELATIVE POSITION WITHIN DIR SEGMENT FOR FILE (0-3). -SCRATCH2: - .DW 0 ; LAST SELECTED TRACK NUMBER. -SCRATCH3: - .DW 0 ; LAST SELECTED SECTOR NUMBER. -; -; DISK STORAGE AREAS FROM PARAMETER BLOCK. -; -DIRBUF: .DW 0 ; ADDRESS OF DIRECTORY BUFFER TO USE. -DISKPB: .DW 0 ; CONTAINS ADDRESS OF DISK PARAMETER BLOCK. -CHKVECT:.DW 0 ; ADDRESS OF CHECK VECTOR. -ALOCVECT: - .DW 0 ; ADDRESS OF ALLOCATION VECTOR (BIT MAP). -; -; PARAMETER BLOCK RETURNED FROM THE BIOS. -; -SECTORS:.DW 0 ; SECTORS PER TRACK FROM BIOS. -BLKSHFT:.DB 0 ; BLOCK SHIFT. -BLKMASK:.DB 0 ; BLOCK MASK. -EXTMASK:.DB 0 ; EXTENT MASK. -DSKSIZE:.DW 0 ; DISK SIZE FROM BIOS (NUMBER OF BLOCKS-1). -DIRSIZE:.DW 0 ; DIRECTORY SIZE. -ALLOC0: .DW 0 ; STORAGE FOR FIRST BYTES OF BIT MAP (DIR SPACE USED). -ALLOC1: .DW 0 -OFFSET: .DW 0 ; FIRST USABLE TRACK NUMBER. -XLATE: .DW 0 ; SECTOR TRANSLATION TABLE ADDRESS. -; -; -CLOSEFLG: - .DB 0 ; CLOSE FLAG (=0FFH IS EXTENT WRITTEN OK). -R.DWRTFLG: - .DB 0 ; READ/WRITE FLAG (0FFH=READ, 0=WRITE). -FNDSTAT:.DB 0 ; FILENAME FOUND STATUS (0=FOUND FIRST ENTRY). -MODE: .DB 0 ; I/O MODE SELECT (0=RANDOM, 1=S.EQUENTIAL, 2=SPECIAL RANDOM). -EPARAM: .DB 0 ; STORAGE FOR REGISTER (E) ON ENTRY TO BDOS. -RELBLOCK: - .DB 0 ; RELATIVE POSITION WITHIN FCB OF BLOCK NUMBER WRITTEN. -COUNTER:.DB 0 ; BYTE COUNTER FOR DIRECTORY NAME SEARCHES. -SAVEFCB:.DW 0,0 ; SAVE SPACE FOR ADDRESS OF FCB (FOR DIRECTORY SEARCHES). -BIGDISK:.DB 0 ; IF =0 THEN DISK IS > 256 BLOCKS LONG. -AUTO: .DB 0 ; IF NON-ZERO, THEN AUTO SELECT ACTIVATED. -OLDDRV: .DB 0 ; ON AUTO SELECT, STORAGE FOR PREVIOUS DRIVE. -AUTOFLAG: - .DB 0 ; IF NON-ZERO, THEN AUTO SELECT CHANGED DRIVES. -SAVNXT: .DB 0 ; STORAGE FOR NEXT RECORD NUMBER TO ACCESS. -SAVEXT: .DB 0 ; STORAGE FOR EXTENT NUMBER OF FILE. -SAVNREC:.DW 0 ; STORAGE FOR NUMBER OF RECORDS IN FILE. -BLKNMBR:.DW 0 ; BLOCK NUMBER (PHYSICAL SECTOR) USED WITHIN A FILE OR LOGICAL SEC -LOGSECT:.DW 0 ; STARTING LOGICAL (128 BYTE) SECTOR OF BLOCK (PHYSICAL SECTOR). -FCBPOS: .DB 0 ; RELATIVE POSITION WITHIN BUFFER FOR FCB OF FILE OF INTEREST. -FILEPOS:.DW 0 ; FILES POSITION WITHIN DIRECTORY (0 TO MAX ENTRIES -1). -; -; DISK DIRECTORY BUFFER CHECKSUM BYTES. ONE FOR EACH OF THE -; 16 POSSIBLE DRIVES. -; -CKSUMTBL: - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -;************************************************************** -;* -;* B I O S J U M P T A B L E -;* -;************************************************************** -; - -BIOS = BIOSO ;BIOS ORIGIN -; -BOOT = BIOS ;(BOOT) Cold boot entry -WBOOT = BIOS+3 ;Warm boot entry -CONST = BIOS+6 ;Console status -CONIN = BIOS+9 ;Console char in -CONOUT = BIOS+12 ;Console char out -LIST = BIOS+15 ;List char out -PUNCH = BIOS+18 ;Punch char out -READER = BIOS+21 ;Reader char in -HOME = BIOS+24 ;Home disk -SELDSK = BIOS+27 ;Select disk -SETTRK = BIOS+30 ;Set disk track addr -SETSEC = BIOS+33 ;Set disk sector addr -SETDMA = BIOS+36 ;Set DMA buffer addr -READ = BIOS+39 ;Read sector -WRITE = BIOS+42 ;Write sector -SECTRN = BIOS+48 ;Sector translation routine -; -;dwg; .IF ENDFIL -;dwg; .ORG BDOSO+0DFFH -;dwg; .DB 55H -;dwg; .ENDIF - -;dwg; .END - -_bdos_end:: - .area _CODE - .area _CABS diff --git a/branches/s100/cpurom/src/cbios.s b/branches/s100/cpurom/src/cbios.s deleted file mode 100644 index a909bd64..00000000 --- a/branches/s100/cpurom/src/cbios.s +++ /dev/null @@ -1,2733 +0,0 @@ - .title cbios.s derived from cbios.asm - .sbttl by Douglas Goodall for N8VEM use '11 - - .module cbios - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _cbios -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - -; .area _CODE - .area _CBIOS - -_cbios_start:: -_cbios: - -; CBIOS FOR N8VEM -; -; Supports: Floppy, IDE HDD, ATAPI ZIP, RAM & ROM DRIVES, on board 16550, DSKY & VDU CARD -; -; BY ANDREW LYNCH, WITH INPUT FROM MANY SOURCES -; -; DATA CONSTANTS -;__________________________________________________________________________________________________ -FALSE = 0 -TRUE = 1 - -; LIST OF CONDITIONAL ASSEMBLY INSTRUCTIONS - -CONDIDESOFT = TRUE ; IF NO IDE DRIVE, HAS A SIGNIFICANT DELAY ON SOFT BOOT (TRUE) OR QUICK (FALSE) -CONDSHORTMSG = TRUE ; TRUE FOR ORIGINAL WARM BOOT SIGNON, FALSE FOR SHORTER ONE WITH LESS -CONDSUPERSUB = TRUE ; TRUE FOR NO SUPERSUB AUTOEXEC, FALSE TO RUN SUPERSUB AUTOEXEC -CONDABONLY = TRUE ; TRUE FOR ORIGINAL, FALSE TO ONLY HAVE DRIVE A AND B - -CONDUSEVDU = FALSE ; TRUE FOR USE VDU CARD, FALSE TO USE SERIAL PORT (FOR CONSOLE) -CONDUSEFLOPPY = TRUE ; TRUE FOR USE FLOPPY, FALSE FOR NO FLOPPY DRIVE -COND144FLOPPY = TRUE ; TRUE FOR 1.44Mb FLOPPY ON DRIVE G: -CONDUSEATAPI = FALSE ; TRUE FOR USE ZIP DISK, FALSE FOR NO ZIP DISK -CONDUSEDSKY = FALSE ; TRUE FOR USE DSKY, FALSE FOR NO DSKY - -; POINTERS TO VDU ROUTINES IN HIGH ROM BANK (NOT NEEDED IF NOT USING VDU CARD) - -VDU_INIT = 0x0100 ; VECTOR TO VDU INIT CODE -IS_KBHIT = 0x0395 ; VECTOR TO KB HIT CODE -GET_KEY = 0x039C ; VECTOR TO GET KEY CODE -CHARIN = 0x011B ; VECTOR TO CHARIN CODE -PR_OUTCHAR = 0x0CD6 ; VECTOR TO PRINTER CODE - -; -MSIZE = 59 ;CP/M VERSION MEMORY SIZE IN KILOBYTES -; -; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS -; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT) -; -BIAS = (MSIZE-20)*1024 ; -CCP = 0x3400+BIAS ; BASE OF CCP -BDOS = CCP+0x806 ; BASE OF BDOS -BIOS = CCP+0x1600 ; BASE OF BIOS -CDISK = 4 ; CURRENT DISK NUMBER 0=A,...,15=P -IOBYTE = 3 ; I/O DEFINITION BYTE. - -END = 0x0FF -CR = 0x0D -LF = 0x0A - -; TEST PROTOTYPE SPECIFIC HARDWARE IO PORT ADDRESSES AND MEMORY LOCATIONS - -UART = 0x68 ; BASE IO ADDRESS OF UART -MPCL_RAM = 0x78 ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH -MPCL_ROM = 0x7C ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH - -ROMSTART_CPM= 0x00A00 ; WHERE THE CCP+BDOS+BIOS IS STORED IN ROM -RAMTARG_CPM= 0x0D000 ; WHERE THE CCP+BDOS+BIOS STARTS IN RAM (ENTRY POINT) -MOVSIZ_CPM= 0x02BFF ; CCP, BDOS -CCPSIZ_CPM= 0x00800 ; CCP 0800h BYTES IN LENGTH - -; IDE REGISTER IO PORT ; FUNCTION -IDELO = 0x20 ; DATA PORT (LOW BYTE) -IDEERR = 0x21 ; READ: ERROR REGISTER; WRITE: PRECOMP -IDESECTC = 0x22 ; SECTOR COUNT -IDESECTN = 0x23 ; SECTOR NUMBER -IDECYLLO = 0x24 ; CYLINDER LOW -IDECYLHI = 0x25 ; CYLINDER HIGH -IDEHEAD = 0x26 ; DRIVE/HEAD -IDESTTS = 0x27 ; READ: STATUS; WRITE: COMMAND -IDEHI = 0x28 ; DATA PORT (HIGH BYTE) -IDECTRL = 0x2E ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL -IDEADDR = 0x2F ; DRIVE ADDRESS (READ ONLY) -FMSR = 0x36 ; ADDRESS OF MAIN STATUS REGISTER -FDATA = 0x37 ; FLOPPY DATA REGISTER -FLATCH = 0x3A ; FLOPPY CONFIGURATION LATCH -FDMA = 0x3C ; PSEUDO DMA ADDRESS -; -; FDC CONFIGURATION LATCH OUTPUT BIT PATTERNS -MOTOR = 0b00000000 ; BIT PATTERN IN LATCH FOR MOTOR CONTROL (ON) -TERMCN = 0b00000001 ; BIT PATTERN IN LATCH TO WRITE A TC STROBE -RESETL = 0b00000010 ; BIT PATTERN IN LATCH TO RESET ALL BITS -MINI = 0b00000100 ; BIT PATTERN IN LATCH TO SET MINI MODE FDC9229 LOW DENS=1, HIGH DENS=0 -PRECOMP = 0b00100000 ; BIT PATTERN IN LATCH TO SET WRITE PRECOMP 125 NS: -FDDENSITY = 0b01000000 ; BIT PATTERN IN LATCH TO FLOPPY LOW DENSITY (HIGH IS 0) -FDREADY = 0b10000000 ; BIT PATTERN IN LATCH TO FLOPPY READY (P-34): -; -; PIO 82C55 I/O IS DECODED TO PORT 60-67 -PORTA = 0x60 ; PORT A -PORTB = 0x61 ; PORT B -PORTC = 0x62 ; PORT C -PIOCONT = 0x63 ; PIO CONTROL PORT - - -;dwg; .ORG BIOS - -;__________________________________________________________________________________________________ -; -; CP/M JUMP VECTOR TABLE FOR INDIVIDUAL SUBROUTINES -;__________________________________________________________________________________________________ -; - JP BOOT ; COLD START -WBOOTE: JP WBOOT ; WARM START - JP CONST ; CONSOLE STATUS - JP CONIN ; CONSOLE CHARACTER IN - JP CONOUT ; CONSOLE CHARACTER OUT - JP LIST ; LIST CHARACTER OUT (NULL ROUTINE) - JP PUNCH ; PUNCH CHARACTER OUT (NULL ROUTINE) - JP READER ; READER CHARACTER OUT (NULL ROUTINE) - JP HOME ; MOVE HEAD TO HOME POSITION - JP SELDSK ; SELECT DISK - JP SETTRK ; SET TRACK NUMBER - JP SETSEC ; SET SECTOR NUMBER - JP SETDMA ; SET DMA ADDRESS - JP READ ; READ DISK - JP WRITE ; WRITE DISK - JP LISTST ; RETURN LIST STATUS (NULL ROUTINE) - JP SECTRN ; SECTOR TRANSLATE - -;__________________________________________________________________________________________________ -; -; FIXED DATA TABLES FOR ALL DRIVES -; 0= FLOPPY DISK OR RAM DISK, 1=RAM DISK, 2=IDE, 3=ATAPI OR RAM DISK, 4=HDPART4 -; 5= 1MB ROM DISK,6=32K ROM DISK -; -; NOTE: The RAM disk area is used as a substitute if the Floppy and/or ZIP drives are not enabled -; in the sustem. This RAM disk is the same "disk" as drive B. -; -;__________________________________________________________________________________________________ - -; DISK PARAMETER HEADER FOR DISK 00 -DPBASE: - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK1 - .DW CHK01,ALL01 - -; DISK PARAMETER HEADER FOR DISK 01 -.IF CONDUSEFLOPPY - .IF COND144FLOPPY - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK7 ; FOR 1.44M FLOPPIES - .DW CHK07,ALL07 - .ELSE - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK0 - .DW CHK00,ALL00 - .ENDIF -.ELSE - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK1 - .DW CHK01,ALL01 -.ENDIF -; DISK PARAMETER HEADER FOR DISK 02 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK2 - .DW CHK02,ALL02 - - .IF CONDUSEATAPI -; DISK PARAMETER HEADER FOR DISK 03 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK3 - .DW CHK03,ALL03 - .ELSE - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK1 - .DW CHK01,ALL01 - .ENDIF - -; DISK PARAMETER HEADER FOR DISK 04 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK4 - .DW CHK04,ALL04 - -; DISK PARAMETER HEADER FOR DISK 05 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK5 - .DW CHK05,ALL05 - -; DISK PARAMETER HEADER FOR DISK 06 - .DW 0000,0000 - .DW 0000,0000 - .DW DIRBF,DPBLK6 - .DW CHK06,ALL06 -; - -DPBLK0: ; DISK PARAMETER BLOCK (FLOPPY DISK 720KB) -SPT_0: .DW 36 ; 36 SECTORS OF 128 BYTES PER 4.5K TRACK -BSH_0: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_0: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_0: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_0: .DW 350 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_0: .DW 127 ; NUMBER OF DIRECTORY ENTRIES -AL0_0: .DB 0b11000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_0: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_0: .DW 32 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_0: .DW 4 ; FIRST 4 TRACKS TRACKS RESERVED (18K FOR SYSTEM) - ; -DPBLK1: ; DISK PARAMETER BLOCK (RAMDISK 512K, 448K USABLE) -SPT_1: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_1: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_1: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_1: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_1: .DW 225 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_1: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_1: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_1: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_1: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_1: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF RAM] - ; -DPBLK2: ; DISK PARAMETER BLOCK (IDE HARD DISK 8MB) -SPT_2: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_2: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_2: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_2: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_2: .DW 2017 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_2: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_2: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_2: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_2: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_2: .DW 0x03F1 ; TRACKS (32K) RESERVED FOR SYSTEM AND OTHER PARTITIONS - ; -DPBLK3: ; DISK PARAMETER BLOCK (ATAPI DRIVE 8MB) -SPT_3: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_3: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_3: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_3: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_3: .DW 2017 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_3: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_3: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_3: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_3: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_3: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - ; -DPBLK4: ; DISK PARAMETER BLOCK (IDE HARD DISK 1024K) -SPT_4: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_4: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_4: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_4: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_4: .DW 497 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_4: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_4: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_4: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_4: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_4: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF PARTITION] - ; -DPBLK5: ; DISK PARAMETER BLOCK (ROMDISK 1MB) -SPT_5: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_5: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_5: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_5: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_5: .DW 511 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS +1 =DRIVE SIZE -DRM_5: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_5: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_5: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_5: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_5: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF ROM] - ; -DPBLK6: ; DISK PARAMETER BLOCK (ROMDISK 32KB) -SPT_6: .DW 16 ; 16 SECTORS OF 128 BYTES PER 2K TRACK -BSH_6: .DB 3 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_6: .DB 7 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_6: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_6: .DW 31 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_6: .DW 31 ; NUMBER OF DIRECTORY ENTRIES -AL0_6: .DB 0b10000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_6: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_6: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_6: .DW 10 ; FIRST 10 TRACKS TRACKS RESERVED (20K FOR SYSTEM) - ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR -DPBLK7: ; DISK PARAMETER BLOCK FLOPPY 1.44M -SPT_7: .DW 72 ; 16 SECTORS OF 128 BYTES PER 2K TRACK -BSH_7: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_7: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_7: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_7: .DW 710 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_7: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_7: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_7: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED - -CKS_7: .DW 32 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_7: .DW 2 ; FIRST 10 TRACKS TRACKS RESERVED (20K FOR SYSTEM) - ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR - ; - ; IMPORTANT NOTE: TRACKS 00h - 0AH OF 2K BYTES - ; EACH ARE MARKED WITH THE OFF_6 SET TO 5 AS - ; SYSTEM TRACKS USABLE ROM DRIVE SPACE - ; STARTING AFTER THE TENTH TRACK (IE, TRACK 0AH) - ; MOST LIKELY FIX TO THIS IS PLACING A DUMMY - ; FIRST 20K ROM CONTAINS THE ROM LOADER, MONITOR, - ; CCP, BDOS, BIOS, ETC (10 TRACKS * 2K EACH) -;__________________________________________________________________________________________________ -; -; END OF FIXED CP/M TABLES -; -; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION -;__________________________________________________________________________________________________ - - -;___BOOT___________________________________________________________________________________________ -BOOT: ; SIMPLEST CASE IS TO JUST PERFORM PARAMETER INITIALIZATION - ; - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - ; - LD A,#0b10000001 ; SWITCH IN FIRST 32K LOWER PAGE (FIRST TRACK) - OUT (MPCL_RAM),A ; - ; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA - ; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK) - LD HL,#0000 ; STARTING MEMORY ADDRESS OF TRACK 1, SECTOR 0 IN HL - LD BC,#0x1FFF ; 8K OF DIRECTORY SECTORS RESERVED (LENGTH IN BC) - LD A,#0x0E5 ; INITIALIZING VALUE IN A - LD E,L ; - LD D,H ; - INC DE ; - LD (HL),A ; - LDIR ; - ; - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - LD A,#0 ; ENSURE LOWEST RAM PAGE SELECTED - OUT (MPCL_RAM),A ; BRING IN LOWEST 32K RAM PAGE - ; - XOR A ; ZERO IN THE ACCUM - LD (IOBYTE),A ; CLEAR THE IOBYTE - LD (CDISK),A ; SELECT DISK 0 - ; - CALL IDE_SOFT_RESET ; RESET THE IDE HARD DISK - ; - ; - JP GOCPM ; INITIALIZE AND GO TO CP/M - ; -; -;___WBOOT__________________________________________________________________________________________ -WBOOT: ; SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED - ; WITH A ROMDISK WE SELECT THE ROM AND THE CORRECT PAGE [0] - ; THEN COPY THE CP/M IMAGE (CCP, BDOS, BIOS, MONITOR) TO HIGH RAM - ; LOAD ADDRESS - ; FOR Z80 IT LOOKS LIKE THIS . USING 8080 NEMONICS - ; - DI ; DISABLE INTERRUPT - LD SP,#0x80 ; USE SPACE BELOW BUFFER FOR STACK - IM 1 ; SET INTERRUPT MODE 1 - ; - XOR A ; CHEAP ZERO IN ACC - OUT (MPCL_ROM),A ; SEND 0 TO ROM MAP PORT (SWITCH IN LOWER 32K ROM PAGE) - ; - XOR A ; CHEAP ZERO IN ACC - OUT (MPCL_RAM),A ; SEND 0 TO RAM MAP PORT (SELECT LOWEST RAM PAGE) - ; - LD HL,#ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) - LD DE,#RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) - LD BC,#CCPSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM - LDIR ; - ; - ; -;;;;; EI ; ENABLE INTERRUPTS - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - XOR A ; CHEAP ZERO IN ACC - OUT (MPCL_RAM),A ; SEND 0 TO RAM MAP PORT (SELECT LOWEST RAM PAGE) - ; - CALL IDE_SOFT_RESET ; RESET THE IDE HARD DISK - ; - .IF CONDSUPERSUB ; - ; DO NOTHING FOR ORIGINAL CODE - .ELSE ; - ; CLEAR THE AUTOSUB BUFFER, DO ON A WARM BOOT - XOR A ; - LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH - .ENDIF ; - ; FALL THROUGH TO GOCPM ROUTINE -; -; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M -; -;___GOCPM__________________________________________________________________________________________ -GOCPM: - ; CPU RESET HANDLER - LD A,#0x0C3 ; C3 IS A JMP INSTRUCTION - LD (0),A ; FOR JMP TO WBOOT - LD HL,#WBOOTE ; WBOOT ENTRY POINT - LD (1),HL ; SET ADDRESS FIELD FOR JMP AT 0 - ; - ; CPU INTERRUPT HANDLER - LD A,#0x0C3 ; C3 IS A JMP INSTRUCTION - LD (0x0038),A ; FOR JMP TO WBOOT - LD HL,#WBOOTE ; WBOOT ENTRY POINT - LD (1),HL ; SET ADDRESS FIELD FOR JMP AT 0 - ; - LD (5),A ; FOR JMP TO BDOS - LD HL,#BDOS ; BDOS ENTRY POINT - LD (6),HL ; ADDRESS FIELD OF JUMP AT 5 TO BDOS - ; - LD BC,#0x80 ; DEFAULT DMA ADDRESS IS 80H - CALL SETDMA ; - ; - .IF CONDUSEFLOPPY ; - CALL SETUPDRIVE ; SETUP FLOPPY PARAMETERS - .ENDIF ; - ; - .IF CONDUSEVDU ; - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL VDU_INIT ; - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) -;;;;; EI ; ENABLE INTERRUPTS - .ENDIF ; - LD HL,#TXT_STARTUP_MSG ; PRINT STARTUP MESSAGE - CALL PRTMSG ; - ; - LD A,(CDISK) ; GET CURRENT DISK NUMBER - LD C,A ; SEND TO THE CCP - JP CCP ; GO TO CP/M FOR FURTHER PROCESSING - ; -;__________________________________________________________________________________________________ -; -; ** CONSOLE & PRINTER I/O -- VDU CARD DRIVER INTERFACE -; -;__________________________________________________________________________________________________ - .IF CONDUSEVDU -CONST: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#1FH ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL IS_KBHIT ; CHECK FOR KB HIT - LD C,A ; STORE RESULT - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - LD A,C ; RESTORE RESULT -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET - -CONIN: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL GET_KEY ; GET KEY FROM KEYBOARD - LD C,A ; STORE RESULT - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) - LD A,C ; RESTORE RESULT -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET - -CONOUT: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - LD A,C ; RESTORE CHARACTER - CALL CHARIN ; DISPLAY CHARACTER - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET -LIST: - PUSH HL ; STORE HL - DI ; DISABLE INTERRUPTS - LD A,#0x1F ; SET HIGH ROM PAGE - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - LD A,C ; RESTORE CHARACTER - CALL PR_OUTCHAR ; - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,#0x80 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; - LD A,#0x00 ; CHOOSE HIGHEST RAM PAGE - OUT (MPCL_RAM),A ; SEND 19H TO RAM MAP PORT (SELECT HIGHEST RAM PAGE) -;;;;; EI ; ENABLE INTERRUPTS - POP HL ; RESTORE HL - RET - -;__________________________________________________________________________________________________ -; -; ** CONSOLE I/O -- ON-BOARD 16550 SERIAL INTERFACE -; -;__________________________________________________________________________________________________ - .ELSE -CONST: ; CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT - IN A,(UART + 5) ; READ LINE STATUS REGISTER (UART5 = 068h + $05) - AND #0x01 ; TEST IF DATA IN RECEIVE BUFFER - ; IS THERE A CHAR READY? 0=NO, 1=YES - JP Z,NOT_READY ; - LD A,#0x0FF ; YES, PUT 0FFh IN A AND RETURN -NOT_READY: ; - ; NO, LEAVE 000h IN A AND RETURN - RET ; -CONIN: ; CONSOLE CHARACTER INTO REGISTER A - ; - CALL CONST ; IS A CHAR READY TO BE READ FROM UART? - CP #0 ; - JP Z,CONIN ; NO? TRY AGAIN - IN A,(UART) ; YES? READ THE CHAR FROM THE UART (UART0 = 068h + $00) - ; REGISTER AND PASS BACK TO USER - RET ; - ; -CONOUT: ; CONSOLE CHARACTER OUTPUT FROM REGISTER C - IN A,(UART + 5) ; READ LINE STATUS REGISTER - AND #0x20 ; TEST IF UART IS READY TO SEND - JP Z,CONOUT ; IF NOT REPEAT - ; - LD A,C ; GET TO ACCUMULATOR - OUT (UART),A ; THEN WRITE THE CHAR TO UART (UART0 = 068h + $00) - RET ; - ; -LIST: ;LIST CHARACTER FROM REGISTER C - LD A,C ;CHARACTER TO REGISTER A - RET ;NULL SUBROUTINE - .ENDIF - ; -LISTST: ;RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) - XOR A ;0 IS ALWAYS OK TO RETURN - RET ; - ; - ; -;__________________________________________________________________________________________________ -; -; ** PUNCH & READER I/O -- STUB -; -;__________________________________________________________________________________________________ -PUNCH: ;PUNCH CHARACTER FROM REGISTER C - LD A,C ;CHARACTER TO REGISTER A - RET ;NULL SUBROUTINE - ; -READER: ;READ CHARACTER INTO REGISTER A FROM READER DEVICE - LD A,C ;CHARACTER TO REGISTER A - RET - - -;__________________________________________________________________________________________________ -; -; ** DISK STORAGE I/O -; -;__________________________________________________________________________________________________ -; -; SELECT DISK GIVEN BY REGISTER C -;__________________________________________________________________________________________________ - -SELDSK: LD HL,#0x0000 ; ERROR RETURN CODE - LD A,C ; - .IF CONDABONLY ; - CP #7 ; MUST BE BETWEEN 0 AND 6 - .ELSE ; - CP #2 ; IF NO IDE THEN ONLY DRIVE A AND B FOR THE MINI N8VEM SO 0 OR 1 ONLY - .ENDIF ; - RET NC ; RETURN IF OUT OF RANGE - LD (DISKNO),A ; - ; DISK NUMBER IS IN THE PROPER RANGE - ; COMPUTE PROPER DISK PARAMETER HEADER ADDRESS - LD L,A ; L=DISK NUMBER 0,1,2,3,4 - LD H,#0 ; HIGH ORDER ZERO - ADD HL,HL ; *2 - ADD HL,HL ; *4 - ADD HL,HL ; *8 - ADD HL,HL ; *16 (SIZE OF EACH HEADER) - LD DE,#DPBASE ; - ADD HL,DE ; HL= DPBASE(DISKNO*16) - RET -;__________________________________________________________________________________________________ -HOME: ; MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE - ; TRANSLATE THIS CALL INTO A SETTRK CALL WITH PARAMETER 00 - LD BC,#0 ; SELECT TRACK 0000 -;__________________________________________________________________________________________________ -SETTRK: ; SET TRACK GIVEN BY REGISTER BC - LD H,B ; - LD L,C ; - LD (TRACK),HL ; - RET -;__________________________________________________________________________________________________ -SETSEC: ; SET SECTOR GIVEN BY REGISTER BC - LD H,B ; - LD L,C ; - LD (SECTOR),HL ; - RET ; -;__________________________________________________________________________________________________ -; -; TRANSLATE THE SECTOR GIVEN BY BC USING THE -; TRANSLATE TABLE GIVEN BY DE -; ONLY USED FOR FLOPPIES! FOR ROMDISK/RAMDISK/IDE/ATAPI IT'S 1:1 -; DO THE NEXT ROUTINE IS A NULL (RETURNS THE SAME) -;__________________________________________________________________________________________________ -SECTRN: - LD H,B ; - LD L,C ; - RET ; -;__________________________________________________________________________________________________ -SETDMA: ; SET DMA ADDRESS GIVEN BY REGISTERS B AND C - LD L,C ; LOW ORDER ADDRESS - LD H,B ; HIGH ORDER ADDRESS - LD (DMAAD),HL ; SAVE THE ADDRESS - RET -;________________________________________________________________________________________________________ -; DISK DRIVERS . -; -; DRIVER NEEDS TO DO SEVERAL THINGS FOR ROM AND RAM DISKS -; - INTERRUPTS ARE NOT ALLOWED DURING LOW RAM/ROM ACCESS (DISABLE!) -; -TRANSLATE TRACK AND SECTOR INTO A POINTER TO WHERE THE 128 BYTE -; SECTOR BEGINS IN THE RAM/ROM -; -TRANSLATE THE DRIVE INTO A RAM/ROM SELECT, COMBINE WITH TRACK ADDRESS -; AND SEND TO THE MAP PORT -; -COPY 128 BYTE FROM OR TO THE ROM/RAMDISK AND MEMORY POINTED TO BY THE DMA -; ADDRESS PREVIOUSLY STORED -; -RESTORE MAP PORT TO PRIOR CONDITION BEFOR READ/WRITE -; -; - FIRST TRICK IS THAT WE MADE SECTORS 256 AS 256*128=32768 SO WE COPY -; THE LOW SECTOR ADDRESS TO THE LOW BYTE OF THE HL REGISTER AND THEN -; MULTIPLY BY 128 THIS RESULTS IN THE STARTING ADDRESS IN THE RAM OR ROM -; (0000 -> 7F80H) 32K PAGE -; -; - TRICK TWO IS THE TRACK ADDRESS EQUALS THE 32K PAGE ADDRESS AND IS A -; DIRECT SELECT THAT CAN BE COPIED TO THE MAP PORT D0 THROUGH D5 D7 -; SELECTS THE DRIVE (ROM OR RAM) -; THAT MEANS THE LOW BYTE OF TRACK CONTAINS THE D0-D5 VALUE AND -; DISKNO HAS THE DRIVE SELECTED WE FIRST COPY DISKNO TO ACC -; AND RIGHTSHIFT IT TO PLACE THAT IN BIT 7, WE THEN ADD THE LOW BYTE OF -; TRACK TO ACC AND THEN SEND THAT TO THE MAP PORT -; -; NOTE 1: A WRITE TO ROM SHOULD BE FLAGGED AS AN ERROR -; NOTE 2: RAM MUST START AS A "FORMATTED DISK" IF BATTERY BACKED UP -; IT'S A DO ONCE AT COLD COLD START IF NOT BATTERY BACKED U -; IT WILL HAVE TO BE DONE EVERY TIME THE SYSTEM IS POWERED -; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA -; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK) -; IT COULD BE DONE AS A SIMPLE UTILITY PROGRAM STORED IN ROMD -; OR ANYTIME COLBOOT IS CALLED(LESS DESIREABLE) -; -; -WE NOW CAN COPY TO OR FROM AS CORRECT FOR THE DEVICE 128 BYTES (SECTOR) -; TO OR FROM THE DMA ADDRESS ALMOST! SINCE ROM OR RAM IS BEING PAGED -; WE HAVE TO COPY ANYTHING DETINED FOR BELOW 8000H TO A TEMP BUFFER THEN -; HANDLE THE PAGING -; -; -; - LAST STEP IS TO RESTORE THE MAP PORT TO POINT TO THE RAM (TRACK 0) SO T -; MEMORY MAP IS ALL RAM AGAIN AND NOT POINTING INTO THE DATA AREAS OR THE -; SINCE THE RAM 0TH PAGE IS NOMINALLY THE LOW 32K OF RAM IN THE SYSTEM WE -; SEND A SIMPLE MVI A,80H ; OUT MPCL_ROM ; MVI A,00H ; OUT MPCL_RAM -; -; - THE READ OR WRITE OPERATION IS DONE -; -; READ DISK -; USES DE,DL, BC, ACC FLAGS -; Z80 COULD USE BLOCK MOVE [LDIR] BUT WRITTEN IN 8080 -;________________________________________________________________________________________________________ - -;__READ__________________________________________________________________________________________________ -; -; PERFORM CP/M SECTOR READ -;________________________________________________________________________________________________________ -READ: - DI ; DISABLE INTERRUPTS - LD A,(DISKNO) ; GET DRIVE - CP #0x01 ; "B" - .IF CONDUSEFLOPPY - JP Z,READ_FLPY_DSK ; READ FLOPPY - .ELSE - JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - .ENDIF - CP #0 ; "B" - JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - CP #2 ; "C" - JP Z,READ_IDE ; READ FROM 8 MB IDE HARD DISK - CP #3 ; "D" - .IF CONDUSEATAPI - JP Z,READ_ATAPI ; READ FROM 8 MB ATAPI - .ELSE - JP Z,READ_RAM_DISK ; READ FROM 448K RAM DISK - .ENDIF - - CP #4 ; "E" - JP Z,READ_HDPART4 ; READ FROM 1 MB IDE HARD DISK, PARTITION 4 ** future use - CP #5 ; "F" - JP Z,READ_RAM_DISK ; READ FROM 1M ROM DISK (UTILIZES SAME - ; ROUTINES AS RAM_DISK - ; "G" - ; READ FROM 22K EEPROM DISK , SO FALL THROUGH - -;___READ_EEPROM_DISK_____________________________________________________________________________________ -; -; READ EEPROM DISK -;________________________________________________________________________________________________________ -READ_EEPROM_DISK: - ; - ; IF ROM, MAP TRACK/SECTOR TO VIRTUAL TRACK/SECTOR - ; HANDLE READING FROM ROM HERE - ; - ; PURPOSE OF THIS ROUTINE IS TO MAP 32K ROM PART - ; TRACK/SECTOR MAP (2K TRACK SIZE MADE OF 16 128 - ; BYTE SECTORS EACH) ONTO WHAT THE RAM/ROM SECTOR - ; READ ROUTINES ARE EXPECTING (32K TRACK SIZE MADE - ; OF 256 128 BYTE SECTORS EACH) THE ROUTINE - ; CONVERTS 4 BIT TRACK # AND 4 BIT SECTOR # - ; INTO A VIRTUAL 1 TRACK, 256 SECTOR ACCESS - LD HL,(TRACK) ; TRACK # IS UPPER 4 BITS OF SECTOR ADDRESS - ADD HL,HL ; SHIFT BITS LEFT 1 (*2) - ADD HL,HL ; SHIFT BITS LEFT 1 (*4) - ADD HL,HL ; SHIFT BITS LEFT 1 (*8) - ADD HL,HL ; SHIFT BITS LEFT 1 (*16) - LD B,H ; PUT UPPER 4 BITS OF SECTOR ADDRESS IN BC - LD C,L ; (B IS UPPER BYTE AND C IS LOWER BYTE) - ; BC NOW CONTAINS THE UPDATED TRACK # - LD HL,(SECTOR) ; SECTOR # IS LOWER 4 BITS OF SECTOR ADDRESS - ADD HL,BC ; VIRTUAL SECTOR = (UPDATED TRACK #) + SECTOR # - LD (PSECTOR),HL ; STORE VIRTUAL SECTOR # - ; NOW CONTINUE READING ROM WITH REGULAR RAM - ; SETUP FOR READ OF RAM OR ROM DISK - LD HL,(PSECTOR) ; - ADD HL,HL ; SHIFT BITS LEFT 1 (*2) - ADD HL,HL ; SHIFT BITS LEFT 1 (*4) - ADD HL,HL ; SHIFT BITS LEFT 1 (*8) - ADD HL,HL ; SHIFT BITS LEFT 1 (*16) - ADD HL,HL ; SHIFT BITS LEFT 1 (*32) - ADD HL,HL ; SHIFT BITS LEFT 1 (*64) - ADD HL,HL ; SHIFT BITS LEFT 1 (*128) - LD (SECST),HL ; SAVE SECTOR STARTING ADDRESS - ; SET PAGER WITH DRIVE (0) AND TRACK (0) - LD A,#0 ; SWITCH IN ROM PAGE - OUT (MPCL_ROM),A ; SEND TO PORT MAPPER - LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,(SECST) ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; - CALL RPAGE ; SET PAGE TO CP/M RAM - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,#SECTOR_BUFFER ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - LD A,#0 ; -;;;;; EI ; RE-ENABLE INTERRUPTS - RET -;___READ_RAM_DISK_________________________________________________________________________________________ -; -; READ RAM DISK -;________________________________________________________________________________________________________ -READ_RAM_DISK: ; - ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,(SECST) ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; MOVE SECTOR TO SECTOR_BUFFER - CALL RPAGE ; SET PAGE TO CP/M RAM - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS ; - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,#SECTOR_BUFFER ; GET ROM/RAM ADDRESS - CALL COPY_CPM_SECTOR ; MOVE SECTOR FROM SECTOR_BUFFER TO DMA AREA - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - LD A,#0 ; -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - -;___TRFLSEC______________________________________________________________________________________________ -; -; TRANSLATE LOGICAL FLOPPY DISK SECTOR TO PHYSICAL SECTOR -; IN: TRACK,SECTOR -; OUT: PTRACK,PSECTOR,SECTOR_INDEX -;________________________________________________________________________________________________________ -TRFLSEC: - LD A,(TRACK) ; LOAD TRACK # (LOW BYTE) - AND #1 ; FILTER OUT HEAD - LD (HEAD),A ; STORE HEAD - LD A,(TRACK) ; SAVE TRACK IN A - SRL A ; REMOVE HEAD BIT - LD (PTRACK),A ; STORE IN TRACK - LD A,(SECTOR) ; LOAD SECTOR # (LOW BYTE) - LD (SECTOR_INDEX),A ; STORE SECTOR IN SECTOR INDEX - SRL A ; - SRL A ; DIVIDE BY 4 (FOR BLOCKING) - LD (PSECTOR),A ; STORE IN SECTOR - LD A,(SECTOR_INDEX) ; FILTER OUT UNWANTED BITS - AND #3 ; - LD (SECTOR_INDEX),A ; - RET - -;___DEBSEC_______________________________________________________________________________________________ -; -; DEBLOCK 512 BYTE SECTOR FOR CP/M -; -;________________________________________________________________________________________________________ -DEBSEC: - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS - LD D,H ; TRANSFER HL REGISTERS TO DE - LD E,L ; - PUSH DE ; STORE DE - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ SECTOR BUFFER - LD HL,#SECTOR_BUFFER ; LOAD HL WITH SECTOR BUFFER ADDRESS - LD A,(SECTOR_INDEX) ; GET THE SECTOR INDEX (CP/M SECTOR OFFSET IN BUFFER) - RRCA ; MOVE BIT 0 TO BIT 7 - RRCA ; DO AGAIN - IN EFFECT MULTIPLY BY 4 - LD D,#0 ; PUT RESULT AS 16 VALUE IN DE, UPPER BYTE IN D IS 000h - LD E,A ; PUT ADDRESS OFFSET IN E - ADD HL,DE ; MULTIPLY BY 2, TOTAL MULTIPLICATION IS X 128 - ADD HL,DE ; CP/M SECTOR STARTING ADDRESS IN IDE HD SECTOR BUFFER - ; COPY CP/M SECTOR TO BDOS DMA ADDRESS BUFFER - POP DE ; RESTORE DE - CALL COPY_CPM_SECTOR ; - RET - -;___BLKSEC_______________________________________________________________________________________________ -; -; BLOCK 512 BYTE SECTOR FOR CP/M -; -;________________________________________________________________________________________________________ -BLKSEC: - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ SECTOR BUFFER - LD HL,#SECTOR_BUFFER ; LOAD HL WITH SECTOR BUFFER ADDRESS - LD A,(SECTOR_INDEX) ; GET THE SECTOR INDEX (CP/M SECTOR OFFSET IN BUFFER) - RRCA ; MOVE BIT 0 TO BIT 7 - RRCA ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - LD D,#0 ; PUT RESULT AS 16 VALUE IN DE, UPPER BYTE IN D IS 000h - LD E,A ; PUT ADDRESS OFFSET IN E - ADD HL,DE ; CP/M SECTOR STARTING ADDRESS IN IDE HD SECTOR BUFFER - ADD HL,DE ; MULTIPLY BY 2, TOTAL MULTIPLICATION IS X 128 - LD (SECST),HL ; KEEP CP/M SECTOR ADDRESS FOR LATER USE - ; COPY CP/M SECTOR FROM BDOS DMA ADDRESS BUFFER - LD HL,(SECST) ; LOAD CP/M SECTOR ADDRESS (WHERE THE DATA IS TO BE WRITTEN) - LD D,H ; TRANSFER HL REGISTERS TO DE - LD E,L ; - LD HL,(DMAAD) ; LOAD HL WITH DMA ADDRESS (WHERE THE DATA TO BE WRITTEN IS) - CALL COPY_CPM_SECTOR ; - RET - -;___ISCUR_______________________________________________________________________________________________ -; -; IS CURRENT SECTOR IN BUFFER? -; -;________________________________________________________________________________________________________ -ISCUR: - LD HL,(PSECTOR) ; COMPARE REQUESTED SECTOR WITH SECTOR IN BUFFER - LD A,(CUSECTOR) ; - CP L ; - RET NZ ; LOW BYTE NOT EQUAL - LD A,(CUSECTOR+1) ; - CP H ; - RET NZ ; HIGH BYTE NOT EQUAL - LD HL,(PTRACK) ; COMPARE REQUESTED TRACK WITH TRACK IN BUFFER - LD A,(CUTRACK) ; - CP L ; LOW BYTE NOT EQUAL - RET NZ ; - LD A,(CUTRACK+1) ; - CP H ; - RET NZ ; HIGH BYTE NOT EQUAL - LD HL,(DISKNO) ; COMPARE REQUESTED DRIVE WITH DRIVE IN BUFFER - LD A,(CUDISK) ; - CP L ; - RET ; EXIT WITH RESULT - -;___READ_FLPY_DSK________________________________________________________________________________________ -; -; READ FLOPPY DISK -; -;________________________________________________________________________________________________________ - -READ_FLPY_DSK: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL TRFLSEC ; TRANSLATE SECTOR INFORMATION - CALL READ_FLPY_SEC ; - CALL DEBSEC ; DEBLOCK SECTOR - LD A,(ST1) ; LOAD RESULT CODE INTO A -READ_FLPY_DSK_EXIT: ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - - -;___READ_FLPY_SEC________________________________________________________________________________________ -; -; READ A SECTOR FROM A FLOPPY DISK -; -;________________________________________________________________________________________________________ -READ_FLPY_SEC: - LD A,#0 ; RESET STATUS FLAG 1 - LD (ST1),A ; - CALL ISCUR ; IS CURRENT SECTOR ALREADY IN BUFFER - JP Z,READ_FLPY_SEC_OK - LD A,#20 ; 20 RETRIES - LD (RETRY),A ; - LD A,#2 ; 2 ITERATIONS OF RETRIES - LD (RETRY1),A ; -READ_FLPY_SEC_RETRY: ; - CALL FLOPPYREAD ; READ THE FLOPPY DISK SECTOR - LD A,(ST0) ; GET STATUS FLAG 0 - AND #0x0F8 ; MASK OF DRIVE AND HEAD SELECTION - LD B,A ; MOVE STATUS FLAG 0 TO B - LD A,(ST1) ; GET STATUS FLAG 1 - OR B ; IF ZERO READ WAS OK - JP Z,READ_FLPY_SEC_OK - LD A,(RETRY) ; READ NOT OK, DEC RETRY COUNTER - DEC A ; - LD (RETRY),A ; STORE NEW RETRY COUNTER - JP NZ,READ_FLPY_SEC_RETRY - CALL CYCLEFLOPPY ; CYCLE FLOPPY HEAD - LD A,#20 ; RESET TO 20 RETRIES - LD (RETRY),A ; STORE RETRY COUNTER - LD A,(RETRY1) ; DEC RETRY ITERATION COUNTER - DEC A ; - LD (RETRY1),A ; - JP NZ,READ_FLPY_SEC_RETRY - LD HL,#0x0FFFF ; SET INVALID CONDITION, BUFFER IS INVALID - LD (CUSECTOR),HL ; CURRENT PHYSICAL DISK SECTOR IN BUFFER - LD (CUTRACK),HL ; CURRENT PHYSICAL DISK TRACK IN BUFFER - RET ; -READ_FLPY_SEC_OK: ; - LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - LD (CUSECTOR),HL ; - LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - LD (CUTRACK),HL ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - RET - -;___READ_IDE_____________________________________________________________________________________________ -; -; READ FROM IDE HARD DISK -;________________________________________________________________________________________________________ - -READ_IDE: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - ; DISABLE INTERRUPTS - CALL CONVERT_IDE_SECTOR_CPM - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - JP NC,READ_IDE_ERROR - CALL DEBSEC ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE READ SUCCESSFUL A=0 - RET ; -READ_IDE_ERROR: ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE READ ERROR A=FF - RET - -;___READ_ATAPI_________________________________________________________________________________________ -; -; READ FROM ATAPI DEVICE -;________________________________________________________________________________________________________ -READ_ATAPI: - LD A,#0x0FF ; 255 RETRIES - LD (RETRY),A ; -READ_ATAPI_RETRY: - LD A,#0x10 ; SET TO SECONDARY DEVICE - LD (IDEDEVICE),A ; - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL CONVERT_IDE_SECTOR_CPM - CALL ATAPI_READ_SECTOR - JP NC,READ_ATAPI_ERROR - CALL DEBSEC ; - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE READ SUCCESSFUL A=0 - RET ; -READ_ATAPI_ERROR: - LD A,(RETRY) ; READ NOT OK, DEC RETRY COUNTER - DEC A ; - LD (RETRY),A ; STORE NEW RETRY COUNTER - JP NZ,READ_ATAPI_RETRY - LD SP,(PARKSTACK) ; RETURN STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE READ ERROR A=FF - RET ; - -READ_HDPART4: - ; STUB - RET - -;___WRITE______________________________________________________________________________________________ -; -; HANDLE CP/M WRITE CALL -; -;________________________________________________________________________________________________________ -WRITE: - DI ; DISABLE INTERRUPTS - LD A,(DISKNO) ; GET DRIVE - CP #1 ; FIND OUT WHICH DRIVE IS BEING REQUESTED - .IF CONDUSEFLOPPY - JP Z,WRITE_FLP_DSK ; - .ELSE - JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - .ENDIF - CP #0 ; - JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - CP #2 ; - JP Z,WRITE_IDE ; WRITE TO 8 MB IDE HARD DISK, PARTITION 2 - CP #3 ; - .IF CONDUSEATAPI - JP Z,WRITE_ATAPI ; WRITE TO 8 MB IDE HARD DISK, PARTITION 3 - .ELSE - JP Z,WRITE_RAM_DISK ; WRITE TO 448K RAM DISK - .ENDIF - CP #4 ; - JP Z,WRITE_HDPART4 ; WRITE TO 1 MB IDE HARD DISK, PARTITION 4 - - -;___RDONLY______________________________________________________________________________________________ -; -; HANDLE WRITE TO READ ONLY -; -; SENDS A MESSAGE TO TERMINAL THAT ROM DRIVE IS NOT WRITEABLE -; DOES A PAUSE THEN RETURNS TO CPM WITH ERROR FLAGGED THIS IS -; DONE TO ALLOW A POSSIBLE GRACEFUL EXIT (SOME APPS MAY PUKE) -;________________________________________________________________________________________________________ -RDONLY: - LD HL,#TXT_RO_ERROR ; SET HL TO START OF ERROR MESSAGE - CALL PRTMSG ; PRINT ERROR MESSAGE - LD A,#1 ; SEND BAD SECTOR ERROR BACK - ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - RET - -;___WRITE_RAM_DISK_____________________________________________________________________________________ -; -; WRITE RAM DISK -;________________________________________________________________________________________________________ -WRITE_RAM_DISK: - LD HL,#SECTOR_BUFFER ; LOAD HL WITH TEMP BUF ADDRESS - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,(DMAAD) ; GET DMA ADDRESS - CALL COPY_CPM_SECTOR ; - CALL SECPAGE ; GET RAM PAGE WRITE ADDRESS - CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - LD HL,(SECST) ; LOAD HL WITH DMA ADDRESS (WHERE TO WRITE TO) - LD E,L ; - LD D,H ; GET IT INTO DE - LD HL,#SECTOR_BUFFER ; GET TEMP BUFFER ADDRESS - CALL COPY_CPM_SECTOR ; - CALL RPAGE ; SET BACK TO RAM - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - LD A,#0 ; -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - -;___WRITE_FLP_DSK_____________________________________________________________________________________ -; -; WRITE FLOPPY DISK -;________________________________________________________________________________________________________ -WRITE_FLP_DSK: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; MOVE STACK POINTER TO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL TRFLSEC ; TRANSLATE SECTOR INFORMATION - CALL READ_FLPY_SEC ; - LD A,(ST1) ; GET STATUS CODE - JP NZ,WRITE_FLP_DSK_OK -WRITE_READ_FLPY_DSK_OK: ; - CALL BLKSEC ; BLOCK SECTOR - ; IDE HD SECTOR IS NOW UPDATED WITH CURRENT CP/M SECTOR DATA SO WRITE TO DISK - LD A,#20 ; 20 RETRIES - LD (RETRY),A ; -WRITE_FLP_DSK_RETRY: ; - CALL FLOPPYWRITE ; WRITE THE FLOPPY DISK SECTOR - LD A,(ST0) ; GET STATUS CODE 0 - AND #0x0F8 ; MASK OF DRIVE AND HEAD SELECTION - LD B,A ; MOVE STATUS CODE 0 TO B - LD A,(ST1) ; GET STATUS CODE 1 - OR B ; IF ZERO WRITE WAS OK - JP Z,WRITE_FLP_DSK_OK ; - LD A,(RETRY) ; BAD WRITE, DEC RETRY COUNTER - DEC A ; - LD (RETRY),A ; STORE NEW RETRY COUNTER - JP NZ,WRITE_FLP_DSK_RETRY ; -WRITE_FLP_DSK_OK: ; - LD SP,(PARKSTACK) ; RESTORE STACK - LD A,(ST1) ; GET STATUS CODE 1 -;;;;; EI ; RE-ENABLE INTERRUPTS - RET - - - -;___WRITE_IDE____________________________________________________________________________________________ -; -; WRITE TO IDE DEVICE -;________________________________________________________________________________________________________ -WRITE_IDE: - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - CALL CONVERT_IDE_SECTOR_CPM ; - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - JP NC,WRITE_IDE_ERROR ; - CALL BLKSEC ; DEBLOCK SECTOR - CALL IDE_WRITE_SECTOR ; WRITE THE UPDATED IDE HARD DISK SECTOR - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE WRITE SUCCESSFUL A=0 - RET ; -WRITE_IDE_ERROR: ; - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE WRITE ERROR A=FF - RET - -;___WRITE_ATAPI__________________________________________________________________________________________ -; -; WRITE TO ATAPI DEVICE -;________________________________________________________________________________________________________ -WRITE_ATAPI: - LD A,#0x10 ; SET TO SECONDARY DEVICE - LD (IDEDEVICE),A ; - DI ; DISABLE INTERRUPTS - LD HL,#0 ; - ADD HL,SP ; GET STACK POINTER INTO HL - LD (PARKSTACK),HL ; SAVE STACK POINTER - LD SP,#FLOPPYSTACK ; - ; - CALL CONVERT_IDE_SECTOR_CPM ; - ; - CALL ATAPI_READ_SECTOR ; - JP NC,WRITE_ATAPI_ERROR ; - CALL BLKSEC ; DEBLOCK SECTOR - CALL ATAPI_WRITE_SECTOR ; - ; - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0 ; RETURN ERROR CODE WRITE SUCCESSFUL A=0 - RET ; -WRITE_ATAPI_ERROR: ; - LD SP,(PARKSTACK) ; RESTORE STACK -;;;;; EI ; RE-ENABLE INTERRUPTS - LD A,#0x0FF ; RETURN ERROR CODE WRITE ERROR A=FF - RET ; - -WRITE_HDPART4: - ; STUB - RET - - -;___PRTMSG_______________________________________________________________________________________________ -; -; PRINT MESSAGE POINTED TO BY HL ON CONSOLE DEVICE -;________________________________________________________________________________________________________ -PRTMSG: - LD A,(HL) ; GET CHARACTER TO A - CP #END ; TEST FOR END BYTE - JP Z,PRTMSG1 ; JUMP IF END BYTE IS FOUND - LD C,A ; PUT CHAR TO PRINT VALUE IN REG C FOR CONOUT - CALL CONOUT ; SEND CHARACTER TO CONSOLE FROM REG C - INC HL ; INC POINTER, TO NEXT CHAR - JP PRTMSG ; TRANSMIT LOOP -PRTMSG1: - RET - - -;___SECPAGE_______________________________________________________________________________________________ -; -; UTILITY ROUTINE FOR SECTOR TO PAGE ADDRESS -;________________________________________________________________________________________________________ -SECPAGE: - LD HL,(SECTOR) ; GET SECTOR INTO HL - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*2) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*4) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*8) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*16) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*32) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*64) - ADD HL,HL ; SHIFT BITS 1 TO LEFT (*128) - LD (SECST),HL ; SAVE SECTOR STARTING ADDRESS - RET - -;___PAGERB_______________________________________________________________________________________________ -; -; PAGER BYTE CREATION -; ASSEMBLES DRIVE AND TRACK AND SENDS IT TO PAGER PORT -;________________________________________________________________________________________________________ -PAGERB: - LD HL,(TRACK) ; LOAD TRACK INTO HL - LD A,(DISKNO) ; LOAD DISK INTO A - CP #5 ; IS ROM? - JP Z,ROMD ; READ FROM 1M ROM DISK - CP #6 ; IS ROM? - JP Z,ROMD ; READ FROM 22K ROM DISK - AND #1 ; MASK FOR 1 BIT OF DRIVE SELECT - RRCA ; MOVE BIT 0 TO BIT 7 - OR L ; OR L WITH ACC TO COMBINE TRACK AND DRIVE - OUT (MPCL_RAM),A ; SEND TO RAM PORT MAPPER - LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - RET ; -ROMD: ; - LD A,#5 ; - AND #1 ; MASK FOR 1 BIT OF DRIVE SELECT - RRCA ; MOVE BIT 0 TO BIT 7 - OR L ; OR L WITH ACC TO COMBINE TRACK AND DRIVE - AND #0x7F ; STRIP OFF BIT 7 (ROM_ENABLE BIT) - OUT (MPCL_ROM),A ; SEND TO ROM PORT MAPPER - LD (PAGER),A ; SAVE COPY (JUST BECAUSE) - LD (DB_PAGER),A ; SAVE COPY (JUST BECAUSE) (DEBUG) - RET - -;___RPAGE_______________________________________________________________________________________________ -; -; RESET PAGER BACK TO RAM -;________________________________________________________________________________________________________ -RPAGE: - LD A,#0x80 ; DESELECT ROM PAGE - OUT (MPCL_ROM),A ; SELECT RAM - LD A,#0 ; SET TO RAM, TRACK 0 - OUT (MPCL_RAM),A ; SELECT RAM - LD (PAGER),A ; SAVE COPY OF PAGER BYTE - RET - -;___COPY_CPM_SECTOR______________________________________________________________________________________ -; -; COPIES ONE CPM SECTOR FROM ONE MEMORY ADDRESS TO ANOTHER -; INPUT -; DE SOURCE ADDRESS -; HL TARGET ADDRESS -; USES C REGISTER -;________________________________________________________________________________________________________ -COPY_CPM_SECTOR: - LD BC,#128 ; BC IS COUNTER FOR FIXED SIZE TRANSFER (128 BYTES) - LDIR ; TRANSFER - RET - -;___CONVERT_IDE_SECTOR_CPM________________________________________________________________________________ -; -; COMPUTES WHERE THE CP/M SECTOR IS IN THE LBA PARTITION -; LBA HD SECTORS ARE 512 BYTES EACH, CP/M SECTORS ARE 128 BYTES EACH -; MAXIMUM SIZE OF CP/M DISK IS 8 MB = 65536 (16 BITS) X 128 BYTES PER SECTOR -; LBA HD PARTITION CAN HAVE AT MOST 16777215 IDE SECTORS -> 67108860 CP/M SECTORS -; EACH IDE HD SECTOR CONTAINS 4 ADJACENT CP/M SECTORS -; -; -; INPUT: -; - CP/M TRACK AND SECTOR 16 BIT WORDS -; -; OUTPUT: -; IDE TARGET SECTOR (SENT TO IDE HD CONTROLLER FOR READ OPERATION) -; - LOWER 16 BITS STORED IN LBA_TARGET_LO -; - UPPER 16 BITS STORED IN LBA_TARGET_HI -; CP/M TO IDE HD SECTOR MAPPING PARAMETER STORED IN SECTOR_INDEX -; - 8 BIT VALUE WITH 4 LEGAL STATES (00, 01, 02, 04) WHICH IS -; TO BE USED TO COMPUTE STARTING ADDRESS OF 128 BYTE CP/M SECTOR ONCE -; 512 BYTE IDE HD SECTOR READ INTO MEMORY BUFFER -; LBA ADDRESS FORMAT = 00TTTTSS -; -; ROTATE WITH CARRY 16 BIT TRACK,SECTOR VALUE IN HL TO GET 14 BIT IDE HD -; TARGET SECTOR IN PARTITION -; KEEP LAST TWO BITS IN B FOR IDE HD SECTOR TO CP/M SECTOR TRANSLATION -; COMPUTE SECTOR_INDEX -;________________________________________________________________________________________________________ -CONVERT_IDE_SECTOR_CPM: - - LD A,(TRACK) ; LOAD TRACK # (LOW BYTE) - LD H,A ; - LD A,(SECTOR) ; LOAD SECTOR# (LOW BYTE) - LD L,A ; - CALL RRA16 ; ROTATE 'HL' RIGHT (DIVIDE BY 2) - CALL RRA16 ; ROTATE 'HL' RIGHT (DIVIDE BY 2) - LD A,(TRACK+1) ; GET HIGH BYTE OF TRACK INTO A - SLA A ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - OR H ; - LD H,A ; - LD A,(TRACK+1) ; GET HIGH BYTE OF TRACK INTO A - SRL A ; - SRL A ; - LD (LBA_TARGET_HI),A ; - LD A,L ; - LD (LBA_TARGET_LO),A ; LBA REGISTER IS 00TTTTSS / 4 - LD A,H ; - LD (LBA_TARGET_LO+1),A ; - LD A,#0 ; - LD (LBA_TARGET_HI+1),A ; - ; - LD HL,(LBA_TARGET_LO) ; STORE PHYSICAL SECTOR - LD (PSECTOR),HL ; - LD HL,(LBA_TARGET_HI) ; STORE PHYSICAL TRACK - LD (PTRACK),HL ; - LD A,(SECTOR) ; LOAD SECTOR # - AND #0b000000011 ; - LD (SECTOR_INDEX),A ; LOCATES WHERE THE 128 BYTE CP/M SECTOR - ; IS WITHIN THE 512 BYTE IDE HD SECTOR - ; COMPUTE WHICH IDE HD SECTOR TO READ TO WITHIN 4 CP/M SECTORS - ; SHIFTS 16 BIT PARTITION OFFSET TO THE RIGHT 2 BITS AND ADDS RESULT TO - ; IDE HD PARTITION STARTING SECTOR - ; SHIFT PARTITION OFFSET RIGHT 1 BIT - RET -RRA16: - SCF ; - CCF ; CLEAR CARRY FLAG - LD A,H ; 16 BIT ROTATE HL WITH CARRY - RRA ; - LD H,A ; ROTATE HL RIGHT 1 BIT (DIVIDE BY 2) - LD A,L ; - RRA ; - LD L,A ; - RET - - -;___IDE_READ_SECTOR______________________________________________________________________________________ -; -; READ IDE SECTOR -;________________________________________________________________________________________________________ -IDE_READ_SECTOR: - CALL ISCUR ; IS CURRENT SECTOR IN BUFFER? - JP Z,IDE_READ_SECTOR_OK ; - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_SETUP_LBA ; TELL DRIVE WHAT SECTOR IS REQUIRED - LD A,#0x20 ; - OUT (IDESTTS),A ; 020h = IDE 'READ SECTOR' COMMAND -IDE_SREX: ; - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - RET NC ; ERROR, RETURN - CALL IDE_WAIT_BUFFER ; WAIT FOR FULL BUFFER SIGNAL FROM DRIVE - RET NC ; ERROR, RETURN - CALL IDE_READ_BUFFER ; GRAB THE 256 WORDS FROM THE BUFFER - SCF ; CARRY = 1 ON RETURN = OPERATION OK -IDE_READ_SECTOR_OK: ; - LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - LD (CUSECTOR),HL ; - LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - LD (CUTRACK),HL ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET - -;___IDE_WRITE_SECTOR_____________________________________________________________________________________ -; -; WRITE IDE SECTOR -;________________________________________________________________________________________________________ -IDE_WRITE_SECTOR: - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_SETUP_LBA ; TELL DRIVE WHAT SECTOR IS REQUIRED - LD A,#0x30 ; - OUT (IDESTTS),A ; 030h = IDE 'WRITE SECTOR' COMMAND - CALL IDE_WAIT_BUSY_READY ; - RET NC ; ERROR, RETURN - CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - RET NC ; ERROR, RETURN - CALL IDE_WAIT_BUFFER ; WAIT FOR BUFFER READY SIGNAL FROM DRIVE - RET NC ; ERROR, RETURN - CALL IDE_WRITE_BUFFER ; SEND 256 WORDS TO DRIVE'S BUFFER - CALL IDE_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_TEST_ERROR ; ENSURE NO ERROR WAS REPORTED - RET NC ; ERROR, RETURN - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET - -;___IDE_SOFT_RESET_______________________________________________________________________________________ -; -; RESET IDE CHANNEL -;________________________________________________________________________________________________________ -IDE_SOFT_RESET: - .IF CONDIDESOFT ; - LD A,#0b000000110 ; NO INTERRUPTS, RESET DRIVE = 1 - OUT (IDECTRL),A ; - LD A,#0b000000010 ; NO INTERRUPTS, RESET DRIVE = 0 - OUT (IDECTRL),A ; - CALL IDE_WAIT_BUSY_READY ;THIS TAKES A COUPLE OF SECONDS - RET - .ELSE - ; SKIP THIS IF NO IDE DRIVE WHICH SPEEDS UP REBOOTS AND STARTUPS - RET - .ENDIF - -;___ATAPI_WAIT_BUSY_READY________________________________________________________________________________ -; -; WAIT FOR ATAPI CHANNEL TO BE READY -;________________________________________________________________________________________________________ -ATAPI_WAIT_BUSY_READY: - LD DE,#0 ; CLEAR OUT DE -ATAPI_WBSY: ; - LD B,#0x0F0 ; SETUP TIMEOUT -ATAPI_DLP: ; - DJNZ ATAPI_DLP ; - INC DE ; - LD A,D ; - OR E ; - JR Z,ATAPI_TO ; - IN A,(IDESTTS) ; READ ERROR REG - AND #0b010000000 ; MASK OFF BUSY BIT - JR NZ,ATAPI_WBSY ; WE WANT BUSY(7) TO BE 0 - SCF ; CARRY 1 = OK - RET ; -ATAPI_TO: ; - XOR A ; CARRY 0 = TIMED OUT - RET ; - -;___IDE_WAIT_DRQ_READY___________________________________________________________________________________ -; -; WAIT FOR IDE CHANNEL TO BE READY -;________________________________________________________________________________________________________ -IDE_WAIT_DRQ_READY: - IN A,(IDESTTS) ; READ ERROR REG - AND #0b000001000 ; MASK OFF RDY BIT - JR Z,IDE_WAIT_DRQ_READY ; WE WANT DRQ(3) TO BE 1 - RET - -;___IDE_WAIT_DRQ_ZERO____________________________________________________________________________________ -; -; WAIT FOR IDE DRQ TO BE ZERO -;________________________________________________________________________________________________________ -IDE_WAIT_DRQ_ZERO: - IN A,(IDESTTS) ; READ ERROR REG - AND #0b000001000 ; MASK OFF RDY BIT - JR NZ,IDE_WAIT_DRQ_ZERO ; WE WANT DRQ(3) TO BE 0 - RET - -;___IDE_WAIT_BUSY_READY___________________________________________________________________________________ -; -; WAIT FOR IDE CHANNEL TO BE READY -;________________________________________________________________________________________________________ -IDE_WAIT_BUSY_READY: - LD DE,#0 ; CLEAR DE -IDE_WBSY: ; - LD B,#5 ; SETUP TIMEOUT -IDE_DLP: ; - DEC B ; - JP NZ,IDE_DLP ; - INC DE ; - LD A,D ; - OR E ; - JP Z,IDE_TO ; - IN A,(IDESTTS) ; READ ERROR REG - AND #0b011000000 ; MASK OFF BUSY AND RDY BITS - XOR #0b001000000 ; WE WANT BUSY(7) TO BE 0 AND RDY(6) TO BE 1 - JP NZ,IDE_WBSY ; - SCF ; CARRY 1 = OK - RET -IDE_TO: - XOR A ; CARRY 0 = TIMED OUT - RET - -;___IDE_TEST_ERROR_______________________________________________________________________________________ -; -; CHECK FOR IDE ERROR CONDITION -;________________________________________________________________________________________________________ -IDE_TEST_ERROR: - SCF ; - IN A,(IDESTTS) ; - LD B,A ; - AND #0b000000001 ; TEST ERROR BIT - SCF ; - RET Z ; - LD A,B ; - AND #0b000100000 ; - SCF ; - JP NZ,IDE_ERR ; TEST WRITE ERROR BIT - IN A,(IDEERR) ; READ ERROR FLAGS -IDE_ERR: - OR A ; CARRY 0 = ERROR - RET ; IF A = 0, IDE BUSY TIMED OUT - -;___IDE_WAIT_BUFFER_______________________________________________________________________________________ -; -; WAIT FOR DATA BUFFER READY -;________________________________________________________________________________________________________ -IDE_WAIT_BUFFER: - LD DE,#0 ; -IDE_WDRQ: ; - LD B,#5 ; -IDE_BLP: ; - DEC B ; - JP NZ,IDE_BLP ; - INC DE ; - LD A,D ; - OR E ; - JP Z,IDE_TO2 ; - IN A,(IDESTTS) ; WAIT FOR DRIVE'S 512 BYTE READ BUFFER - AND #0b000001000 ; TO FILL (OR READY TO FILL) - JP Z,IDE_WDRQ ; - SCF ; CARRY 1 = OK - RET ; -IDE_TO2: ; - XOR A ; CARRY 0 = TIMED OUT - RET ; - -;___IDE_READ_BUFFER_______________________________________________________________________________________ -; -; READ IDE BUFFER -;________________________________________________________________________________________________________ -IDE_READ_BUFFER: - PUSH HL ; - LD HL,#SECTOR_BUFFER ; - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) -IDEBUFRD: ; - IN A,(IDELO) ; LOW BYTE OF WORD FIRST - LD (HL),A ; - IN A,(IDEHI) ; THEN HIGH BYTE OF WORD - INC HL ; - LD (HL),A ; - INC HL ; - DEC B ; - JP NZ,IDEBUFRD ; - POP HL ; - RET - -;___IDE_WRITE_BUFFER_______________________________________________________________________________________ -; -; WRITE TO IDE BUFFER -;________________________________________________________________________________________________________ -IDE_WRITE_BUFFER: - PUSH HL ; - LD HL,#SECTOR_BUFFER ; - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) -IDEBUFWT: - INC HL ; - LD A,(HL) ; - DEC HL ; - OUT (IDEHI),A ; SET UP HIGH LATCHED BYTE BEFORE - LD A,(HL) ; - OUT (IDELO),A ; WRITING WORD WITH WRITE TO LOW BYTE - INC HL ; - INC HL ; - DEC B ; - JP NZ,IDEBUFWT ; - POP HL ; - RET - -;___IDE_SETUP_LDA________________________________________________________________________________________ -; -; SETUP IDE DRIVE FOR LDA OPERATION -;________________________________________________________________________________________________________ -IDE_SETUP_LBA: - LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - LD (IDE_LBA0),A ; - LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - LD (IDE_LBA1),A ; - LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - LD (IDE_LBA2),A ; - LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - AND #0b000001111 ; ONLY LOWER FOUR BITS ARE VALID - ADD A,#0b011100000 ; ENABLE LBA BITS 5:7=111 IN IDE_LBA3 - LD (IDE_LBA3),A ; - ; READ IDE HD SECTOR - LD A,#1 ; - OUT (IDESECTC),A ; SET SECTOR COUNT = 1 - ; - LD A,(IDE_LBA0) ; - OUT (IDESECTN),A ; SET LBA 0:7 - ; - LD A,(IDE_LBA1) ; - OUT (IDECYLLO),A ; SET LBA 8:15 - ; - LD A,(IDE_LBA2) ; - OUT (IDECYLHI),A ; SET LBA 16:23 - ; - LD A,(IDE_LBA3) ; - AND #0b000001111 ; LOWEST 4 BITS USED ONLY - OR #0b011100000 ; TO ENABLE LBA MODE - OUT (IDEHEAD),A ; SET LBA 24:27 + BITS 5:7=111 - .IF CONDUSEDSKY - CALL IDESEGDISPLAY ; - .ENDIF - RET - -;___ATAPI_SOFT_RESET_____________________________________________________________________________________ -; -; RESET ATAPI BUS -;________________________________________________________________________________________________________ -ATAPI_SOFT_RESET: - LD A,#0b000001110 ;NO INTERRUPTS, RESET DRIVE = 1 - OUT (IDECTRL),A ; - CALL DELAY24 ; - LD A,#0b000001010 ;NO INTERRUPTS, RESET DRIVE = 0 - OUT (IDECTRL),A ; - CALL ATAPI_WAIT_BUSY_READY ; - RET NC ; ERROR, RETURN - CALL ATAPI_DEVICE_SELECTION ; - CALL DELAY24 ; - CALL REQUEST_SENSE_LOOP ; - RET - -;___REQUEST_SENSE_LOOP____________________________________________________________________________________ -; -; ATAPI_REQUEST SENSE DATA -;_________________________________________________________________________________________________________ -REQUEST_SENSE_LOOP: - LD HL,#ATAPI_REQUEST_SENSE ; - CALL ATAPI_SEND_PACKET ; - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) -REQUEST_SENSE_LOOP1: ; - IN A,(IDELO) ; - INC IX ; - IN A,(IDEHI) ; - INC IX ; - DJNZ REQUEST_SENSE_LOOP1 ; - RRD ; DELAY ONLY - IN A,(IDESTTS) ;READ ERROR REG - AND #0b000000001 ;MASK OFF BIT - JR NZ,REQUEST_SENSE_LOOP ; - RET - -;___ATAPI_DEVICE_SELECTION________________________________________________________________________________ -; -; ATAPI DEVICE SELECTION -;_________________________________________________________________________________________________________ -ATAPI_DEVICE_SELECTION: - - LD A,(IDEDEVICE) ; SELECTS DEVICE - OR #0x0A0 ; - OUT (IDEHEAD),A ; - RET ; - - - -;__ATAPI_READ_SECTOR_____________________________________________________________________________________________________________ -; READ ATAPI SECTOR -; -; D E H L = SECTOR (DOUBLE WORD) TO READ -;________________________________________________________________________________________________________________________________ -ATAPI_READ_SECTOR: - CALL ISCUR ; - JP Z,ATAPI_READ_DATA_EXIT ; - LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+5),A ; - LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+4),A ; - LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+3),A ; - LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - LD (READ_DISK_PACKET+2),A ; - .IF CONDUSEDSKY - CALL ATAPISEGDISPLAY ; - .ENDIF - CALL REQUEST_SENSE_LOOP ; GET ATAPI SENSE CODES TO CLEAR ERRORS - LD HL,#READ_DISK_PACKET ; SET POINTER TO READ SECTOR PACKET - CALL ATAPI_SEND_PACKET ; SEND PACKET COMMAND - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - LD IX,#SECTOR_BUFFER ; - IN A,(IDESTTS) ; READ REG - AND #0b000001000 ; MASK OFF BIT - CP #8 ; IS DATA WAITING? - JR NZ,ATAPI_READ_DATA_EXIT ; NO, EXIT -ATAPI_READ_DATA_LOOP: - IN A,(IDELO) ; - - LD (IX),A ; - - INC IX ; - IN A,(IDEHI) ; - - LD (IX),A ; - - INC IX ; - DJNZ ATAPI_READ_DATA_LOOP ; -ATAPI_READ_DATA_EXIT: ; - LD HL,(PSECTOR) ; STORE PHYSICAL SECTOR IN BUFFER - LD (CUSECTOR),HL ; - LD HL,(PTRACK) ; STORE PHYSICAL DISK TRACK IN BUFFER - LD (CUTRACK),HL ; - LD A,(DISKNO) ; STORE CURRENT DRIVE IN BUFFER - LD (CUDISK),A ; - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET ; - - - -;__ATAPI_WRITE_SECTOR_____________________________________________________________________________________________________________ -; WRITE ATAPI SECTOR -; -; D E H L = SECTOR (DOUBLE WORD) TO WRITE -;________________________________________________________________________________________________________________________________ -ATAPI_WRITE_SECTOR: - - LD A,(LBA_TARGET_LO) ; LOAD LBA REGISTER 0 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+5),A ; - LD A,(LBA_TARGET_LO+1) ; LOAD LBA REGISTER 1 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+4),A ; - LD A,(LBA_TARGET_HI) ; LOAD LBA REGISTER 2 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+3),A ; - LD A,(LBA_TARGET_HI+1) ; LOAD LBA REGISTER 3 WITH SECTOR ADDRESS TO READ - LD (WRITE_DISK_PACKET+2),A ; - .IF CONDUSEDSKY - CALL ATAPISEGDISPLAY ; - .ENDIF - CALL REQUEST_SENSE_LOOP ; - LD HL,#WRITE_DISK_PACKET ; SET POINTER TO WRITE PACKET COMMAND - CALL ATAPI_SEND_PACKET ; SEND THE PACKET COMMAND - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - LD B,#0 ; 256 WORDS (512 BYTES PER SECTOR) - LD IX,#SECTOR_BUFFER ; -ATAPI_WRITE_DATA_LOOP: - IN A,(IDESTTS) ; READ REG - - LD A,(IX) ; - - PUSH AF ; - INC IX ; - - LD A,(IX) ; - - OUT (IDEHI),A ; - POP AF ; - OUT (IDELO),A ; - INC IX ; - DJNZ ATAPI_WRITE_DATA_LOOP ; - SCF ; CARRY = 1 ON RETURN = OPERATION OK - RET ; - - - - -;__ATAPI_SEND_PACKET_____________________________________________________________________________________________________________ -; SEND PACKET POINTED TO BY HL TO ATAPI DRIVE -; -;________________________________________________________________________________________________________________________________ -ATAPI_SEND_PACKET: - - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - CALL IDE_WAIT_DRQ_ZERO ; - ; - LD A,#0x0A ; - OUT (IDECTRL),A ; DISABLE INT - LD A,#0 ; - OUT (IDEERR),A ; - LD A,#0 ; - OUT (IDESECTC),A ; - LD A,#0 ; - OUT (IDESECTN),A ; - LD A,#0 ; - OUT (IDECYLLO),A ; - LD A,#0x60 ; - OUT (IDECYLHI),A ; - LD A,(IDEDEVICE) ; - OUT (IDEHEAD),A ; BIT 4 SELECTS DEVICE - LD A,#0x0A0 ; - OUT (IDESTTS),A ; - ; - CALL IDE_WAIT_DRQ_READY ; MAKE SURE DRIVE IS READY TO PROCEED - ; - LD B,#6 ; SEND 12 BYTES (6 WORDS) - ; -ATAPI_SEND_PACKET_LOOP: - LD A,(HL) ; GET BYTE - LD D,A ; STORE LOW BYTE IN D - INC HL ; INC POINTER - LD A,(HL) ; GET HIGH BYTE - OUT (IDEHI),A ; STORE HIGH BYTE - LD A,D ; MOVE LOW BYTE INTO A - OUT (IDELO),A ; STORE LOW BYTE - INC HL ; INC POINTER - IN A,(IDECTRL) ; GET STATUS - DJNZ ATAPI_SEND_PACKET_LOOP ; LOOP - ; - CALL ATAPI_WAIT_BUSY_READY ; MAKE SURE DRIVE IS READY TO PROCEED - RET NC ; ERROR, RETURN - IN A,(IDECTRL) ; READ STATUS (FOR DELAY) - ; - RET ; - -;__SETUPDRIVE__________________________________________________________________________________________________________________________ -; -; SETUP FLOPPY DRIVE SETTINGS -;________________________________________________________________________________________________________________________________ -; -SETUPDRIVE: - LD A,#RESETL ; RESET SETTINGS -.IF COND144FLOPPY-1 - OR MINI ; SELECT MINI FLOPPY (LOW DENS=1, HIGH DENS=0) -.ENDIF - OR #PRECOMP ; SELECT PRECOMP - OR #FDDENSITY ; SELECT DENSITY - OR #FDREADY ; SELECT READY SIGNAL - LD (FLATCH_STORE),A ; SAVE SETTINGS - LD A,#1 ; - LD (UNIT),A ; SET UNIT 1 - LD A,#2 ; DENSITY - LD (DENS),A ; - LD A,#9 ; -.IF COND144FLOPPY - ADD A,A -.ENDIF - LD (EOTSEC),A ; LAST SECTOR OF TRACK - LD A,#0x7F ; - LD (SRTHUT),A ; STEP RATE AND HEAD UNLOAD TIME - LD A,#5 ; - LD (HLT),A ; HEAD LOAD TIME - LD A,#0x0D ; - LD (GAP),A ; GAP -;; LD A,#0x80 ; -;; LD (SECSIZ),A ; SECTOR SIZE /4 - ; - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - ; - LD HL,#FLATCH_STORE ; POINT TO FLATCH - RES 1,(HL) ; SET MOTOR ON - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; - LD A,#0 ; ZERO TRACK - LD (PTRACK),A ; STORE TRACK - CALL SETTRACK ; DO IT - NOP ; - NOP ; - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - RET -; -;__OUTFLATCH__________________________________________________________________________________________________________________________ -; -; SEND SETTINGS TO FLOPPY CONTROLLER -;________________________________________________________________________________________________________________________________ -; -OUTFLATCH: - LD A,(FLATCH_STORE) ; SET A TO SETTINGS - OUT (FLATCH),A ; OUTPUT TO CONTROLLER - RET - -;__FLOPPYREAD__________________________________________________________________________________________________________________________ -; -; READ A FLOPPY DISK SECTOR -;________________________________________________________________________________________________________________________________ -; -FLOPPYREAD: - .IF CONDUSEDSKY - CALL SEGDISPLAY ; - .ENDIF - LD A,#0x46 ; BIT 6 SETS MFM, 06H IS READ COMMAND - LD (CMD),A ; - JP DSKOP ; -; -;__FLOPPYWRITE__________________________________________________________________________________________________________________________ -; -; WRITE A FLOPPY DISK SECTOR -;________________________________________________________________________________________________________________________________ -; -FLOPPYWRITE: - .IF CONDUSEDSKY - CALL SEGDISPLAY ; - .ENDIF - LD A,#0x45 ; BIT 6 SETS MFM, 05H IS WRITE COMMAND - LD (CMD),A ; - JP DSKOP ; -; -;__DSKOP__________________________________________________________________________________________________________________________ -; -; PERFORM A DISK OPERATION -;________________________________________________________________________________________________________________________________ -; -DSKOP: - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CP #0x0FF ; DID IT RETURN WITH ERROR CODE? - JP Z,DSKEXIT ; IF YES, EXIT WITH ERROR CODE - ; - LD A,(UNIT) ; GET DISK UNIT NUMBER - AND #3 ; MASK FOR FOUR DRIVES - LD B,A ; PARK IT IN B - LD A,(HEAD) ; GET HEAD SELECTION - AND #1 ; INSURE SINGLE BIT - RLA ; - RLA ; MOVE HEAD TO BIT 2 POSITION - OR B ; OR HEAD TO UNIT BYTE IN COMMAND BLOCK - LD (UNIT),A ; STORE IN UNIT - ; - LD HL,#FLATCH_STORE ; POINT TO FLATCH - RES 1,(HL) ; SET MOTOR ON - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - LD A,#3 ; SPECIFY COMMAND - CALL PFDATA ; PUSH IT - LD A,(SRTHUT) ; STEP RATE AND HEAD UNLOAD TIME - CALL PFDATA ; PUSH THAT - LD A,(HLT) ; - CALL PFDATA ; PUSH THAT - ; - CALL SETTRACK ; PERFORM SEEK TO TRACK - ; - JP NZ,DSKEXIT ; IF ERROR, EXIT - ; - LD A,(CMD) ; WHAT COMMAND IS PENDING? - OR A ; SET FLAGS - JP DOSO4 ; NO, MUST BE READ OR WRITE COMMAND -DSKEXIT: - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - OR #0x0FF ; SET -1 IF ERROR - RET - -RESULT: - LD C,#7 ; LOAD C WITH NUMBER OF STATUS BYTES - LD HL,#ST0 ; POINT TO STATS STORAGE -RS3: - CALL GFDATA ; GET FIRST BYTE - LD (HL),A ; SAVE IT - INC HL ; POINTER++ - DEC C ; CC-1 - JP NZ,RS3 ; LOOP TIL C0 - LD A,(ST0) ; LOAD STS0 - AND #0x0F8 ; MASK OFF DRIVE # - LD B,A ; PARK IT - LD A,(ST1) ; LOAD STS1 - OR B ; ACC OR B ->ACC IF 0 THEN SUCCESS - ; -RSTEXIT: - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 1,(HL) ; SET MOTOR OFF - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - ; - .IF CONDUSEDSKY - CALL SEGDISPLAY ; - .ENDIF - RET ; DONE RETURN TO CALLER - - -DOSO4: - ; -.IF 1 ; -INT_LOC = 0x038 ; IM 1 INTERRUPT CALLS GO HERE -; SET UP FOR I/O AT INTERRUPT LEVEL - LD DE,#INT_LOC - LD HL,#INT_RD - LD BC,#L_INT_RD - LD A,(CMD) ; - AND #0b000000001 ; WRITE IS 1 - JP Z,IS_READ - ADD HL,BC -IS_READ: - LDIR -.ENDIF - - LD HL,#SECTOR_BUFFER ; GET BUFFER ADDRESS TO HL -;; LD A,(SECSIZ) ; XFERLEN -;; LD C,A ; C WILL BE THE NUMBER OF TRANSACTIONS - ; DIVIDED BY 4 - - ld de,(FSECSIZ) ; GET FULL SECTOR SIZE - LD B,E - LD C,#FDATA ; GET DATA REGISTER I/O ADDRESS - - LD A,(CMD) ; - CALL PFDATA ; PUSH COMMAND TO I8272 - LD A,(UNIT) ; - CALL PFDATA ; - LD A,(PTRACK) ; - CALL PFDATA ; - LD A,(HEAD) ; - CALL PFDATA ; - LD A,(PSECTOR) ; - INC A ; - CALL PFDATA ; - LD A,(DENS) ; - CALL PFDATA ; WHAT DENSITY - LD A,(EOTSEC) ; - CALL PFDATA ; ASSUME SC (SECTOR COUNT) EOT - LD A,(GAP) ; - CALL PFDATA ; WHAT GAP IS NEEDED - LD A,(DTL) ; DTL, IS THE LAST COMMAND BYTE TO I8272 - CALL PFDATAS ; -; -; -; PERFORM READ / WRITE -; - - -RDD_POLL: - -FDC_RW_P0: - EI - HALT - JP NZ,FDC_RW_P0 ;10 COUNT THRU 256 BYTES -FDC_RW_P1: - EI - HALT - JP NZ,FDC_RW_P1 ;10 COUNT THRU 256 BYTES - - -; FALL THROUGH WITH INTERRUPTS DISABLED (NOT ENABLED IN INTERRUPT SERVICE) - - -DSKOPEND: - LD HL,#FLATCH_STORE ; POINT TO FLATCH - SET 0,(HL) ; SET TC - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; 2 MICROSECOND DELAY - RES 0,(HL) ; RESET TC - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; 2 MICROSECOND DELAY - NOP ; - NOP ; 2 MICROSECOND DELAY - SET 1,(HL) ; TURN OFF MOTOR - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - JP RESULT ; GET STATUS BYTES - - - -INT_RD: INI - RET -IRTEMP: -L_INT_RD = IRTEMP - INT_RD - -INT_WR: OUTI - RET -IWTEMP: -L_INT_WR = IWTEMP - INT_WR - - - -;__SETTRACK__________________________________________________________________________________________________________________________ -; -; SEEK TO A TRACK ON GIVEN UNIT -; A: TRACK # -;________________________________________________________________________________________________________________________________ -; -SETTRACK: - LD A,(FTRACK) ; GET CURRENT HEAD TRACK - LD C,A - LD A,(PTRACK) ; GET TRACK - OR A ; SET FLAGS - JP Z,RECAL ; IF 0 PERFORM RECAL INSTEAD OF SEEK - CP C ; - JP Z,WAINT ; ALREADY THERE, ABORT - LD (FTRACK),A ; STORE TRACK - LD A,#0x0F ; SEEK COMMAND - CALL PFDATA ; PUSH COMMAND - LD A,(UNIT) ; SAY WHICH UNIT - CALL PFDATA ; SEND THAT - LD A,(PTRACK) ; TO WHAT TRACK - CALL PFDATA ; SEND THAT TOO - JP WAINT ; WAIT FOR INTERRUPT SAYING DONE -RECAL: - LD A,#0 ; - LD (FTRACK),A ; STORE TRACK - LD A,#7 ; RECAL TO TRACK 0 - CALL PFDATA ; SEND IT - LD A,(UNIT) ; WHICH UNIT - CALL PFDATA ; SEND THAT TOO - ; -WAINT: - ; - CALL DELAYHSEC ; DELAY TO LET HEADS SETTLE BEFORE READ - ; - ; WAIT HERE FOR INTERRPT SAYING DONE - ; LOOP TIL INTERRUPT - CALL CHECKINT ; CHECK INTERRUPT STATUS - ; - RET - -;__CYCLEFLOPPY__________________________________________________________________________________________________________________________ -; -; SEEK TO TRACK 0, THEN BACK TO THE SELECTED TRACK -; THIS CAN BE USED ON AN ERROR CONDITION TO VERIFY THAT HEAD IS ON SELECTED TRACK -; -;________________________________________________________________________________________________________________________________ -; -CYCLEFLOPPY: - PUSH AF ; STORE AF - PUSH HL ; STORE HL - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - CALL CHECKINT ; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR - LD HL,#FLATCH_STORE ; POINT TO FLATCH - RES 1,(HL) ; SET MOTOR ON - CALL OUTFLATCH ; OUTPUT TO CONTROLLER - NOP ; - NOP ; - CALL RECAL ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL RECAL ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL SETTRACK ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - CALL DELAYHSEC ; - POP HL ; - POP AF ; RESTORE AF - RET - -;__PFDATAS__________________________________________________________________________________________________________________________ -; -; WRITE A COMMAND OR PARAMETER SEQUENCE -; -; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 -; RQM DIO -; 0 0 BUSY -; 1 0 WRITE TO DATA REGISTER PERMITTED -; 1 1 BYTE FOR READ BY HOST PENDING -; 0 1 BUSY -; -;________________________________________________________________________________________________________________________________ -; -PFDATAS: - PUSH AF ; STORE AF -PFDS1: - IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - AND #0x80 ; MASK OFF RQM BIT - JP Z,PFDS1 ; WAIT FOR RQM TO BE TRUE - IN A,(FMSR) ; READ STATUS - AND #0x40 ; WAITING FOR INPUT? - CALL NZ,ERRORT ; NO, SIGNAL ERROR - POP AF ; RESTORE AF - OUT (FDATA),A ; OUTPUT A TO CONTROLLER - RET - -;__PFDATA__________________________________________________________________________________________________________________________ -; -; WRITE A COMMAND OR PARAMETER SEQUENCE -; -; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 -; RQM DIO -; 0 0 BUSY -; 1 0 WRITE TO DATA REGISTER PERMITTED -; 1 1 BYTE FOR READ BY HOST PENDING -; 0 1 BUSY -; -;________________________________________________________________________________________________________________________________ -; -PFDATA: - PUSH AF ; STORE AF -PFD1: - IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - AND #0x80 ; MASK OFF RQM BIT - JP Z,PFD1 ; WAIT FOR RQM TO BE TRUE - IN A,(FMSR) ; READ STATUS - AND #0x40 ; WAITING FOR INPUT? - CALL NZ,ERRORT ; NO, SIGNAL ERROR - POP AF ; RESTORE AF - OUT (FDATA),A ; OUTPUT A TO CONTROLLER - JP DELAY24 ; DELAY 24US - - - -;__DELAY24__________________________________________________________________________________________________________________________ -; -; DELAY 24US -;________________________________________________________________________________________________________________________________ -; -DELAY24: - ; JP= 10T - PUSH IX ; 15T - POP IX ; 14T - PUSH IX ; 15T - POP IX ; 14T -DELAY12: - PUSH IX ; 15T - POP IX ; 14T - RET ; 10T - - -;__CHECKINT__________________________________________________________________________________________________________________________ -; -; CHECK FOR ACTIVE FDC INTERRUPTS BEFORE GIVING I8272 COMMANDS -; POLL RQM FOR WHEN NOT BUSY AND THEN SEND FDC -; SENSE INTERRUPT COMMAND IF IT RETURNS WITH NON ZERO -; ERROR CODE, PASS BACK TO CALLING ROUTINE FOR HANDLING -;________________________________________________________________________________________________________________________________ -; -CHECKINT: - IN A,(FMSR) ; READING OR WRITING IS KEYS TO D7 RQM - AND #0x80 ; MASK OFF RQM BIT - JP Z,CHECKINT ; WAIT FOR RQM TO BE TRUE WAIT UNTIL DONE - IN A,(FMSR) ; READ STATUS - AND #0x40 ; WAITING FOR INPUT? - JP NZ,CHECKINTDONE ; NO, SIGNAL ERROR - CALL SENDINT ; SENSE INTERRUPT COMMAND -CHECKINTDONE: - RET ; - - -;__DELAYHSEC__________________________________________________________________________________________________________________________ -; -; DELAY FOR 1/2 SECOND -;________________________________________________________________________________________________________________________________ -; -DELAYHSEC: - LD HL,#0 ; 65536 -DELDM: - NOP ; (4 T) - NOP ; (4 T) - NOP ; (4 T) - NOP ; (4 T) - DEC L ; (6 T) - JP NZ,DELDM ; (10 T) 24 T 8 MICROSECONDS AT 4 MHZ - DEC H ; (6 T) - JP NZ,DELDM ; (10 T) (8 US * 256) * 256 524288 US 5 SECONDS - RET - -;__ERRORT__________________________________________________________________________________________________________________________ -; -; ERROR HANDLING -;________________________________________________________________________________________________________________________________ -; -ERRORT: - IN A,(FDATA) ; CLEAR THE JUNK OUT OF DATA REGISTER - IN A,(FMSR) ; CHECK WITH RQM - AND #0x80 ; IF STILL NOT READY, READ OUT MORE JUNK - JP Z,ERRORT ; - LD A,#0x0FF ; RETURN ERROR CODE -1 - ; - RET - -;__SENDINT__________________________________________________________________________________________________________________________ -; -; SENSE INTERRUPT COMMAND -;________________________________________________________________________________________________________________________________ -; -SENDINT: - LD A,#8 ; SENSE INTERRUPT COMMAND - CALL PFDATA ; SEND IT - CALL GFDATA ; GET RESULTS - LD (ST0A),A ; STORE THAT - AND #0x0C0 ; MASK OFF INTERRUPT STATUS BITS - CP #0x80 ; CHECK IF INVALID COMMAND - JP Z,ENDSENDINT ; YES, EXIT - CALL GFDATA ; GET ANOTHER (STATUS CODE 1) - LD (ST1A),A ; SAVE THAT - LD A,(ST0A) ; GET FIRST ONE - AND #0x0C0 ; MASK OFF ALL BUT INTERRUPT CODE 00 IS NORMAL -ENDSENDINT: - RET ; ANYTHING ELSE IS AN ERROR - - -;__GFDATA__________________________________________________________________________________________________________________________ -; -; GET DATA FROM FLOPPY CONTROLLER -; -; TRANSFERS ARE SYNCHONIZED BYT MSR D7 AND D6 -; RQM DIO -; 0 0 BUSY -; 1 0 WRITE TO DATA REGISTER PERMITTED -; 1 1 BYTE FOR READ BY HOST PENDING -; 0 1 BUSY -; -;________________________________________________________________________________________________________________________________ -; -GFDATA: - IN A,(FMSR) ; READ STATUS BYTE - AND #0x80 ; MASK OFF RQM - JP Z,GFDATA ; LOOP WHILE BUSY - IN A,(FMSR) ; READ STSTUS BUTE - AND #0x40 ; MASK OFF DIO - CALL Z,ERRORT ; IF WRITE EXPECTED RUN ERRORRT - IN A,(FDATA) ; READ DATA - JP DELAY24 ; DELAY 24US - - - - .IF CONDUSEDSKY -;__IDESEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF IDE LOGICAL BLOCK ADDRESS ON DSKY -;____________________________________________________________________________________________________ -IDESEGDISPLAY: - LD A, #0x82 ; - OUT (PIOCONT),A ; - ; - LD A,(IDE_LBA3) ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,(IDE_LBA3) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - ; - LD A,(IDE_LBA2) ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,(IDE_LBA2) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - ; - LD A,(IDE_LBA1) ; - AND #0x0F ; - LD (DISPLAYBUF+2),A ; - LD A,(IDE_LBA1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+3),A ; - - LD A,(IDE_LBA0) ; - AND #0x0F ; - LD (DISPLAYBUF),A ; - LD A,(IDE_LBA0) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; - JP SEGDISPLAY1 ; - -;__ATAPISEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF ATAPI LOGICAL BLOCK ADDRESS ON DSKY -;____________________________________________________________________________________________________ -ATAPISEGDISPLAY: - LD A, #0x82 ; - OUT (PIOCONT),A ; - ; - LD A,(LBA_TARGET_HI+1) ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,(LBA_TARGET_HI+1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - ; - LD A,(LBA_TARGET_HI) ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,(LBA_TARGET_HI) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - ; - LD A,(LBA_TARGET_LO+1) ; - AND #0x0F ; - LD (DISPLAYBUF+2),A ; - LD A,(LBA_TARGET_LO+1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+3),A ; - ; - LD A,(LBA_TARGET_LO) ; - AND #0x0F ; - LD (DISPLAYBUF),A ; - LD A,(LBA_TARGET_LO) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; - JP SEGDISPLAY1 ; - -;__SEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF TRACK, SECTOR, ST0, ST1 ON DSKY -; -;____________________________________________________________________________________________________ -SEGDISPLAY: - LD A, #0x82 ; - OUT (PIOCONT),A ; - LD A,(TRACK) ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,(TRACK) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,(SECTOR) ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,(SECTOR) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,(ST0) ; - AND #0x0F ; - LD (DISPLAYBUF+2),A ; - LD A,(ST0) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+3),A ; - LD A,(ST1) ; - AND #0x0F ; - LD (DISPLAYBUF),A ; - LD A,(ST1) ; - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; -SEGDISPLAY1: ; - LD HL,#DISPLAYBUF ; - LD BC,#7 ; - ADD HL,BC ; - LD B,#8 ; SET DIGIT COUNT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL DELAY12 ; WAIT - LD A,#0x0D0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE, DECODE, NORMAL) - OUT (PORTA),A ; OUTPUT TO PORT - LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PORTC),A ; OUTPUT TO PORT - CALL DELAY12 ; WAIT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL DELAY12 ; WAIT -SEGDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - OUT (PORTA),A ; OUT TO PORTA - LD A,#0 ; SET WRITE STROBE - OUT (PORTC),A ; OUT TO PORTC - CALL DELAY12 ; DELAY - LD A,#0x40 ; SET CONTROL PORT OFF - OUT (PORTC),A ; OUT TO PORTC - CALL DELAY12 ; WAIT - DEC HL ; INC POINTER - DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - RET - -DISPLAYBUF: .DB 01,02,03,04,05,06,07,08 - .ENDIF - .DB 00,00,00,00,00,00,00,00 - .DB 00,00,00,00,00,00,00,00 - .DB 00,00,00,00,00,00,00,00 - .DB 00,00,00,00,00,00,00,00 - - - -FLOPPYSTACK: .DB 00 -PARKSTACK: .DB 00,00,00,00 - -READ_DISK_PACKET: - .DB 0x0A8,00,00,00,00,01,00,00,00,01,00,00 -WRITE_DISK_PACKET: - .DB 0x2A,00,00,00,00,0x11,00,00,01,00,00,00 -ATAPI_REQUEST_SENSE: - .DB 3,00,00,00,0x11,00,00,00,00,00,00,00 - -; ******* TEXT STRINGS ******* - -TXT_RO_ERROR: - .DB CR,LF - .ascii "ERROR: WRITE TO READ ONLY DISK" - .DB END - - -TXT_STARTUP_MSG: - - .IF CONDSHORTMSG - .DB CR,LF - .ascii "CP/M-80 2.2C (JC0705-1) for " - .ascii "N8VEM - W/" - .IF CONDUSEVDU - .ascii "VDU " - .ENDIF - .IF CONDUSEDSKY - .ascii "DSKY " - .ENDIF - .IF CONDIDESOFT - .ascii "IDE " - .ENDIF - .IF CONDUSEATAPI - .ascii "ATAPI " - .ENDIF - .IF CONDUSEFLOPPY - .ascii "FLOPPY " - .IF COND144FLOPPY - .ascii "1.44M " - .ENDIF - .ENDIF - .DB CR,LF - .DB END - .ELSE - .ascii "CP/M V2.2C" - .DB END - .ENDIF - -; -; THE REMAINDER OF THE CBIOS IS RESERVED UNINITIALIZED -; DATA AREA, AND DOES NOT NEED TO BE A PART OF THE -; SYSTEM MEMORY IMAGE (THE SPACE MUST BE AVAILABLE, -; HOWEVER, BETWEEN "BEGDAT" AND "ENDDAT") -; - -; -; DISK COMMAND BLOCK -; -CMD: .DB 0 ; COMMAND READ OR WRITE, -UNIT: .DB 0 ; PHYSICAL DRIVE 0->3 -HEAD: .DB 0 ; HEAD SEL 0 OR 1 -DENS: .DB 2 ; DENSITY -EOTSEC: .DB 09 ; LAST SECTOR OF TRACK -GAP: .DB 0x1B ; VALUE FOR IRG -;SECSIZ: .DB 0x80 ; HOW MANY BYTES TO TRANSFER/4 -FSECSIZ: .dw 0x0200 ; actual sector size in bytes -DTL: .DB 0x0FF ; SIZE OF SECTOR -SRTHUT: .DB 0x7F ; STEP RATE AND HEAD UNLOAD TIME -HLT: .DB 5 ; HEAD LOAD TIME -MIN: .DB MINI ; LATCH BIT PATTERN FOR FDC9229 MINITRUE -PRE: .DB PRECOMP ; LATCH BIT PATTERN FOR FDC9229 PRECOMP125NS -; -; FLOPPY STATUS RESULT STORAGE -; -ST0: .DB 0 ; STORE STATUS 0 -ST1: .DB 0 ; ST1 -ST2: .DB 0 ; ST2 -SCYL: .DB 0 ; TRACK -SHEAD: .DB 0 ; HEAD 0 OR 1 -SREC: .DB 0 ; SECTOR -SNBIT: .DB 0 ; DENSITY -ST0A: .DB 0 ; STORE STATUS 0 -ST1A: .DB 0 ; ST1 -RETRY: .DB 0 ; RETRIES -RETRY1: .DB 0 ; RETRIES - -FLATCH_STORE: .DB 00 ; - -TRACK: .DW 0 ; TWO BYTES FOR TRACK # (LOGICAL) -PTRACK: .DW 0 ; TWO BYTES FOR TRACK # (PHYSICAL) -FTRACK: .DW 0 ; TWO BYTES FOR TRACK # (HEAD LOCATION) - -PAGER: .DB 1 ; COPY OF PAGER BYTE -DB_PAGER: .DB 0x0FF ; COPY OF PAGER BYTE (DEBUG) -SECTOR: .DW 0 ; TWO BYTES FOR SECTOR # (LOGICAL) -PSECTOR: .DW 0 ; TWO BYTES FOR SECTOR # (PHYSICAL) -SECST: .DW 0 ; SECTOR IN ROM/RAM START ADDRESS -DMAAD: .DW 0 ; DIRECT MEMORY ADDRESS -DISKNO: .DB 0 ; DISK NUMBER 0-15 -LBA_TARGET_LO: .DW 0 ; IDE HD PARTITION TARGET SECTOR (LOW 16 BITS) -LBA_TARGET_HI: .DW 0 ; IDE HD PARTITION TARGET SECTOR (HI 16 BITS, 12 USED) -IDEDEVICE: .DB 0 ; ATAPI DEVICE SELECTION FLAG - -IDE_LBA0: .DB 0 ; SET LBA 0:7 -IDE_LBA1: .DB 0 ; SET LBA 8:15 -IDE_LBA2: .DB 0 ; SET LBA 16:23 -IDE_LBA3: .DB 0 ; LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE -SECTOR_INDEX: .DB 1 ; WHERE 128 BYTE CP/M SECTOR IS IN 512 BYTE IDE HD SECTOR -; -; SCRATCH RAM AREA FOR BDOS USE -BEGDAT: -; = $ ; BEGINNING OF DATA AREA -DIRBF: .DS 128 ; SCRATCH DIRECTORY AREA -ALL00: .DS 65 ; ALLOCATION VECTOR 0 (DSM/8 = 1 BIT PER BLOCK) 44 -ALL01: .DS 33 ; ALLOCATION VECTOR 1 (225/8) -ALL02: .DS 256 ; ALLOCATION VECTOR 2 (511/8) -ALL03: .DS 256 ; ALLOCATION VECTOR 3 (511/8) -ALL04: .DS 65 ; ALLOCATION VECTOR 4 (497/8) -ALL05: .DS 65 ; ALLOCATION VECTOR 4 (495/8) -ALL06: .DS 65 ; ALLOCATION VECTOR 4 (495/8) -ALL07: .DS 135 ; ALLOCATION VECTOR 7 (495/8) -CHK00: .DS 5 ; 720K MEDIA -CHK01: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK02: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK03: .DS 128 ; 8M MEDIA -CHK04: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK05: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK06: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK07: .DS 15 ; 1.44M MEDIA -; -CUDISK: .DS 1 ; CURRENT PHYSICAL DISK ID IN BUFFER -CUSECTOR: .DW 1 ; CURRENT PHYSICAL DISK SECTOR IN BUFFER -CUTRACK: .DW 2 ; CURRENT PHYSICAL DISK TRACK IN BUFFER -SECTOR_BUFFER: .DS 520 ; STORAGE FOR 512 BYTE IDE HD SECTOR -ENDDAT: -; .EQU $ ; END OF DATA AREA -DSTEMP: -DATSIZ = DSTEMP - BEGDAT ; SIZE OF DATA AREA - - -;dwg; .ORG 0FDFFH -LASTBYTE: .DB 0 - -; .END - - - - - -_cbios_end:: - .area _CODE - .area _CABS diff --git a/branches/s100/cpurom/src/cbiosn8.s b/branches/s100/cpurom/src/cbiosn8.s deleted file mode 100644 index 709f9826..00000000 --- a/branches/s100/cpurom/src/cbiosn8.s +++ /dev/null @@ -1,1708 +0,0 @@ -;-------------------------------------------------------- -; cbioshc.s derived from CPM22-HC.ASM by dwg 5/18-30/2011 -;-------------------------------------------------------- - .module cbioshc - .optsdcc -mz80 -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _cbioshc -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _CBIOS -_cbioshc_start:: -_cbioshc: - -;************************************************************** -;* -;* C B I O S f o r -;* -;* T e s t P r o t o t y p e -;* -;* by Andrew Lynch, with input from many sources -;* Updated 24-Mar-2009 Max Scane - changed seldsk: to not save bogus drive value -;* changed a: to be ram drive, B: to be rom disk -;* Updated 1-Jun-2010 Max Scane - Changed DPBs to be more sane -;* Updated 1-Jul-2010 Max Scane - Added PPIDE driver and conditionals -;* Updated April 2011 Max Scane - Adapted for the N8VEM Home Computer -;************************************************************** -; -; SKELETAL CBIOS FOR FIRST LEVEL OF CP/M 2.0 ALTERATION -; WITH MODS FOR CP/M ROMDISK AND RAMDISK. -; -; ENTIRELY IN 8080 MNEUMONICS (SO ASM CAN BE USED) -; BUT ASSUMES A Z80! (remove) -; - -MEM = 60 ; DOUGTEMP DOUGTEMP - - -;MSIZE .EQU 20 ;CP/M VERSION MEMORY SIZE IN KILOBYTES -;MSIZE .EQU 62 ;CP/M VERSION MEMORY SIZE IN KILOBYTES -; MEM defined in CPM22 above, line 0015 - -MSIZE = MEM ;CP/M VERSION MEMORY SIZE IN KILOBYTES - -; -; "BIAS" IS ADDRESS OFFSET FROM 3400H FOR MEMORY SYSTEMS -; THAN 16K (REFERRED TO AS "B" THROUGHOUT THE TEXT). -; - -BIAS = (MSIZE-20)*1024 - -CCP = 0x3400+BIAS ; base of ccp - -BDOS = CCP+0x0806 ; base of BDOS - -BIOS = CCP+0x1600 ; base of BIOS - -CDISK = 0x0004 ; current disk number 0=a,...,15=p - -; IOBYTE already defined in CPM22 above, line 0017 -;IOBYTE .EQU 0003H ;INTEL I/O BYTE - -; since the assembly has been broken into pieces, -; this symbols wasn't previously encountered. -; It could be exported from other module, but why? -IOBYTE = 0x0003 - -; -; CONSTANTS - - -END = 0x0FF - - -CR = 0x0d -LF = 0x0a - -DEFIOB = 0x94 ; default IOBYTE (TTY,RDR,PUN,LPT) - -; - -ROMSTART_MON = 0x0100 ; where the monitor is stored in ROM - -RAMTARG_MON = 0x0f800 ; where the monitor starts in RAM - -MOVSIZ_MON = 0x0800 ; monitor is 2K in length - -ROMSTART_CPM = 0x0900 ; where ccp+bdos+bios is stored in ROM - -RAMTARG_CPM = 0x0D400 ; where ccp+bdos+bios starts in RAM - -;dwg; INTERESTING - 0x15FF is 4K+1K+512-1, not 5KB -;dwg;MOVSIZ_CPM: .EQU $15FF ; CCP, BDOS IS 5KB IN LENGTH -MOVSIZ_CPM = 0x15FF ; ccp+bdos is 5KB in length - -HC_REG_BASE = 0x80 ; N8 I/I Regs $80-9F - -PPI1 = HC_REG_BASE+0x00 - -ACR = HC_REG_BASE+0x14 - -RMAP = ACR+2 - -IO_REG_BASE = 0x40 ; IO reg base offset for Z1x80 - -CNTLA0 = IO_REG_BASE+0x00 - -CNTLB0 = IO_REG_BASE+0x02 - -STAT0 = IO_REG_BASE+0x04 - -TDR0 = IO_REG_BASE+0x06 - -RDR0 = IO_REG_BASE+0x08 - -ASEXT0 = IO_REG_BASE+0x12 - -CBR = IO_REG_BASE+0x38 - -BBR = IO_REG_BASE+0x39 - -CBAR = IO_REG_BASE+0x3A - -; -; -; PIO 82C55 I/O IS ATTACHED TO THE FIRST IO BASE ADDRESS - -IDELSB = PPI1+0 ; LSB - -IDEMSB = PPI1+1 ; MSB - -IDECTL = PPI1+2 ; Control Signals - -PIO1CONT = PPI1+3 ; Control Byte PIO 82C55 - -; PPI control bytes for read and write to IDE drive - -rd_ide_8255 = 0b10010010 ; ide_8255_ctl out ide_8255_lsb/msb input - -wr_ide_8255 = 0b10000000 ; all three ports output - -;ide control lines for use with ide_8255_ctl. Change these 8 -;constants to reflect where each signal of the 8255 each of the -;ide control signals is connected. All the control signals must -;be on the same port, but these 8 lines let you connect them to -;whichever pins on that port. - -ide_a0_line = 0x01 ; direct from 8255 to ide interface - -ide_a1_line = 0x02 ; direct from 8255 to ide intereface - -ide_a2_line = 0x04 ; direct from 8255 to ide interface - -ide_cs0_line = 0x08 ; inverter between 8255 and ide interface - -ide_cs1_line = 0x10 ; inverter between 8255 and ide interface - -ide_wr_line = 0x20 ; inverter between 8255 and ide interface - -ide_rd_line = 0x40 ; inverter between 8255 and ide interface - -ide_rst_line = 0x80 ; inverter between 8255 and ide interface - -;------------------------------------------------------------------ -; More symbolic constants... these should not be changed, unless of -; course the IDE drive interface changes, perhaps when drives get -; to 128G and the PC industry will do yet another kludge. - -;some symbolic constants for the ide registers, which makes the -;code more readable than always specifying the address pins - -ide_data = ide_cs0_line -ide_err = ide_cs0_line + ide_a0_line -ide_sec_cnt = ide_cs0_line + ide_a1_line -ide_sector = ide_cs0_line + ide_a1_line + ide_a0_line -ide_cyl_lsb = ide_cs0_line + ide_a2_line -ide_cyl_msb = ide_cs0_line + ide_a2_line + ide_a0_line -ide_head = ide_cs0_line + ide_a2_line + ide_a1_line -ide_command = ide_cs0_line + ide_a2_line + ide_a1_line + ide_a0_line -ide_status = ide_cs0_line + ide_a2_line + ide_a1_line + ide_a0_line -ide_control = ide_cs1_line + ide_a2_line + ide_a1_line -ide_astatus = ide_cs1_line + ide_a2_line + ide_a1_line + ide_a0_line - -;IDE Command Constants. These should never change. - -ide_cmd_recal = 0x10 -ide_cmd_read = 0x20 -ide_cmd_write = 0x30 -ide_cmd_init = 0x91 -ide_cmd_id = 0x0ec -ide_cmd_spindown = 0xe0 -ide_cmd_spinup = 0xe1 - - -; .ORG BIOS ;ORIGIN OF THIS PROGRAM - - -;dwg;NSECTS .EQU ($-CCP)/128 ;WARM START SECTOR COUNT - -; -; JUMP VECTOR FOR INDIVIDUAL SUBROUTINES - - JP BOOT ;COLD START -WBOOTE: JP WBOOT ;WARM START - JP CONST ;CONSOLE STATUS - JP CONIN ;CONSOLE CHARACTER IN - JP CONOUT ;CONSOLE CHARACTER OUT - JP LIST ;LIST CHARACTER OUT (NULL ROUTINE) - JP PUNCH ;PUNCH CHARACTER OUT (NULL ROUTINE) - JP READER ;READER CHARACTER OUT (NULL ROUTINE) - JP HOME ;MOVE HEAD TO HOME POSITION - JP SELDSK ;SELECT DISK - JP SETTRK ;SET TRACK NUMBER - JP SETSEC ;SET SECTOR NUMBER - JP SETDMA ;SET DMA ADDRESS - JP READ ;READ DISK - JP WRITE ;WRITE DISK - JP LISTST ;RETURN LIST STATUS (NULL ROUTINE) - JP SECTRN ;SECTOR TRANSLATE - -; -; FIXED DATA TABLES FOR ALL DRIVES -; 0= RAMDISK, 1=ROMDISK, 2=HDPART1, 3=HDPART2 -; DISK PARAMETER HEADER FOR DISK 00 (RAM Disk) -DPBASE: - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK0 - .DW CHK00,ALL00 - -; DISK PARAMETER HEADER FOR DISK 05 (Large ROM Disk) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK5 - .DW CHK05,ALL05 - - -; DISK PARAMETER HEADER FOR DISK 02 (8MB disk Partition) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK2 - .DW CHK02,ALL02 - -; DISK PARAMETER HEADER FOR DISK 03 (8MB disk Partition) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK3 - .DW CHK03,ALL03 - -; DISK PARAMETER HEADER FOR DISK 04 (??? third disk partition ???) - .DW 0x0000,0x0000 - .DW 0x0000,0x0000 - .DW DIRBF,DPBLK4 - .DW CHK04,ALL04 - -DPBLK0: ;DISK PARAMETER BLOCK (RAMDISK 512K, 448K usable) -SPT_1: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_1: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_1: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_1: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_1: .DW 223 ; BLOCKSIZE [2048] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_1: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_1: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_1: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_1: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_1: .DW 2 ; 2 TRACK RESERVED [FIRST 64K OF RAM] -; Note: changed to 2 tracks to skip over the 1st 64KB or RAM. - -DPBLK1: ;DISK PARAMETER BLOCK (ROMDISK 32KB WITH 16 2K TRACKS, 22K usable) -SPT_0: .DW 16 ; 16 SECTORS OF 128 BYTES PER 2K TRACK -BSH_0: .DB 3 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_0: .DB 7 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_0: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_0: .DW 31 ; BLOCKSIZE [1024] * NUMBER OF BLOCKS + 1 = DRIVE SIZE -DRM_0: .DW 31 ; NUMBER OF DIRECTORY ENTRIES -AL0_0: .DB 0b10000000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_0: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_0: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_0: .DW 5 ; FIRST 5 TRACKS TRACKS RESERVED (10K FOR SYSTEM) - ; SYSTEM IS ROM LOADER, CCP, BDOS, CBIOS, AND MONITOR - ; - ; IMPORTANT NOTE: TRACKS $00 - $04 OF 2K BYTES - ; EACH ARE MARKED WITH THE OFF_0 SET TO 5 AS - ; SYSTEM TRACKS. USABLE ROM DRIVE SPACE - ; STARTING AFTER THE FIFTH TRACK (IE, TRACK $05) - ; MOST LIKELY FIX TO THIS IS PLACING A DUMMY - ; FIRST 10K ROM CONTAINS THE ROM LOADER, MONITOR, - ; CCP, BDOS, BIOS, ETC (5 TRACKS * 2K EACH) - - -DPBLK2: ;DISK PARAMETER BLOCK (IDE HARD DISK 8MB) -SPT_2: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_2: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_2: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_2: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_2: .DW 2039 ; BLOCKSIZE [4096] * NUMBER OF BLOCKS + 1 = DRIVE SIZE - ; HD PARTITION 2 IS 16128 SECTORS LONG - ; AT 512 BYTES EACH WHICH IS - ; 2016 BLOCKS AT 4096 BYTES A PIECE. -DRM_2: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_2: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_2: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_2: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_2: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - -DPBLK3: ;DISK PARAMETER BLOCK (IDE HARD DISK 8MB) -SPT_3: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_3: .DB 5 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_3: .DB 31 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_3: .DB 1 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_3: .DW 2039 ; BLOCKSIZE [4096] * NUMBER OF BLKS + 1 = DRIVE SIZE - ; HD PARTITION 3 IS 16128 SECTORS LONG - ; AT 512 BYTES EACH WHICH IS - ; 2016 BLOCKS AT 4096 BYTES A PIECE. -DRM_3: .DW 511 ; NUMBER OF DIRECTORY ENTRIES -AL0_3: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_3: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_3: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_3: .DW 1 ; 1 TRACK (32K) RESERVED FOR SYSTEM - -DPBLK4: ;DISK PARAMETER BLOCK (IDE HARD DISK 1024K) -SPT_4: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_4: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_4: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_4: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_4: .DW 497 ; BLKSIZE [2048] * NUMBER OF BLKS + 1 = DRIVE SIZE - ; HD PARTITION 4 IS 4032 SECTORS LONG - ; AT 512 BYTES EACH WHICH IS - ; 1008 BLOCKS AT 2048 BYTES A PIECE. - ; NOT USING ALL OF THE AVAILABLE SECTORS SINCE THIS - ; DRIVE IS INTENDED TO EMULATE A ROM DRIVE AND COPIED - ; INTO A ROM IN THE FUTURE. -DRM_4: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_4: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_4: .DB 0b00000000 ; DIRECTORY CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_4: .DW 0 ; SIZE OF DIRECTORY CHECK [0 IF NON REMOVEABLE] -OFF_4: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF PARTITION] - -; -DPBLK5: ;DISK PARAMETER BLOCK (ROMDISK 1MB) -SPT_5: .DW 256 ; 256 SECTORS OF 128 BYTES PER 32K TRACK -BSH_5: .DB 4 ; BLOCK SHIFT FACTOR (SIZE OF ALLOCATION BLOCK) -BLM_5: .DB 15 ; PART OF THE ALLOCATION BLOCK SIZE MATH -EXM_5: .DB 0 ; DEFINES SIZE OF EXTENT (DIRECTORY INFO) -DSM_5: .DW 495 ; BLKSIZE [2048] * NUMBER OF BLKS +1 =DRIVE SIZE -;DSM_5: .DW 511 ; BLKSIZE [2048] * NUMBER OF BLKS +1 =DRIVE SIZE -DRM_5: .DW 255 ; NUMBER OF DIRECTORY ENTRIES -AL0_5: .DB 0b11110000 ; BIT MAP OF SPACE ALLOCATED TO DIRECTORY -AL1_5: .DB 0b00000000 ; DIR CAN HAVE UP TO 16 BLOCKS ALLOCATED -CKS_5: .DW 0 ; SIZE OF DIR CHECK [0 IF NON REMOVEABLE] -OFF_5: .DW 1 ; 1 TRACK RESERVED [FIRST 32K OF ROM] - -; -; END OF FIXED TABLES -; -; INDIVIDUAL SUBROUTINES TO PERFORM EACH FUNCTION - -BOOT: ;SIMPLEST CASE IS TO JUST PERFORM PARAMETER INITIALIZATION - di ; disable interrupts -; IM 1 ; SET INTERRUPT MODE 1 -; .DB $ED,$56 ; Z80 "IM 1" INSTRUCTION - - ld a,#0x80 - -; out0 ACR -; .BYTE $ED,$39,ACR ; ensure that the ROM is switched out - - out (ACR),a - - ld a,#1 - ld (CDISK),a ; select disk 0 - - ld a,#DEFIOB - ld (IOBYTE),a - -; ei ; enable interrupts - - ld hl,#TXT_STARTUP_MSG - CALL PRTMSG - - JP GOCPM ;INITIALIZE AND GO TO CP/M - -; -WBOOT: ;SIMPLEST CASE IS TO READ THE DISK UNTIL ALL SECTORS LOADED - ; WITH A ROMDISK WE SELECT THE ROM AND THE CORRECT PAGE [0] - ; THEN COPY THE CP/M IMAGE (CCP, BDOS, BIOS, MONITOR) TO HIGH RAM - ; LOAD ADDRESS. - - DI ; DISABLE INTERRUPT - - ld SP,#0x0080 ; use space below buffer for stack - -; IM 1 ; SET INTERRUPT MODE 1 -; .DB $ED,$56 ; Z80 "IM 1" INSTRUCTION - - xor a,a - - ; CHEAP ZERO IN ACC -; mvi a,00h ; switch in the ROM -; out0 ACR -; .BYTE $ED,$39,ACR - - out (ACR),a - - xor a,a - -; out0 RMAP -; .BYTE $ED,$39,$F6 - - out (RMAP),a ; set the rom map - - ; Just reload CCP and BDOS - - ld hl,#ROMSTART_CPM ; where in rom cp/m is stored (1st byte) - ld de,#RAMTARG_CPM ; where in ram to move ccp+BDOS to - ld bc,#MOVSIZ_CPM - ldir - - ld a,#0x80 - out (ACR),a - -; EI ; ENABLE INTERRUPTS - -; -; END OF LOAD OPERATION, SET PARAMETERS AND GO TO CP/M -GOCPM: - ;CPU RESET HANDLER - ld a,#0xC3 ; C32 is a jump opcode - ld (0x0000),a - ld hl,#WBOOTE ; address of warm boot - ld (0x0001),hl ; set addr field for jmp at 0 - - ld (0x0005),a ; for jump to bdos - ld hl,#BDOS - ld (0x0006),hl - - ld bc,#0x0080 ; default DMA address - CALL SETDMA - - ld a,(CDISK) ; get current disk number - ld c,a ; send to the ccp - JP CCP ;GO TO CP/M FOR FURTHER PROCESSING - - -; -;---------------------------------------------------------------------------------------------------------------------- -; N8VEM Home computer I/O handlers -; -; This implementation uses IOBYTE and allocates devices as follows: -; -; TTY - Driver for the Z180 ASCI port 0 -; CRT - Driver for the -; UC1 - Driver for the -; xxx - Driver for the -; -; Logical device drivers - these pass control to the physical -; device drivers depending on the value of the IOBYTE -; - -CONST: ;CONSOLE STATUS, RETURN 0FFH IF CHARACTER READY, 00H IF NOT - - ld a,(IOBYTE) - and a,#3 - cp #0 - jp z,TTYISTS - - cp #1 - jp z,CRTISTS - - jp NULLSTS - - - - -CONIN: ;CONSOLE CHARACTER INTO REGISTER A - ld a,(IOBYTE) - and a,#3 - cp #0 - jp z,TTYIN - cp #1 - jp z,CRTIN - jp NULLIN - - -CONOUT: ;CONSOLE CHARACTER OUTPUT FROM REGISTER C - ld a,(IOBYTE) - and a,#3 ; isolate console bits - cp #0 - jp z,TTYOUT - cp #1 - jp z,CRTOUT - jp NULLOUT - -LIST: ;LIST CHARACTER FROM REGISTER C - jp NULLOUT - - - -LISTST: ;RETURN LIST STATUS (0 IF NOT READY, 1 IF READY) - jp NULLSTS - - ; -PUNCH: ;PUNCH CHARACTER FROM REGISTER C - jp NULLOUT - -; -READER: ;READ CHARACTER INTO REGISTER A FROM READER DEVICE - - jp NULLIN ; currently not used - - - -;---------------------------------------------------------------------------------------------------------------------------------------- -; -; Here are the physical io device drivers -; -; Null driver - this is a dummy driver for the NULL device - -NULLIN: - ld a,#0x1a - ret - -NULLOUT: - ld a,c - ret - -NULLSTS: - ld a,#1 - ret - -; -;--------------------------------------------------------------------------------------------------------------------------------------------- -; -; TTY Driver (programmed i/o) this is the driver for the Home Computer console port -; -TTYIN: - CALL TTYISTS; IS A CHAR READY TO BE READ FROM UART? - cp #0 - jp z,TTYIN - -; IN0 A,(RDR0) - -;dwg; .BYTE $ED,$38,RDR0 - .byte 0xED,0x38,RDR0 - - ret - -TTYOUT: - call TTYOSTS - and a,a - jp z,TTYOUT ; if not repeat - - ld a,c ; get to accum - -; OUT0 (TDR0),A - .byte 0xed,0x39,TDR0 - - ret - -TTYISTS: -; IN0 A,(STAT0) -;dwg; .BYTE $ED,$38,STAT0 -;;dwg;; in0 a,(STAT0) - .byte 0xed,0x38,STAT0 - - and a,#0x80 - ret z ; is there a char ready? 0=no 1=yes - ld a,#0xff - ret ; NO, LEAVE $00 IN A AND RETURN - -TTYOSTS: -; IN0 A,(STAT0) -;dwg; .BYTE $ED,$38,STAT0 -;;dwg;; in0 a,(STAT0) - .byte 0xed,0x38,STAT0 - - and a,#2 - ret z - ld a,#0xff - - ret ; NO, LEAVE $00 IN A AND RETURN -;--------------------------------------------------------------------------------------------------------------------------------------------- -; CRT Driver - This is the driver for the Prop VDU -; - -CRTIN: - jp NULLIN - -CRTOUT: - jp NULLOUT - -CRTISTS: - jp NULLSTS - -CRTOSTS: - jp NULLSTS - - -;--------------------------------------------------------------------------------------------------------------------------------------------- - ;; -; I/O DRIVERS FOR THE DISK FOLLOW -; FOR NOW, WE WILL SIMPLY STORE THE PARAMETERS AWAY FOR USE -; IN THE READ AND WRITE SUBROUTINES -; - -; -; SELECT DISK GIVEN BY REGISTER C -; -SELDSK: - - ld hl,#0 ; error return code - - ld a,c - - cp a,#4 ; must be between 0 and 4 - ret nc ; no carry if 4,5,6,7 - ld a,c - ld (DISKNO),a ; save valid disk number - -; -; DISK NUMBER IS IN THE PROPER RANGE -; COMPUTE PROPER DISK PARAMETER HEADER ADDRESS - - ld l,a ; l = disk num 0,1,2,3,4 - ld h,#0 ; high order - add hl,hl ; * 2 - add hl,hl ; * 4 - add hl,hl ; * 8 - add hl,hl ; * 16 (size of each header) - ld de,#DPBASE - add hl,de ; hl = .DPBASE(DISKNO*16) - RET -; -HOME: ;MOVE TO THE TRACK 00 POSITION OF CURRENT DRIVE - ; TRANSLATE THIS CALL INTO A SETTRK CALL WITH PARAMETER 00 - - ld bc,#0 ; select track zero - -; CALL SETTRK -; RET ;WE WILL MOVE TO 00 ON FIRST READ/WRITE - ; FALL THROUGH TO SETTRK TO STORE VALUE - -SETTRK: ;SET TRACK GIVEN BY REGISTER BC - ld h,b - ld l,c - ld (TRACK),hl - RET -; -SETSEC: ;SET SECTOR GIVEN BY REGISTER BC - ld h,b - ld l,c - ld (SECTOR),hl - RET -; -; TRANSLATE THE SECTOR GIVEN BY BC USING THE -; TRANSLATE TABLE GIVEN BY DE -; ONLY USED FOR FLOPPIES! FOR ROMDISK/RAMDISK IT'S 1:1 -; DO THE NEXT ROUTINE IS A NULL (RETURNS THE SAME) -SECTRN: - ld h,b - ld l,c - RET -; - -SETDMA: ;SET DMA ADDRESS GIVEN BY REGISTERS B AND C - ld l,c - ld h,b - ld (DMAAD),hl - RET - -; READ DISK -; USES DE,DL, BC, ACC FLAGS -; Z80 COULD USE BLOCK MOVE [LDIR] BUT WRITTEN IN 8080 -READ: -; DI ; DISABLE INTERRUPTS - - ld a,(DISKNO) - ; FIND OUT WHICH DRIVE IS BEING REQUESTED - ; ARE WE READING RAM OR ROM? - cp #0 - jp z,READ_RAM_DISK - - cp #1 - jp z,READ_ROM_DISK - - cp #2 - jp z,READ_HDPART1 - - cp #3 - jp z,READ_HDPART2 ; READ FROM 8 MB IDE HD, PARTITION 2 - - cp #4 - jp z,READ_HDPART3 ; READ FROM 1 MB IDE HD, PARTITION 4 - - cp #5 - jp z,READ_HDPART4 ; READ FROM 1 MB IDE HD, PARTITION 5 - - ld a,#1 ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - ret - - -; -; WRITE DISK -; -WRITE: -; DI ; DISABLE INTERRUPTS - - ld a,(DISKNO) ; get drive - -; ORA A ; SET FLAGS - - cp #0 ; find out which drive is being requested - - jp z,WRITE_RAM_DISK ; write to 448K ram disk - - cp #1 - jp z,RDONLY ; jump to read only routine - - ; READ ONLY, FROM 22K EEPROM DISK, ERROR ON WRITE - cp #2 - jp z,WRITE_HDPART1 ; write to 8MB IDE HD, Part 2 - - cp #3 - jp z,WRITE_HDPART2 ; write to 8MB IDE HD, Part 3 - - cp #4 - jp z,WRITE_HDPART3 ; write to 1MB IDE HD, Part 4 - - cp #5 - jp z,WRITE_HDPART4 ; write to 1MB IDE HD Part 5 - - - ; IF NONE OF THE OTHER DISKS, IT MUST BE - ; THE RAM DISK, SO FALL THROUGH - - ld a,#1 ; send bad sector error back - ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - ret - - - -RDONLY: -; -; HANDLE WRITE TO READ ONLY -; -; SENDS A MESSAGE TO TERMINAL THAT ROM DRIVE IS NOT WRITEABLE -; DOES A PAUSE THEN RETURNS TO CPM WITH ERROR FLAGGED. THIS IS -; DONE TO ALLOW A POSSIBLE GRACEFUL EXIT (SOME APPS MAY PUKE). -; - - ; CODE TBD, PRINT A HEY WRONG DISK AND PAUSE 5 SEC AND - ; CONTINUE. - - ld hl,#TXT_RO_ERROR ; set hp --> error msg - CALL PRTMSG ; PRINT ERROR MESSAGE - - ld a,#1 ; send bad sector error back - ; BDOS WILL ALSO PRINT ITS OWN ERROR MESSAGE - ; ADD 5 SECOND PAUSE ROUTINE HERE - ret - -; -;-------------------------------------------------------------------------------------------------------------- -; -; DISK DRIVERS... -; -; DRIVER NEED TO DO SEVERAL THINGS FOR ROM AND RAM DISKS. -; - INTERRUPTS ARE NOT ALLOWED DURING LOW RAM/ROM ACCESS (DISABLE!) -; -TRANSLATE TRACK AND SECTOR INTO A POINTER TO WHERE THE 128 BYTE -; SECTOR BEGINS IN THE RAM/ROM -; -TRANSLATE THE DRIVE INTO A RAM/ROM SELECT, COMBINE WITH TRACK ADDRESS -; AND SEND TO THE MAP PORT. -; -COPY 128 BYTE FROM OR TO THE ROM/RAMDISK AND MEM POINTED TO BY DMA -; ADDRESS PREVIOUSLY STORED. -; -RESTORE MAP PORT TO PRIOR CONDITION BEFOR READ/WRITE -; -; - FIRST TRICK IS THAT WE MADE SECTORS 256 AS 256*128=32768. SO WE COPY -; THE LOW SECTOR ADDRESS TO THE LOW BYTE OF THE HL REGISTER AND THEN -; MULTIPLY BY 128. THIS RESULTS IN THE STARTING ADDR IN THE RAM OR ROM -; (0000 -> 7F80H) 32K PAGE. -; -; - TRICK TWO IS THE TRACK ADDRESS EQUALS THE 32K PAGE ADDRESS AND IS A -; DIRECT SELECT THAT CAN BE COPIED TO THE MAP PORT D0 THROUGH D5. D7 -; SELECTS THE DRIVE (ROM OR RAM). -; THAT MEANS THE LOW BYTE OF TRACK CONTAINS THE D0-D5 VALUE AND -; DISKNO HAS THE DRIVE SELECTED. WE FIRST COPY DISKNO TO ACC -; AND RIGHTSHIFT IT TO PLACE THAT IN BIT7, WE THEN ADD LOW BYTE OF -; TRACK TO ACC AND THEN SEND THAT TO THE MAP PORT. -; -; NOTE 1: A WRITE TO ROM SHOULD BE FLAGGED AS AN ERROR. -; NOTE 2: RAM MUST START AS A "FORMATTED DISK" IF BATTERY BACKED UP -; IT'S A DO ONCE AT COLD COLD START. IF NOT BATTERY BACKED UP -; IT WILL HAVE TO BE DONE EVERY TIME THE SYSTEM IS POWERED. -; FORMATTING THE RAM IS SIMPLE AS CLEARING THE DIRECTORY AREA -; TO A VALUE OF E5H (THE FIRST 8K OF TRACK 1 OR THE RAMDISK). -; IT COULD BE DONE AS A SIMPLE UTILITY PROGRAM STORED IN ROMDISK -; OR ANYTIME COLBOOT IS CALLED(LESS DESIREABLE). -; -; -WE NOW CAN COPY TO/FROM AS CORRECT FOR THE DEVICE 128 BYTES (SECTOR) -; TO OR FROM THE DMA ADDRESS. ALMOST! SINCE ROM OR RAM IS BEING PAGED -; WE HAVE TO COPY ANYTHING DESTINED FOR BELOW 8000H TO TEMP BUFFER -; THEN HANDLE THE PAGING. -; -; -; - LAST STEP IS TO RESTORE THE MAP PORT TO POINT TO THE RAM (TRACK 0) -; SO THE CP/M MEMORY MAP IS ALL RAM AGAIN AND NOT POINTING INTO THE -; DATA AREAS OR THE "DISK". -; SINCE THE RAM 0TH PAGE IS NOMINALLY THE LOW 32K OF RAM IN THE i -; SYSTEM WE CAN SEND A SIMPLE MVI A,80H ; OUT MPCL_ROM; MVI A,00H ; -; OUT MPCL_RAM. -; -; - THE READ OR WRITE OPERATION IS DONE. -; -; -; -; -; -; - - ; ACCESS ALGORITHM (ONLY APPLICABLE TO 32K ROM PART!) -READ_RAM_DISK: - DI ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - - ld hl,(TRACK) ; multiply by 8 (4k segs) - -;dwg; dad h ; *2 - add hl,hl - -;dwg; dad h ; *4 - add hl,hl - -;dwg; dad h ; *8 - add hl,hl - -;dwg; MOV A,L ; get track in L - ld a,l - -; out0 BBR ; select RAM bank - -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .byte 0xed,0x39,BBR - - ld hl,#TMPBUF ; load hl with temp buf addr - ld d,h ; get it into de - ld e,l - ld hl,(SECST) ; rom/ram addr - ld bc,#128 - ldir - -; -; NOW WITH THE ROM/RAM DATA IN THE BUFFER WE CAN NOW MOVE IT TO THE -; DMA ADDRESS (IN RAM) -; - - ld a,#0 ; return to system bank - -; out0 BBR ; select RAM bank - -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .db 0xed,0x39,BBR - -; CALL RPAGE ; SET PAGE TO CP/M RAM - -; EI ; RE-ENABLE INTERRUPTS - - ld hl,(DMAAD) ; load hl with dma addr - ld e,l - ld d,h ; get it into de - ld hl,#TMPBUF ; get rom/ram addr - ld bc,#128 - ldir - - ld a,#0 - RET - -READ_ROM_DISK: - DI ; IF RAM, PROCEED WITH NORMAL TRACK/SECTOR READ - CALL SECPAGE ; SETUP FOR READ OF RAM OR ROM DISK - CALL PAGERB ; SET PAGER WITH DRIVE AND TRACK - - ld hl,#TMPBUF ; load hl with temp buf address - ld d,h - ld e,l ; get it into de - ld hl,(SECST) ; rom/ram address - ld bc,#128 - ldir - -; -; NOW WITH THE ROM/RAM DATA IN THE BUFFER WE CAN NOW MOVE IT TO THE -; DMA ADDRESS (IN RAM) -; - CALL RPAGE ; SET PAGE TO CP/M RAM -; EI ; RE-ENABLE INTERRUPTS - - ld hl,(DMAAD) ; load hl with dma address - ld e,l - ld d,h - ld hl,#TMPBUF ; get rom/ram address - ld bc,#128 - ldir - - ld a,#0 - ret - - -WRITE_RAM_DISK: - - ld hl,#TMPBUF ; load hl with temp buf address - ld d,h - ld e,l - ld hl,(DMAAD) - ld bc,#128 - ldir - -; -; NOW THAT DATA IS IN THE TEMP BUF WE SET TO RAM PAGE -; FOR WRITE. -; - DI - CALL SECPAGE ; GET RAM PAGE WRITE ADDRESS - - ld hl,(TRACK) - - add hl,hl ; *2 multiply by 8 (4k segs) - add hl,hl ; *4 - add hl,hl ; *8 - ld a,l ; get track in l - -; out0 BBR ; select RAM bank -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .db 0xed,0x39,BBR - - ld hl,(SECST) ; load hl with dma addr (where to write to) - ld d,h ; get it into de - ld e,l - ld hl,#TMPBUF ; get temp buffer address - ld bc,#128 - ldir - - ld a,#0 ; return to system bank - -; out0 BBR ; select RAM bank -;dwg; .BYTE $ED,$39,BBR -;;dwg;; out0 BBR - .db 0xed,0x39,BBR - -; EI - ; RE-ENABLE INTERRUPTS - ld a,#0 - ret - -;------------------------------------------------------------------- - -; Logical disk drivers - -READ_HDPART1: - - ld hl,#1 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP READ_HDPARTX - -READ_HDPART2: - ld hl,#0x4001 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP READ_HDPARTX - -READ_HDPART3: -READ_HDPART4: - ret - - -READ_HDPARTX: - - ; BDOS TRACK PARAMETER (16 BITS) - ; BDOS SECTOR PARAMETER (16 BITS) - - ld hl,(TRACK) ; load track number (word) - ld b,l ; save lower 8 bits (tracks 0-255) - ld hl,(SECTOR) ; load sector number (word) - ld h,b ; hl is 8 bit track in h, 8 bit sector in l - CALL CONVERT_IDE_SECTOR_CPM ; COMPUTE WHERE CP/M SECTOR IS ON THE - ; IDE PARTITION - - ; MAP COMPUTED IDE HD SECTOR TO LBA REGISTERS - - ; LBA REGISTERS STORE 28 BIT VALUE OF IDE HD SECTOR ADDRESS - - ld a,(LBA_TARGET_LO) ; load LBA reg 0 with sector addr to read - ld (IDE_LBA0),a - ld a,(LBA_TARGET_LO+1) ; load LBA reg 1 with sector addr t read - ld (IDE_LBA1),a - ld a,(LBA_TARGET_HI) ; load LBA reg 2 with sector addr to read - ld (IDE_LBA2),a - ld a,(LBA_TARGET_HI+1) ; load LBA reg 3 with sector addr to read - and a,#0b00001111 ; only lower 4 bits are valid - add a,#0b11100000 ; enable LBA bits 5:7=111 in IDE_LBA3 - ld (IDE_LBA3),a - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - -; NEED TO ADD ERROR CHECKING HERE, CARRY FLAG IS SET IF IDE_READ_SECTOR SUCCESSFUL! - - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ IDE HD SECTOR BUFFER - - ld hl,#SECTOR_BUFFER ; load hl with sector buffer address - - ld a,(SECTOR_INDEX) ; get the sector index (off in buff) - - RRC a ; MOVE BIT 0 TO BIT 7 - RRC a ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - - ld d,#0 ; put result as 16 value in de, upper byte in d is 0 - - ld e,a ; put addr offset in e - - add hl,de ; multiply by 2, total mult is x 128 - - add hl,de ; cp/m sect starting addr in IDE HD sector buffer - - ; COPY CP/M SECTOR TO BDOS DMA ADDRESS BUFFER - - ld D,H ; TRANSFER HL REGISTERS TO DE - ld E,L - ld hl,(DMAAD) ; LOAD HL WITH DMA ADDRESS - ex de,hl - ld bc,#128 - ldir - -; EI ; RE-ENABLE INTERRUPTS - - ld a,#0 ; return err code read successful a=0 - ret - - - - -;------------------------------------------------------------------- - - -WRITE_HDPART1: - -; DI ; DISABLE INTERRUPTS - - ld hl,#1 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP WRITE_HDPARTX - - -WRITE_HDPART2: - -; DI ; DISABLE INTERRUPTS - - ld hl,#0x4001 ; init LBA offset sector lo word - ld (LBA_OFFSET_LO),hl - ld hl,#0 ; init LBA offset sector hi word - ld (LBA_OFFSET_HI),hl - JP WRITE_HDPARTX - -;------------------------------------------------------------------- - -WRITE_HDPART3: ; STUB -WRITE_HDPART4: ; STUB - RET - -;------------------------------------------------------------------- - - -WRITE_HDPARTX: - - ; BDOS TRACK PARAMETER (16 BITS) - ; BDOS SECTOR PARAMETER (16 BITS) - - ld hl,(TRACK) ; load track # (word) - ld b,l ; save lower 8 bits (tracks 0-255) - ld hl,(SECTOR) ; load sector # (word) - ld h,b ; hl is 8 bit track in h, 8 bit sector in l - - CALL CONVERT_IDE_SECTOR_CPM ; COMPUTE WHERE THE CP/M SECT IS ON THE - ; IDE PARTITION - - ; MAP COMPUTED IDE HD SECTOR TO LBA REGISTERS - ; LBA REGISTERS STORE 28 BIT VALUE OF IDE HD SECTOR ADDRESS - - ld a,(LBA_TARGET_LO) ; load LBA reg 0 with sect addr to read - ld (IDE_LBA0),a - ld a,(LBA_TARGET_LO+1) ; load LBA reg 1 with sect addr to read - ld (IDE_LBA1),a - ld a,(LBA_TARGET_HI) ; load LBA reg 2 with sect addr to read - ld (IDE_LBA2),a - ld a,(LBA_TARGET_HI+1) ; load LBA reg 3 with sect addr to read - and a,#0b00001111 ; only lower four bits are valid - add a,#0b11100000 ; enable LBA bits 5:7=111 in IDE_LBA3 - ld (IDE_LBA3),a - CALL IDE_READ_SECTOR ; READ THE IDE HARD DISK SECTOR - - ; NEED TO ADD ERROR CHECKING HERE, - ; CARRY FLAG IS SET IF IDE_READ_SECTOR SUCCESSFUL! - - ; COMPUTE STARTING ADDRESS OF CP/M SECTOR IN READ IDE HD SECTOR BUFFER - - ld hl,#SECTOR_BUFFER ; load hl with sector buffer address - - ld a,(SECTOR_INDEX) ; get the sector index (off in buffer) - - RRC a ; MOVE BIT 0 TO BIT 7 - RRC a ; DO AGAIN - IN EFFECT MULTIPLY BY 64 - - ld d,#0 ; put result as 16 bit value in de - ; UPPER BYTE IN D IS $00 - ld e,a ; put address offset in e - - add hl,de ; cp/m starting addr in buffer - - add hl,de ; *2, total mult is x128 - - ; KEEP CP/M SECTOR ADDRESS FOR LATER USE - ; COPY CP/M SECTOR FROM BDOS DMA ADDRESS BUFFER - ld (SECST),hl - - ld hl,(SECST) ; setup destination - ex de,hl ; swap for next LHLD - ld hl,(DMAAD) ; setup source - ld bc,#128 ; byte count - ldir - - ; IDE HD SECTOR IS NOW UPDATED - ; WITH CURRENT CP/M SECTOR DATA SO WRITE TO DISK - - CALL IDE_WRITE_SECTOR ; WRITE THE UPDATED IDE HARD DISK SECTOR - - ; NEED TO ADD ERROR CHECKING HERE, - ; CARRY FLAG IS SET IF IDE_WRITE_SECTOR SUCCESSFUL! - -; EI ; RE-ENABLE INTERRUPTS - - ld a,#0 ; return error code write successful a=0 - ret - -;------------------------------------------------------------------- - - -PRTMSG: - ld a,(hl) ; get char into A - cp a,#END ; test for end byte - jp z,PRTMSG1 ; jump if end byte is found - ld c,a ; put char to print in C for conout - CALL CONOUT ; SEND CHARACTER TO CONSOLE FROM REG C - inc hl ; inc ptr to next char - JP PRTMSG ; TRANSMIT LOOP -PRTMSG1: - ret - - -; -; UTILITY ROUTINE FOR SECTOR TO PAGE ADDRESS -; USES HL AND CARRY -; -SECPAGE: - ld hl,(SECTOR) - add hl,hl ; * 2 - add hl,hl ; * 4 - add hl,hl ; * 8 - add hl,hl ; * 16 - add hl,hl ; * 32 - add hl,hl ; * 64 - add hl,hl ; * 128 - ld (SECST),hl ; save sector starting address - ret - -; -; PAGER BYTE CREATION -; ASSEMBLES DRIVE AND TRACK AND SENDS IT TO PAGER PORT -; -PAGERB: - ld hl,(TRACK) - ld a,l ; or l with acc to combine track and drive -; out0 ACR+2 - .db 0xed,0x39,ACR+2 ; rom latch - ld a,#0 ; switch in the rom -; out0 ACR - .db 0xed,0x39,ACR - ld (PAGER),a ; save copy (just because) - ld (DB_PAGER),a ; save another copy for debug - RET - -; -; RESET PAGER BACK TO RAM. -; -RPAGE: - - ld a,#0x80 ; deselect rom page -; out0 ACR - .db 0xed,0x39,ACR - - ld a,#0 ; set to RAM track 0 -;dwg; STA PAGER ; SAVE COPY OF PAGER BYTE - ld (PAGER),a - - RET - - -CONVERT_IDE_SECTOR_CPM: - - ; COMPUTES WHERE THE CP/M SECTOR IS IN THE IDE PARTITION - ; IDE HD SECTORS ARE 512 BYTES EACH, CP/M SECTORS ARE 128 BYTES EACH - ; MAXIMUM SIZE OF CP/M DISK IS 8 MB = 65536 (16 BITS) X 128 BYTES PER SECTOR - ; IDE HD PARTITION CAN HAVE AT MOST 16384 IDE SECTORS -> 65536 CP/M SECTORS - ; EACH IDE HD SECTOR CONTAINS 4 ADJACENT CP/M SECTORS - ; - ; - ; INPUT: - ; IDE HD PARTITION STARTING SECTOR NUMBER (FROM PARTITION TABLE) - ; - LOWER 16 BITS STORED IN LBA_OFFSET_LO - ; - UPPER 16 BITS STORED IN LBA_OFFSET_HI - ; PARTITION OFFSET IN HL (16 BITS) - ; - A UNIQUELY COMPUTED FUNCTION BASED ON GEOMETRY OF DISKS NUMBER OF - ; CP/M TRACKS AND SECTORS SPECIFIED IN DPB - ; - ; - ; OUTPUT: - ; IDE TARGET SECTOR (SENT TO IDE HD CONTROLLER FOR READ OPERATION) - ; - LOWER 16 BITS STORED IN LBA_TARGET_LO - ; - UPPER 16 BITS STORED IN LBA_TARGET_HI - ; CP/M TO IDE HD SECTOR MAPPING PARAMETER STORED IN SECTOR_INDEX - ; - 8 BIT VALUE WITH 4 LEGAL STATES (00, 01, 02, 04) WHICH IS - ; TO BE USED TO COMPUTE STARTING ADDRESS OF 128 BYTE CP/M SECTOR ONCE - ; 512 BYTE IDE HD SECTOR READ INTO MEMORY BUFFER - ; - - ; ROTATE WITH CARRY 16 BIT TRACK,SECTOR VALUE IN HL TO GET 14 BIT IDE HD - ; TARGET SECTOR IN PARTITION - ; KEEP LAST TWO BITS IN B FOR IDE HD SECTOR TO CP/M SECTOR TRANSLATION - - ; COMPUTE SECTOR_INDEX - -;;dwg;; What is the point of this? the next inst sets A anyway?? - xor a,a ; zero accumulator - - ld a,l ; store the last 2 bits of l in b - and a,#0b00000011 - ld b,a - - ld (SECTOR_INDEX),a ; locates the 128 cpm sector in buffer - - ; COMPUTE WHICH IDE HD SECTOR TO READ TO WITHIN 4 CP/M SECTORS - ; SHIFTS 16 BIT PARTITION OFFSET TO THE RIGHT 2 BITS AND ADDS RESULT TO - ; IDE HD PARTITION STARTING SECTOR - - ; SHIFT PARTITION OFFSET RIGHT 1 BIT - - scf ; set the carry flag, so we can clear it - ccf ; Complement Carry Flag - - ld a,h ; 16 bit rotate hl with carry - rra - ld h,a ; rotate HL right 1 bit (divide by 2) - ld a,l - rra - ld l,a - - ; SHIFT PARTITION OFFSET RIGHT 1 BIT - - scf - ccf ; CLEAR CARRY FLAG - - ld a,h ; 16 bit rotate HL with carry - rra - ld H,A ; ROTATE HL RIGHT 1 BIT (DIVIDE BY 2) - ld A,L - rra - ld L,A - - ; ADD RESULTING 14 BIT VALUE TO IDE HD PARTITION STARTING SECTOR - ; STORE RESULT IN IDE HD TARGET SECTOR PARAMETER - - ld a,(LBA_OFFSET_LO) ; 16 bit add of LBA_OFFSET_LO with hl - ADD L - ld (LBA_TARGET_LO),a - ld a,(LBA_OFFSET_LO+1) - adc a,h - ld (LBA_TARGET_LO+1),a ; store overflow bit in carry - ld hl,#0 - ld a,(LBA_OFFSET_HI) ; 16 bit add w/carry of LBA_OFFSET_HI w/ - adc a,l - ld (LBA_TARGET_HI),a - ld a,(LBA_OFFSET_HI+1) - adc a,h - ld (LBA_TARGET_HI+1),a - RET - - - -;------------------------------------------------------------------------------------ -; Parallel port IDE driver -; -; -; ----------------------------------------------------------------------------- - - ;read a sector, specified by the 4 bytes in "lba", - ;Return, acc is zero on success, non-zero for an error -IDE_READ_SECTOR: - call ide_wait_not_busy ;make sure drive is ready - call wr_lba ;tell it which sector we want - - ld a,#ide_command ; select IDE reg - ld c,#ide_cmd_read - call ide_write ;ask the drive to read it - call ide_wait_drq ;wait until it's got the data -; bit 0,a -; ani 1 -; jnz get_err - - ld hl,#SECTOR_BUFFER - call read_data ;grab the data - ld a,#0 ; ? set successful return code ? - - ret - - -;----------------------------------------------------------------------------- - - - ;write a sector, specified by the 4 bytes in "lba", - ;whatever is in the buffer gets written to the drive! - ;Return, acc is zero on success, non-zero for an error -IDE_WRITE_SECTOR: - call ide_wait_not_busy ;make sure drive is ready - call wr_lba ;tell it which sector we want - - ld a,#ide_command - ld c,#ide_cmd_write - call ide_write ;tell drive to write a sector - call ide_wait_drq ;wait unit it wants the data - -; bit 0,a ; check for error returned -; ani 1 -; jnz get_err - - ld hl,#SECTOR_BUFFER - call write_data ;give the data to the drive - call ide_wait_not_busy ;wait until the write is complete - -; bit 0,a -; ani 1 -; jnz get_err - -; ld a,#0 ; SHOULD THIS BE HERE (Doug's idea) - ret - - -;----------------------------------------------------------------------------- - -;--------ide_hard_reset--------------------------------------------------------------- - ;do a hard reset on the drive, by pulsing its reset pin. - ;this should usually be followed with a call to "ide_init". -;------------------------------------------------------------------------------------------- -ide_hard_reset: - call set_ppi_rd - ld a,#ide_rst_line - out (IDECTL),a ; assert rst line on IDE interface - ld bc,#0 -rst_dly: - dec b - jp nz,rst_dly - ld a,#0 ; this could be XOR A,A (shorter) - out (IDECTL),a ; deassert RST line on IDE interface - ret - -;------------------------------------------------------------------------------ -; IDE INTERNAL SUBROUTINES -;------------------------------------------------------------------------------ - - - -;---------------------------------------------------------------------------- - ;when an error occurs, we get bit 0 of A set from a call to ide_drq - ;or ide_wait_not_busy (which read the drive's status register). If - ;that error bit is set, we should jump here to read the drive's - ;explaination of the error, to be returned to the user. If for - ;some reason the error code is zero (shouldn't happen), we'll - ;return 255, so that the main program can always depend on a - ;return of zero to indicate success. -get_err: - ld a,#ide_err - call ide_read - ld a,c - jp z,gerr2 - ret -gerr2: - ld a,#255 - ret - -;----------------------------------------------------------------------------- - -ide_wait_not_busy: - ld a,#ide_status ; wait for RDY bit to be set - call ide_read - ld a,c - and a,#0x80 ; isolate busy bit - jp nz,ide_wait_not_busy - ret - - -ide_wait_ready: - ld a,#ide_status ; wait for RDY bit to be set - call ide_read - ld a,c - and a,#0b11000000 ; mask off busy and ready bits - xor a,#0b01000000 ; we want Busy(7) to be 0 and ready(6) to be 1 - jp nz,ide_wait_ready - ret - - ;Wait for the drive to be ready to transfer data. - ;Returns the drive's status in Acc -ide_wait_drq: - ld a,#ide_status ; waut for DRQ bit to be set - call ide_read - ld a,c - and a,#0b10001000 ; mask off busy(7) and DRQ(3) - xor a,#0b00001000 ; we want busy(7) to be 0 and DRQ (3) to be 1 - jp nz,ide_wait_drq - ret - - - -;------------------------------------------------------------------------------ - - ;Read a block of 512 bytes (one sector) from the drive - ;and store it in memory @ HL -read_data: - ld b,#0 -rdblk2: - push bc - push hl - ld a,#ide_data - call ide_read ; read form data port - pop hl - ld (hl),c - inc hl - ld (hl),b - inc hl - pop bc - dec b - jp nz,rdblk2 - ret - -;----------------------------------------------------------------------------- - - ;Write a block of 512 bytes (at HL) to the drive -write_data: - ld b,#0 -wrblk2: - push bc - ld c,(hl) ; lsb - inc hl - ld b,(hl) ; msb - inc hl - push hl - ld a,#ide_data - call ide_write - pop hl - pop bc - dec b - jp nz,wrblk2 - ret - - -;----------------------------------------------------------------------------- - - ;write the logical block address to the drive's registers -wr_lba: - ld a,(IDE_LBA0+3) ; MSB - and a,#0x0f - or a,#0xe0 - ld c,a - ld a,#ide_head - call ide_write - ld a,(IDE_LBA0+2) - ld c,a - ld a,#ide_cyl_msb - call ide_write - ld a,(IDE_LBA0+1) - ld c,a - ld a,#ide_cyl_lsb - call ide_write - ld a,(IDE_LBA0) ; LSB - ld c,a - ld a,#ide_sector - call ide_write - ld c,#1 - ld a,#ide_sec_cnt - call ide_write - - ret - -;------------------------------------------------------------------------------- - -; Low Level I/O to the drive. These are the routines that talk -; directly to the drive, via the 8255 chip. Normally a main -; program would not call to these. - - ;Do a read bus cycle to the drive, using the 8255. - ;input A = ide regsiter address - ;output C = lower byte read from ide drive - ;output B = upper byte read from ide drive - -ide_read: - push af ; save register value - call set_ppi_rd ; setup for a read cycle - pop af ; restore register value - out (IDECTL),a ;drive address onto control lines - or a,#ide_rd_line ; assert RD pin - out (IDECTL),a - push af ; save register value - in a,(IDELSB) ; read lower byte - ld c,a ; save in c reg - in a,(IDEMSB) ; read upper byte - ld b,a ; save in reg b - pop af ; restore reg value - xor a,#ide_rd_line ; deassert RD signal - out (IDECTL),a - ld a,#0 ;; DWG SAYS couln't this be a 1 byter? - out (IDECTL),a ;deassert all control pins - ret - - ;Do a write bus cycle to the drive, via the 8255 - ;input A = ide register address - ;input register C = lsb to write - ;input register B = msb to write - ; - - -ide_write: - push af ; save IDE reg valure - call set_ppi_wr ; setup for a write cycle - ld a,c ; get value to be written - out (IDELSB),a - ld a,b ; get value to be written - out (IDEMSB),a - pop af ; restore saved IDE reg - out (IDECTL),a ; drive address onto control lines - or a,#ide_wr_line ; assert write pin - out (IDECTL),a - xor a,#ide_wr_line ; deasser write pin - out (IDECTL),a ;drive address onto control lines - ld a,#0 ;; DWG SAYS couldn't this be 1 byter? - out (IDECTL),a ; release bus signals - ret - - -;----------------------------------------------------------------------------------- -; ppi setup routine to configure the appropriate PPI mode -; -;------------------------------------------------------------------------------------ - -set_ppi_rd: - ld a,#rd_ide_8255 - out (PIO1CONT),a ;config 8255 chip, read mode - ret - -set_ppi_wr: - ld a,#wr_ide_8255 - out (PIO1CONT),a ;config 8255 chip, write mode - ret - -;----------------------------------------------------------------------------- -; End of PPIDE disk driver -;------------------------------------------------------------------------------------ - - -; TEXT STRINGS - -TXT_RO_ERROR: - .DB CR,LF - .ascii "ERROR: WRITE TO READ ONLY DISK" - .DB END - -TXT_STARTUP_MSG: - .DB CR,LF - .ascii "CP/M-80 VERSION 2.2C FOR THE " - .ascii "N8VEM N8" - .ascii " (PPIDE)" - .DB CR,LF - .DB END - -; -; THE REMAINDER OF THE CBIOS IS RESERVED UNINITIALIZED -; DATA AREA, AND DOES NOT NEED TO BE A PART OF THE -; SYSTEM MEMORY IMAGE -; -TRACK: .DS 2 ; TWO BYTES FOR TRACK # -SECTOR: .DS 2 ; TWO BYTES FOR SECTOR # -DMAAD: .DS 2 ; DIRECT MEMORY ADDRESS -DISKNO: .DS 1 ; DISK NUMBER 0-15 - - -PAGER: .DB 1 ; COPY OF PAGER BYTE - -DB_PAGER: .db 0xff ; copy of pager byte - -V_SECTOR: .DS 2 ; TWO BYTES FOR VIRTUAL SECTOR # -SECST: .DS 2 ; SECTOR IN ROM/RAM START ADDRESS - - -LBA_OFFSET_LO: .DW 0 ; IDE HD PART STARTING SECTOR (LOW 16 BITS) -LBA_OFFSET_HI: .DW 0 ; IDE HD PART STARTING SECTOR (HI 16 BITS, 12 USED) -LBA_TARGET_LO: .DW 0 ; IDE HD PART TARGET SECTOR (LOW 16 BITS) -LBA_TARGET_HI: .DW 0 ; IDE HD PART TARGET SECTOR (HI 16 BITS, 12 USED) - -IDE_LBA0: .DS 1 ;SET LBA 0:7 -IDE_LBA1: .DS 1 ;SET LBA 8:15 -IDE_LBA2: .DS 1 ;SET LBA 16:23 -IDE_LBA3: .DS 1 ;LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE - -SECTOR_INDEX: .DB 0 ;WHERE 128 BYTE CP/M SECTOR IS IN 512 BYTE IDE HD SECTOR - - -; -; SCRATCH RAM AREA FOR BDOS USE -; -; Note: this can extend up to the beginning of the debug monitor however -; there is a limitation in the amount of space available in the EPROM -; -;BEGDAT .EQU $ ;BEGINNING OF DATA AREA -; -; - -SECTOR_BUFFER: .DS 512 ;Deblocking STORAGE FOR 512 BYTE IDE HD SECTOR - -;dwg;TMPBUF .EQU SECTOR_BUFFER -TMPBUF = SECTOR_BUFFER - -DIRBF: .DS 128 ;SCRATCH DIRECTORY AREA -ALL00: .DS 4 ;ALLOCATION VECTOR 0 (DSM/8 = 1 BIT PER BLOCK) -ALL01: .DS 32 ;ALLOCATION VECTOR 1 (225/8) -ALL02: .DS 255 ;ALLOCATION VECTOR 2 (2040/8) -ALL03: .DS 255 ;ALLOCATION VECTOR 3 (2040/8) -ALL04: .DS 64 ;ALLOCATION VECTOR 4 (511/8) -ALL05: .DS 64 ;ALLOCATION VECTOR 5 (495/8) -; -CHK00: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK01: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK02: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK03: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK04: .DS 0 ; NOT USED FOR FIXED MEDIA -CHK05: .DS 0 ; NOT USED FOR FIXED MEDIA - -; DOUG SAYS - THIS NEEDS TO BE DONE ANOTHER WAY NO ORGS IN REL SEG -; -; .ORG $F2FF -; -; F2FF - desired org -; - E600 - BIOS ORG -; ______ -; 0CFF - necessary offset in this module -; -; 0CCF ; where we want to be -; - 0AA9 ; where we are now -; ______ -; 0256 - adjustment to reach desired org in rel segment -; - - .ds 0x0256 ; THIS NEEDS TO BE ADJUSTED SO LASTBYTE IS AT 0CFF - -LASTBYTE: .DB 0xE5 ; note this is just to force out the last byte. - ; this address will actually fall within the - ; allocation vector block - -_cbioshc_end:: - .area _CODE - .area _CABS diff --git a/branches/s100/cpurom/src/ccpb03.s b/branches/s100/cpurom/src/ccpb03.s deleted file mode 100644 index 3eedda69..00000000 --- a/branches/s100/cpurom/src/ccpb03.s +++ /dev/null @@ -1,1345 +0,0 @@ - .title ccpb03.s derived from ccpb03.asm - .sbttl by Douglas Goodall 5/16/2011 dwg - - .module ccpb03 - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _ccp -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - -; .area _CODE - .area _CCPB03 - -_ccp_start:: -_ccp: - -MON = 1 ;ADD THE CCP MON COMMAND -USRDSP = 1 ;SHOW THE USER NUMBER -CHKU0B = 1 ;CHECK FOR TRANSIENTS ON USER 0 TOO -ENDFIL = 1 ;FILE FULL CCP SIZE -; -;************************************************************** -;* -;* C C P - C O N S O L E C O M M A N D P R O C E S S O R -;* -;************************************************************** -;* -IOBYTE = 3 ; I/O DEFINITION BYTE. -TDRIVE = 4 ; CURRENT DRIVE NAME AND USER NUMBER. -ENTRY = 5 ; ENTRY POINT FOR THE CP/M BDOS. -TFCB = 0x5C ; DEFAULT FILE CONTROL BLOCK. -TBUFF = 0x80 ; I/O BUFFER AND COMMAND LINE STORAGE. -TBASE = 0x0100 ; TRANSIANT PROGRAM STORAGE AREA. -MONADR = 0x0FC00 ;MONITOR PROGRAM -; -; SET CONTROL CHARACTER .EQUATES. -; -CNTRLC = 0x03 ; CONTROL-C -CNTRLE = 0x05 ; CONTROL-E -BS = 0x08 ; BACKSPACE -TAB = 0x09 ; TAB -LF = 0x0A ; LINE FEED -FF = 0x0C ; FORM FEED -CR = 0x0D ; CARRIAGE RETURN -CNTRLP = 0x10 ; CONTROL-P -CNTRLR = 0x12 ; CONTROL-R -CNTRLS = 0x13 ; CONTROL-S -CNTRLU = 0x15 ; CONTROL-U -CNTRLX = 0x18 ; CONTROL-X -CNTRLZ = 0x1A ; CONTROL-Z (END-OF-FILE MARK) -ASTERICK = 0x2A -COLON = 0x3A -LESSTHAN = 0x3C -ASCSPACE = 0x20 ; SPACE -PERIOD = 0x2e ; PERIOD -EQUAL = 0x3D -GREATERTHAN = 0x3E -QUESTION = 0x3F ;QUESTION MARK -UNDERSCORE = 0x5F -LCURLY = 0x7B ; { -DEL = 0x7F ; RUBOUT -; -; SET ORIGIN FOR CP/M -; - -NK = 59 ;SYSTEM SIZE -BASE = (NK*1024)-0x5000 -CCPO = BASE+0x3400 ;CCP ORIGIN -BDOSO = BASE+0x3C00 ;BDOS ORIGIN -BIOSO = BASE+0x4A00 ;BIOS ORIGIN - -;dwg; .ORG CCPO -; -CBASE: JP COMMAND ; EXECUTE COMMAND PROCESSOR (CCP). - JP CLEARBUF ; ENTRY TO EMPTY INPUT BUFFER BEFORE STARTING CCP. - -; -; STANDARD CP/M CCP INPUT BUFFER. FORMAT IS (MAX LENGTH), -; (ACTUAL LENGTH), (CHAR #1), (CHAR #2), (CHAR #3), ETC. -; -INBUFF: .DB 127 ; LENGTH OF INPUT BUFFER. - -; N8VEM - if add any text after this point, change .DB 0 below to length -; and put a 0 after the text, and delete the same number of zeros after the dig -; so that inpoint ends up at the same spot -; INBUFF+1 is cleared on the next warm boot, so only runs once. - .DB 0 ;CURRENT LENGTH OF CONTENTS. - - -; .DB 17 ; Autoboot length of string -; .DB "SUPERSUB AUTOEXEC" -; .DB 0 ; zero at end - - - .ascii "COPYRIGHT" - .ascii " 1979 (C) BY " - .ascii "DIGITAL RESEARCH " - .ascii " " - -;dwg; .ORG INBUFF+128 -;dwg; becausje org's are not allowed in rel areas, it has been -; replaced with the following array of .db's to achieve the -; same purpose - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - .db 0,0 - -;; s/b d086 here - -INPOINT:.DW INBUFF+2 ; INPUT LINE POINTER -NAMEPNT:.DW 0 ; INPUT LINE POINTER USED FOR ERROR MESSAGE. POINTS TO -; ;START OF NAME IN ERROR. -; -; ROUTINE TO PRINT (A) ON THE CONSOLE. ALL REGISTERS USED. -; -PRINT: LD E,A ; SETUP BDOS CALL. - LD C,#2 - JP ENTRY -; -; ROUTINE TO PRINT (A) ON THE CONSOLE AND TO SAVE (BC). -; -PRINTB: PUSH BC - CALL PRINT - POP BC - RET -; -; ROUTINE TO SEND A CARRIAGE RETURN, LINE FEED COMBINATION -; TO THE CONSOLE. -; -CRLF: LD A,#CR - CALL PRINTB - LD A,#LF - JP PRINTB -; -; ROUTINE TO SEND ONE SPACE TO THE CONSOLE AND SAVE (BC). -; -SPACE: LD A,#ASCSPACE - JP PRINTB -; -; ROUTINE TO PRINT CHARACTER STRING POINTED TO BE (BC) ON THE -; CONSOLE. IT MUST TERMINATE WITH A NULL BYTE. -; -PLINE: PUSH BC - CALL #CRLF - POP HL -PLINE2: LD A,(HL) - OR A - RET Z - INC HL - PUSH HL - CALL PRINT - POP HL - JP PLINE2 -; -; ROUTINE TO RESET THE DISK SYSTEM. -; -RESDSK: LD C,#13 - JP ENTRY -; -; ROUTINE TO SELECT DISK (A). -; -DSKSEL: LD E,A - LD C,#14 - JP ENTRY -; -; ROUTINE TO CALL BDOS AND SAVE THE RETURN CODE. THE ZERO -; FLAG IS SET ON A RETURN OF 0FFH. -; -ENTRY1: CALL ENTRY - LD (RTNCODE),A ; SAVE RETURN CODE. - INC A ; SET ZERO IF 0FFH RETURNED. - RET -; -; ROUTINE TO OPEN A FILE. (DE) MUST POINT TO THE FCB. -; -OPEN: LD C,#15 - JP ENTRY1 -; -; ROUTINE TO OPEN FILE AT (FCB). -; -OPENFCB:XOR A ; CLEAR THE RECORD NUMBER BYTE AT FCB+32 - LD (FCB+32),A - LD DE,#FCB - JP OPEN -; -; ROUTINE TO CLOSE A FILE. (DE) POINTS TO FCB. -; -CLOSE: LD C,#16 - JP ENTRY1 -; -; ROUTINE TO SEARCH FOR THE FIRST FILE WITH AMBIGUEOUS NAME -; (DE). -; -SRCHFST:LD C,#17 - JP ENTRY1 -; -; SEARCH FOR THE NEXT AMBIGEOUS FILE NAME. -; -SRCHNXT:LD C,#18 - JP ENTRY1 -; -; SEARCH FOR FILE AT (FCB). -; -SRCHFCB:LD DE,#FCB - JP SRCHFST -; -; ROUTINE TO DELETE A FILE POINTED TO BY (DE). -; -DELETE: LD C,#19 - JP ENTRY -; -; ROUTINE TO CALL THE BDOS AND SET THE ZERO FLAG IF A ZERO -; STATUS IS RETURNED. -; -ENTRY2: CALL ENTRY - OR A ; SET ZERO FLAG IF APPROPRIATE. - RET -; -; ROUTINE TO READ THE NEXT RECORD FROM A S.EQUENTIAL FILE. -; (DE) POINTS TO THE FCB. -; -RDREC: LD C,#20 - JP ENTRY2 -; -; ROUTINE TO READ FILE AT (FCB). -; -READFCB:LD DE,#FCB - JP RDREC -; -; ROUTINE TO WRITE THE NEXT RECORD OF A S.EQUENTIAL FILE. -; (DE) POINTS TO THE FCB. -; -WRTREC: LD C,#21 - JP ENTRY2 -; -; ROUTINE TO CREATE THE FILE POINTED TO BY (DE). -; -CREATE: LD C,#22 - JP ENTRY1 -; -; ROUTINE TO RENAME THE FILE POINTED TO BY (DE). NOTE THAT -; THE NEW NAME STARTS AT (DE+16). -; -RENAM: LD C,#23 - JP ENTRY -; -; GET THE CURRENT USER CODE. -; -GETUSR: LD E,#0x0FF -; -; ROUTNE TO GET OR SET THE CURRENT USER CODE. -; IF (E) IS FF THEN THIS IS A GET, ELSE IT IS A SET. -; -GETSETUC: - LD C,#32 - JP ENTRY -; -; ROUTINE TO SET THE CURRENT DRIVE BYTE AT (TDRIVE). -; -SETCDRV:CALL GETUSR ; GET USER NUMBER - ADD A,A ; AND SHIFT INTO THE UPPER 4 BITS. - ADD A,A - ADD A,A - ADD A,A - LD HL,#CDRIVE ; NOW ADD IN THE CURRENT DRIVE NUMBER. - OR (HL) - LD (TDRIVE),A ; AND SAVE. - RET -; -; MOVE CURRENTLY ACTIVE DRIVE DOWN TO (TDRIVE). -; -MOVECD: LD A,(CDRIVE) - LD (TDRIVE),A - RET -; -; ROUTINE TO CONVERT (A) INTO UPPER CASE ASCII. ONLY LETTERS -; ARE AFFECTED. -; -UPPER: CP #0x41 ; CHECK FOR LETTERS IN THE RANGE OF 'A' TO 'Z'. - RET C - CP #LCURLY - RET NC - AND #0x5F ; CONVERT IT IF FOUND. - RET -; -; ROUTINE TO GET A LINE OF INPUT. WE MUST CHECK TO SEE IF THE -; USER IS IN (BATCH) MODE. IF SO, THEN READ THE INPUT FROM FILE -; ($$$.SUB). AT THE END, RESET TO CONSOLE INPUT. -; -GETINP: LD A,(BATCH) ; IF =0, THEN USE CONSOLE INPUT. - OR A - JP Z,GETINP1 -; -; USE THE SUBMIT FILE ($$$.SUB) WHICH IS PREPARED BY A -; SUBMIT RUN. IT MUST BE ON DRIVE (A) AND IT WILL BE DELETED -; IF AND ERROR OCCURES (LIKE EOF). -; - LD A,(CDRIVE) ; SELECT DRIVE 0 IF NEED BE. - OR A - LD A,#0 ; ALWAYS USE DRIVE A FOR SUBMIT. - CALL NZ,DSKSEL ; SELECT IT IF R.EQUIRED. - LD DE,#BATCHFCB - CALL OPEN ; LOOK FOR IT. - JP Z,GETINP1 ; IF NOT THERE, USE NORMAL INPUT. - LD A,(BATCHFCB+15) ; GET LAST RECORD NUMBER+1. - DEC A - LD (BATCHFCB+32),A - LD DE,#BATCHFCB - CALL RDREC ; READ LAST RECORD. - JP NZ,GETINP1 ; QUIT ON END OF FILE. -; -; MOVE THIS RECORD INTO INPUT BUFFER. -; - LD DE,#INBUFF+1 - LD HL,#TBUFF ; DATA WAS READ INTO BUFFER HERE. - LD B,#128 ; ALL 128 CHARACTERS MAY BE USED. - CALL HL2DE ; (HL) TO (DE), (B) BYTES. - LD HL,#BATCHFCB+14 - LD (HL),#0 ; ZERO OUT THE 'S2' BYTE. - INC HL ; AND DECREMENT THE RECORD COUNT. - DEC (HL) - LD DE,#BATCHFCB ; CLOSE THE BATCH FILE NOW. - CALL CLOSE - JP Z,GETINP1 ; QUIT ON AN ERROR. - LD A,(CDRIVE) ; RE-SELECT PREVIOUS DRIVE IF NEED BE. - OR A - CALL NZ,DSKSEL ; DON'T DO NEEDLESS SELECTS. -; -; PRINT LINE JUST READ ON CONSOLE. -; - LD HL,#INBUFF+2 - CALL PLINE2 - CALL CHKCON ; CHECK CONSOLE, QUIT ON A KEY. - JP Z,GETINP2 ; JUMP IF NO KEY IS PRESSED. -; -; TERMINATE THE SUBMIT JOB ON ANY KEYBOARD INPUT. DELETE THIS -; FILE SUCH THAT IT IS NOT RE-STARTED AND JUMP TO NORMAL KEYBOARD -; INPUT SECTION. -; - CALL DELBATCH ; DELETE THE BATCH FILE. - JP CMMND1 ; AND RESTART COMMAND INPUT. -; -; GET HERE FOR NORMAL KEYBOARD INPUT. DELETE THE SUBMIT FILE -; INCASE THERE WAS ONE. -; -GETINP1:CALL DELBATCH ; DELETE FILE ($$$.SUB). - CALL SETCDRV ; RESET ACTIVE DISK. - LD C,#10 ; GET LINE FROM CONSOLE DEVICE. - LD DE,#INBUFF - CALL ENTRY - CALL MOVECD ; RESET CURRENT DRIVE (AGAIN). -; -; CONVERT INPUT LINE TO UPPER CASE. -; -GETINP2:LD HL,#INBUFF+1 - LD B,(HL) ; (B)=CHARACTER COUNTER. -GETINP3:INC HL - LD A,B ; END OF THE LINE? - OR A - JP Z,GETINP4 - LD A,(HL) ; CONVERT TO UPPER CASE. - CALL UPPER - LD (HL),A - DEC B ; ADJUST CHARACTER COUNT. - JP GETINP3 -GETINP4:LD (HL),A ; ADD TRAILING NULL. - LD HL,#INBUFF+2 - LD (INPOINT),HL ; RESET INPUT LINE POINTER. - RET -; -; ROUTINE TO CHECK THE CONSOLE FOR A KEY PRESSED. THE ZERO -; FLAG IS SET IS NONE, ELSE THE CHARACTER IS RETURNED IN (A). -; -CHKCON: LD C,#11 ; CHECK CONSOLE. - CALL ENTRY - OR A - RET Z ; RETURN IF NOTHING. - LD C,#1 ; ELSE GET CHARACTER. - CALL ENTRY - OR A ; CLEAR ZERO FLAG AND RETURN. - RET -; -; ROUTINE TO GET THE CURRENTLY ACTIVE DRIVE NUMBER. -; -GETDSK: LD C,#25 - JP ENTRY -; -; SET THE STABDARD DMA ADDRESS. -; -STDDMA: LD DE,#TBUFF -; -; ROUTINE TO SET THE DMA ADDRESS TO (DE). -; -DMASET: LD C,#26 - JP ENTRY -; -; DELETE THE BATCH FILE CREATED BY SUBMIT. -; -DELBATCH: - LD HL,#BATCH ; IS BATCH ACTIVE? - LD A,(HL) - OR A - RET Z - LD (HL),#0 ; YES, DE-ACTIVATE IT. - XOR A - CALL DSKSEL ; SELECT DRIVE 0 FOR SURE. - LD DE,#BATCHFCB ; AND DELETE THIS FILE. - CALL DELETE - LD A,(CDRIVE) ; RESET CURRENT DRIVE. - JP DSKSEL -; -; PRINT BACK FILE NAME WITH A '?' TO INDICATE A SYNTAX ERROR. -; -SYNERR: CALL CRLF ; END CURRENT LINE. - LD HL,(NAMEPNT) ; THIS POINTS TO NAME IN ERROR. -SYNERR1:LD A,(HL) ; PRINT IT UNTIL A SPACE OR NULL IS FOUND. - CP #ASCSPACE - JP Z,SYNERR2 - OR A - JP Z,SYNERR2 - PUSH HL - CALL PRINT - POP HL - INC HL - JP SYNERR1 -SYNERR2:LD A,#QUESTION ; ADD TRAILING '?'. - CALL PRINT - CALL CRLF - CALL DELBATCH ; DELETE ANY BATCH FILE. - JP CMMND1 ; AND RESTART FROM CONSOLE INPUT. -; -; CHECK CHARACTER AT (DE) FOR LEGAL COMMAND INPUT. NOTE THAT THE -; ZERO FLAG IS SET IF THE CHARACTER IS A DELIMITER. -; -CHECK: LD A,(DE) - OR A - RET Z - CP #ASCSPACE ; CONTROL CHARACTERS ARE NOT LEGAL HERE. - JP C,SYNERR - RET Z ; CHECK FOR VALID DELIMITER. - CP #EQUAL - RET Z - CP #UNDERSCORE - RET Z - CP #PERIOD - RET Z - CP #COLON - RET Z - CP #0x3b - RET Z - CP #LESSTHAN - RET Z - CP #GREATERTHAN - RET Z - RET -; -; GET THE NEXT NON-BLANK CHARACTER FROM (DE). -; -NONBLANK: - LD A,(DE) - OR A ; STRING ENDS WITH A NULL. - RET Z - CP #ASCSPACE - RET NZ - INC DE - JP NONBLANK -; -; ADD (HL)=(HL)+(A) -; -ADDHL: ADD A,L - LD L,A - RET NC ; TAKE CARE OF ANY CARRY. - INC H - RET -; -; CONVERT THE FIRST NAME IN (FCB). -; -CONVFST:LD A,#0 -; -; FORMAT A FILE NAME (CONVERT * TO '?', ETC.). ON RETURN, -; (A)=0 IS AN UNAMBIGEOUS NAME WAS SPECIFIED. ENTER WITH (A) .EQUAL TO -; THE POSITION WITHIN THE FCB FOR THE NAME (EITHER 0 OR 16). -; -CONVERT:LD HL,#FCB - CALL ADDHL - PUSH HL - PUSH HL - XOR A - LD (CHGDRV),A ; INITIALIZE DRIVE CHANGE FLAG. - LD HL,(INPOINT) ; SET (HL) AS POINTER INTO INPUT LINE. - EX DE,HL - CALL NONBLANK ; GET NEXT NON-BLANK CHARACTER. - EX DE,HL - LD (NAMEPNT),HL ; SAVE POINTER HERE FOR ANY ERROR MESSAGE. - EX DE,HL - POP HL - LD A,(DE) ; GET FIRST CHARACTER. - OR A - JP Z,CONVRT1 - SBC A,#0x41-1 ; MIGHT BE A DRIVE NAME, CONVERT TO BINARY. - LD B,A ; AND SAVE. - INC DE ; CHECK NEXT CHARACTER FOR A ':'. - LD A,(DE) - CP #COLON - JP Z,CONVRT2 - DEC DE ; NOPE, MOVE POINTER BACK TO THE START OF THE LINE. -CONVRT1:LD A,(CDRIVE) - LD (HL),A - JP CONVRT3 -CONVRT2:LD A,B - LD (CHGDRV),A ; SET CHANGE IN DRIVES FLAG. - LD (HL),B - INC DE -; -; CONVERT THE BASIC FILE NAME. -; -CONVRT3:LD B,#8 -CONVRT4:CALL CHECK - JP Z,CONVRT8 - INC HL - CP #ASTERICK ; NOTE THAT AN '*' WILL FILL THE REMAINING - JP NZ,CONVRT5 ; FIELD WITH '?'. - LD (HL),#QUESTION - JP CONVRT6 -CONVRT5:LD (HL),A - INC DE -CONVRT6:DEC B - JP NZ,CONVRT4 -CONVRT7:CALL CHECK ; GET NEXT DELIMITER. - JP Z,GETEXT - INC DE - JP CONVRT7 -CONVRT8:INC HL ; BLANK FILL THE FILE NAME. - LD (HL),#ASCSPACE - DEC B - JP NZ,CONVRT8 -; -; GET THE EXTENSION AND CONVERT IT. -; -GETEXT: LD B,#3 - CP #PERIOD - JP NZ,GETEXT5 - INC DE -GETEXT1:CALL CHECK - JP Z,GETEXT5 - INC HL - CP #ASTERICK - JP NZ,GETEXT2 - LD (HL),#QUESTION - JP GETEXT3 -GETEXT2:LD (HL),A - INC DE -GETEXT3:DEC B - JP NZ,GETEXT1 -GETEXT4:CALL CHECK - JP Z,GETEXT6 - INC DE - JP GETEXT4 -GETEXT5:INC HL - LD (HL),#ASCSPACE - DEC B - JP NZ,GETEXT5 -GETEXT6:LD B,#3 -GETEXT7:INC HL - LD (HL),#0 - DEC B - JP NZ,GETEXT7 - EX DE,HL - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - POP HL -; -; CHECK TO SEE IF THIS IS AN AMBIGEOUS FILE NAME SPECIFICATION. -; SET THE (A) REGISTER TO NON ZERO IF IT IS. -; - LD BC,#11 ; SET NAME LENGTH. -GETEXT8:INC HL - LD A,(HL) - CP #QUESTION ; ANY QUESTION MARKS? - JP NZ,GETEXT9 - INC B ; COUNT THEM. -GETEXT9:DEC C - JP NZ,GETEXT8 - LD A,B - OR A - RET -; -; CP/M COMMAND TABLE. NOTE COMMANDS CAN BE EITHER 3 OR 4 CHARACTERS LONG. -; - .if MON -NUMCMDS = 7 ; NUMBER OF COMMANDS - .else -NUMCMDS = 6 ; NUMBER OF COMMANDS - .endif - -CMDTBL: .ascii "DIR " - .ascii "ERA " - .ascii "TYPE" - .ascii "SAVE" - .ascii "REN " - .ascii "USER" - .if MON - .ascii "MON " - .ENDIF - -CMDADR: .DW DIRECT - .DW ERASE - .DW TYPE - .DW SAVE - .DW RENAME - .DW USER - .IF MON - .DW MONITOR - .ENDIF - .DW UNKNOWN -; -; SEARCH THE COMMAND TABLE FOR A MATCH WITH WHAT HAS JUST -; BEEN ENTERED. IF A MATCH IS FOUND, THEN WE JUMP TO THE -; PROPER SECTION. ELSE JUMP TO (UNKNOWN). -; ON RETURN, THE (C) REGISTER IS SET TO THE COMMAND NUMBER -; THAT MATCHED (OR NUMCMDS+1 IF NO MATCH). -; -SEARCH: LD HL,#CMDTBL - LD C,#0 -SEARCH1:LD A,C - CP #NUMCMDS ; THIS COMMANDS EXISTS. - RET NC - LD DE,#FCB+1 ; CHECK THIS ONE. - LD B,#4 ; MAX COMMAND LENGTH. -SEARCH2:LD A,(DE) - CP (HL) - JP NZ,SEARCH3 ; NOT A MATCH. - INC DE - INC HL - DEC B - JP NZ,SEARCH2 - LD A,(DE) ; ALLOW A 3 CHARACTER COMMAND TO MATCH. - CP #ASCSPACE - JP NZ,SEARCH4 - LD A,C ; SET RETURN REGISTER FOR THIS COMMAND. - RET -SEARCH3:INC HL - DEC B - JP NZ,SEARCH3 -SEARCH4:INC C - JP SEARCH1 -; -; SET THE INPUT BUFFER TO EMPTY AND THEN START THE COMMAND -; PROCESSOR (CCP). -; -CLEARBUF: - XOR A - LD (INBUFF+1),A ; SECOND BYTE IS ACTUAL LENGTH. -COMMAND:LD SP,#CCPSTACK ; SETUP STACK AREA. - PUSH BC ; NOTE THAT (C) SHOULD BE .EQUAL TO: - LD A,C ; (UUUUDDDD) WHERE 'UUUU' IS THE USER NUMBER - RRA ; AND 'DDDD' IS THE DRIVE NUMBER. - RRA - RRA - RRA - AND #0x0F ; ISOLATE THE USER NUMBER. - LD E,A - CALL GETSETUC ; AND SET IT. - CALL RESDSK ; RESET THE DISK SYSTEM. - LD (BATCH),A ; CLEAR BATCH MODE FLAG. - POP BC - LD A,C - AND #0x0F ; ISOLATE THE DRIVE NUMBER. - LD (CDRIVE),A ; AND SAVE. - CALL DSKSEL ; ...AND SELECT. - LD A,(INBUFF+1) - OR A ; ANYTHING IN INPUT BUFFER ALREADY? - JP NZ,CMMND2 ; YES, WE JUST PROCESS IT. -; -; ENTRY POINT TO GET A COMMAND LINE FROM THE CONSOLE. -; -CMMND1: LD SP,#CCPSTACK ; SET STACK STRAIGHT. - CALL CRLF ; START A NEW LINE ON THE SCREEN. - CALL GETDSK ; GET CURRENT DRIVE. - ADD A,#0x41 - CALL PRINT ; PRINT CURRENT DRIVE. - .IF USRDSP - CALL GETUSR ;GET CURRENT USER NUMBER - CP #10 ;TWO DIGITS? - JR C,CMMND3 ;NO - LD A,#0x31 ;PRINT LEADING '1' - CALL PRINT - CALL GETUSR ;GET CURRENT USER NUMBER - SUB #10 ;SUBTRACT 10 -CMMND3: ADD A,#0x30 - CALL PRINT - .ENDIF - LD A,#GREATERTHAN - CALL PRINT ; AND ADD PROMPT. - CALL GETINP ; GET LINE FROM USER. -; -; PROCESS COMMAND LINE HERE. -; -CMMND2: LD DE,#TBUFF - CALL DMASET ; SET STANDARD DMA ADDRESS. - CALL GETDSK - LD (CDRIVE),A ; SET CURRENT DRIVE. - CALL CONVFST ; CONVERT NAME TYPED IN. - CALL NZ,SYNERR ; WILD CARDS ARE NOT ALLOWED. - LD A,(CHGDRV) ; IF A CHANGE IN DRIVES WAS INDICATED, - OR A ; THEN TREAT THIS AS AN UNKNOWN COMMAND - JP NZ,UNKNOWN ; WHICH GETS EXECUTED. - CALL SEARCH ; ELSE SEARCH COMMAND TABLE FOR A MATCH. -; -; NOTE THAT AN UNKNOWN COMMAND RETURNS -; WITH (A) POINTING TO THE LAST ADDRESS -; IN OUR TABLE WHICH IS (UNKNOWN). -; - LD HL,#CMDADR ; NOW, LOOK THRU OUR ADDRESS TABLE FOR COMMAND (A). - LD E,A ; SET (DE) TO COMMAND NUMBER. - LD D,#0 - ADD HL,DE - ADD HL,DE ; (HL)=(CMDADR)+2*(COMMAND NUMBER). - LD A,(HL) ; NOW PICK OUT THIS ADDRESS. - INC HL - LD H,(HL) - LD L,A - JP (HL) ; NOW EXECUTE IT. -; -; READ ERROR WHILE TYPEING A FILE. -; -RDERROR:LD BC,#RDERR - JP PLINE -RDERR: .asciz "Read Error" - -; -; R.EQUIRED FILE WAS NOT LOCATED. -; -NONE: LD BC,#NOFILE - JP PLINE -NOFILE: .asciz "No File" -; -; DECODE A COMMAND OF THE FORM 'A>FILENAME NUMBER{ FILENAME}. -; NOTE THAT A DRIVE SPECIFIER IS NOT ALLOWED ON THE FIRST FILE -; NAME. ON RETURN, THE NUMBER IS IN REGISTER (A). ANY ERROR -; CAUSES 'FILENAME?' TO BE PRINTED AND THE COMMAND IS ABORTED. -; -DECODE: CALL CONVFST ; CONVERT FILENAME. - LD A,(CHGDRV) ; DO NOT ALLOW A DRIVE TO BE SPECIFIED. - OR A - JP NZ,SYNERR - LD HL,#FCB+1 ; CONVERT NUMBER NOW. - LD BC,#11 ; (B)=SUM REGISTER, (C)=MAX DIGIT COUNT. -DECODE1:LD A,(HL) - CP #ASCSPACE ; A SPACE TERMINATES THE NUMERAL. - JP Z,DECODE3 - INC HL - SUB #0x30 ; MAKE BINARY FROM ASCII. - CP #10 ; LEGAL DIGIT? - JP NC,SYNERR - LD D,A ; YES, SAVE IT IN (D). - LD A,B ; COMPUTE (B)=(B)*10 AND CHECK FOR OVERFLOW. - AND #0x0E0 - JP NZ,SYNERR - LD A,B - RLCA - RLCA - RLCA ; (A)=(B)*8 - ADD A,B ; .......*9 - JP C,SYNERR - ADD A,B ; .......*10 - JP C,SYNERR - ADD A,D ; ADD IN NEW DIGIT NOW. -DECODE2:JP C,SYNERR - LD B,A ; AND SAVE RESULT. - DEC C ; ONLY LOOK AT 11 DIGITS. - JP NZ,DECODE1 - RET -DECODE3:LD A,(HL) ; SPACES MUST FOLLOW (WHY?). - CP #ASCSPACE - JP NZ,SYNERR - INC HL -DECODE4:DEC C - JP NZ,DECODE3 - LD A,B ; SET (A)=THE NUMERIC VALUE ENTERED. - RET -; -; MOVE 3 BYTES FROM (HL) TO (DE). NOTE THAT THERE IS ONLY -; ONE REFERENCE TO THIS AT (A2D5H). -; -MOVE3: LD B,#3 -; -; MOVE (B) BYTES FROM (HL) TO (DE). -; -HL2DE: LD A,(HL) - LD (DE),A - INC HL - INC DE - DEC B - JP NZ,HL2DE - RET -; -; COMPUTE (HL)=(TBUFF)+(A)+(C) AND GET THE BYTE THAT'S HERE. -; -EXTRACT:LD HL,#TBUFF - ADD A,C - CALL ADDHL - LD A,(HL) - RET -; -; CHECK DRIVE SPECIFIED. IF IT MEANS A CHANGE, THEN THE NEW -; DRIVE WILL BE SELECTED. IN ANY CASE, THE DRIVE BYTE OF THE -; FCB WILL BE SET TO NULL (MEANS USE CURRENT DRIVE). -; -DSELECT:XOR A ; NULL OUT FIRST BYTE OF FCB. - LD (FCB),A - LD A,(CHGDRV) ; A DRIVE CHANGE INDICATED? - OR A - RET Z - DEC A ; YES, IS IT THE SAME AS THE CURRENT DRIVE? - LD HL,#CDRIVE - CP (HL) - RET Z - JP DSKSEL ; NO. SELECT IT THEN. -; -; CHECK THE DRIVE SELECTION AND RESET IT TO THE PREVIOUS -; DRIVE IF IT WAS CHANGED FOR THE PRECEEDING COMMAND. -; -RESETDR:LD A,(CHGDRV) ; DRIVE CHANGE INDICATED? - OR A - RET Z - DEC A ; YES, WAS IT A DIFFERENT DRIVE? - LD HL,#CDRIVE - CP (HL) - RET Z - LD A,(CDRIVE) ; YES, RE-SELECT OUR OLD DRIVE. - JP DSKSEL - - .IF MON -; -;************************************************************** -;* -;* M O N I T O R C O M M A N D -;* -;************************************************************** -; -MONITOR: JP MONADR - .ENDIF - -; -;************************************************************** -;* -;* D I R E C T O R Y C O M M A N D -;* -;************************************************************** -; -DIRECT: CALL CONVFST ; CONVERT FILE NAME. - CALL DSELECT ; SELECT INDICATED DRIVE. - LD HL,#FCB+1 ; WAS ANY FILE INDICATED? - LD A,(HL) - CP #ASCSPACE - JP NZ,DIRECT2 - LD B,#11 ; NO. FILL FIELD WITH '?' - SAME AS *.*. -DIRECT1:LD (HL),#QUESTION - INC HL - DEC B - JP NZ,DIRECT1 -DIRECT2:LD E,#0 ; SET INITIAL CURSOR POSITION. - PUSH DE - CALL SRCHFCB ; GET FIRST FILE NAME. - CALL Z,NONE ; NONE FOUND AT ALL? -DIRECT3:JP Z,DIRECT9 ; TERMINATE IF NO MORE NAMES. - LD A,(RTNCODE) ; GET FILE'S POSITION IN SEGMENT (0-3). - RRCA - RRCA - RRCA - AND #0x60 ; (A)=POSITION*32 - LD C,A - LD A,#10 - CALL EXTRACT ; EXTRACT THE TENTH ENTRY IN FCB. - RLA ; CHECK SYSTEM FILE STATUS BIT. - JP C,DIRECT8 ; WE DON'T LIST THEM. - POP DE - LD A,E ; BUMP NAME COUNT. - INC E - PUSH DE - AND #3 ; AT END OF LINE? - PUSH AF - JP NZ,DIRECT4 - CALL CRLF ; YES, END THIS LINE AND START ANOTHER. - PUSH BC - CALL GETDSK ; START LINE WITH ('A:'). - POP BC - ADD A,#0x41 - CALL PRINTB - LD A,#COLON - CALL PRINTB - JP DIRECT5 -DIRECT4:CALL SPACE ; ADD SEPERATOR BETWEEN FILE NAMES. - LD A,#COLON - CALL PRINTB -DIRECT5:CALL SPACE - LD B,#1 ; 'EXTRACT' EACH FILE NAME CHARACTER AT A TIME. -DIRECT6:LD A,B - CALL EXTRACT - AND #0x7F ; STRIP BIT 7 (STATUS BIT). - CP #ASCSPACE ; ARE WE AT THE END OF THE NAME? - JP NZ,DRECT65 - POP AF ; YES, DON'T PRINT SPACES AT THE END OF A LINE. - PUSH AF - CP #3 - JP NZ,DRECT63 - LD A,#9 ; FIRST CHECK FOR NO EXTENSION. - CALL EXTRACT - AND #0x7F - CP #ASCSPACE - JP Z,DIRECT7 ; DON'T PRINT SPACES. -DRECT63:LD A,#ASCSPACE ; ELSE PRINT THEM. -DRECT65:CALL PRINTB - INC B ; BUMP TO NEXT CHARACTER PSOITION. - LD A,B - CP #12 ; END OF THE NAME? - JP NC,DIRECT7 - CP #9 ; NOPE, STARTING EXTENSION? - JP NZ,DIRECT6 - CALL SPACE ; YES, ADD SEPERATING SPACE. - JP DIRECT6 -DIRECT7:POP AF ; GET THE NEXT FILE NAME. -DIRECT8:CALL CHKCON ; FIRST CHECK CONSOLE, QUIT ON ANYTHING. - JP NZ,DIRECT9 - CALL SRCHNXT ; GET NEXT NAME. - JP DIRECT3 ; AND CONTINUE WITH OUR LIST. -DIRECT9:POP DE ; RESTORE THE STACK AND RETURN TO COMMAND LEVEL. - JP GETBACK -; -;************************************************************** -;* -;* E R A S E C O M M A N D -;* -;************************************************************** -; -ERASE: CALL CONVFST ; CONVERT FILE NAME. - CP #11 ; WAS '*.*' ENTERED? - JP NZ,ERASE1 - LD BC,#YESNO ; YES, ASK FOR CONFIRMATION. - CALL PLINE - CALL GETINP - LD HL,#INBUFF+1 - DEC (HL) ; MUST BE EXACTLY 'Y'. - JP NZ,CMMND1 - INC HL - LD A,(HL) - CP #0x59 - JP NZ,CMMND1 - INC HL - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. -ERASE1: CALL DSELECT ; SELECT DESIRED DISK. - LD DE,#FCB - CALL DELETE ; DELETE THE FILE. - INC A - CALL Z,NONE ; NOT THERE? - JP GETBACK ; RETURN TO COMMAND LEVEL NOW. -YESNO: .asciz "All (Y/N)?" -; -;************************************************************** -;* -;* T Y P E C O M M A N D -;* -;************************************************************** -; -TYPE: CALL CONVFST ; CONVERT FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - CALL DSELECT ; SELECT INDICATED DRIVE. - CALL OPENFCB ; OPEN THE FILE. - JP Z,TYPE5 ; NOT THERE? - CALL CRLF ; OK, START A NEW LINE ON THE SCREEN. - LD HL,#NBYTES ; INITIALIZE BYTE COUNTER. - LD (HL),#0x0FF ; SET TO READ FIRST SECTOR. -TYPE1: LD HL,#NBYTES -TYPE2: LD A,(HL) ; HAVE WE WRITTEN THE ENTIRE SECTOR? - CP #128 - JP C,TYPE3 - PUSH HL ; YES, READ IN THE NEXT ONE. - CALL READFCB - POP HL - JP NZ,TYPE4 ; END OR ERROR? - XOR A ; OK, CLEAR BYTE COUNTER. - LD (HL),A -TYPE3: INC (HL) ; COUNT THIS BYTE. - LD HL,#TBUFF ; AND GET THE (A)TH ONE FROM THE BUFFER (TBUFF). - CALL ADDHL - LD A,(HL) - CP #CNTRLZ ; END OF FILE MARK? - JP Z,GETBACK - CALL PRINT ; NO, PRINT IT. - CALL CHKCON ; CHECK CONSOLE, QUIT IF ANYTHING READY. - JP NZ,GETBACK - JP TYPE1 -; -; GET HERE ON AN END OF FILE OR READ ERROR. -; -TYPE4: DEC A ; READ ERROR? - JP Z,GETBACK - CALL RDERROR ; YES, PRINT MESSAGE. -TYPE5: CALL RESETDR ; AND RESET PROPER DRIVE - JP SYNERR ; NOW PRINT FILE NAME WITH PROBLEM. -; -;************************************************************** -;* -;* S A V E C O M M A N D -;* -;************************************************************** -; -SAVE: CALL DECODE ; GET NUMERIC NUMBER THAT FOLLOWS SAVE. - PUSH AF ; SAVE NUMBER OF PAGES TO WRITE. - CALL CONVFST ; CONVERT FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - CALL DSELECT ; SELECT SPECIFIED DRIVE. - LD DE,#FCB ; NOW DELETE THIS FILE. - PUSH DE - CALL DELETE - POP DE - CALL CREATE ; AND CREATE IT AGAIN. - JP Z,SAVE3 ; CAN'T CREATE? - XOR A ; CLEAR RECORD NUMBER BYTE. - LD (FCB+32),A - POP AF ; CONVERT PAGES TO SECTORS. - LD L,A - LD H,#0 - ADD HL,HL ; (HL)=NUMBER OF SECTORS TO WRITE. - LD DE,#TBASE ; AND WE START FROM HERE. -SAVE1: LD A,H ; DONE YET? - OR L - JP Z,SAVE2 - DEC HL ; NOPE, COUNT THIS AND COMPUTE THE START - PUSH HL ; OF THE NEXT 128 BYTE SECTOR. - LD HL,#128 - ADD HL,DE - PUSH HL ; SAVE IT AND SET THE TRANSFER ADDRESS. - CALL DMASET - LD DE,#FCB ; WRITE OUT THIS SECTOR NOW. - CALL WRTREC - POP DE ; RESET (DE) TO THE START OF THE LAST SECTOR. - POP HL ; RESTORE SECTOR COUNT. - JP NZ,SAVE3 ; WRITE ERROR? - JP SAVE1 -; -; GET HERE AFTER WRITING ALL OF THE FILE. -; -SAVE2: LD DE,#FCB ; NOW CLOSE THE FILE. - CALL CLOSE - INC A ; DID IT CLOSE OK? - JP NZ,SAVE4 -; -; PRINT OUT ERROR MESSAGE (NO SPACE). -; -SAVE3: LD BC,#NOSPACE - CALL PLINE -SAVE4: CALL STDDMA ; RESET THE STANDARD DMA ADDRESS. - JP GETBACK - -NOSPACE: .asciz "No Space" -; -;************************************************************** -;* -;* R E N A M E C O M M A N D -;* -;************************************************************** -; -RENAME: CALL CONVFST ; CONVERT FIRST FILE NAME. - JP NZ,SYNERR ; WILD CARDS NOT ALLOWED. - LD A,(CHGDRV) ; REMEMBER ANY CHANGE IN DRIVES SPECIFIED. - PUSH AF - CALL DSELECT ; AND SELECT THIS DRIVE. - CALL SRCHFCB ; IS THIS FILE PRESENT? - JP NZ,RENAME6 ; YES, PRINT ERROR MESSAGE. - LD HL,#FCB ; YES, MOVE THIS NAME INTO SECOND SLOT. - LD DE,#FCB+16 - LD B,#16 - CALL HL2DE - LD HL,(INPOINT) ; GET INPUT POINTER. - EX DE,HL - CALL NONBLANK ; GET NEXT NON BLANK CHARACTER. - CP #EQUAL ; ONLY ALLOW AN '=' OR '_' SEPERATOR. - JP Z,RENAME1 - CP #ASCSPACE - JP NZ,RENAME5 -RENAME1:EX DE,HL - INC HL ; OK, SKIP SEPERATOR. - LD (INPOINT),HL ; SAVE INPUT LINE POINTER. - CALL CONVFST ; CONVERT THIS SECOND FILE NAME NOW. - JP NZ,RENAME5 ; AGAIN, NO WILD CARDS. - POP AF ; IF A DRIVE WAS SPECIFIED, THEN IT - LD B,A ; MUST BE THE SAME AS BEFORE. - LD HL,#CHGDRV - LD A,(HL) - OR A - JP Z,RENAME2 - CP B - LD (HL),B - JP NZ,RENAME5 ; THEY WERE DIFFERENT, ERROR. -RENAME2:LD (HL),B ; RESET AS PER THE FIRST FILE SPECIFICATION. - XOR A - LD (FCB),A ; CLEAR THE DRIVE BYTE OF THE FCB. -RENAME3:CALL SRCHFCB ; AND GO LOOK FOR SECOND FILE. - JP Z,RENAME4 ; DOESN'T EXIST? - LD DE,#FCB - CALL RENAM ; OK, RENAME THE FILE. - JP GETBACK -; -; PROCESS RENAME ERRORS HERE. -; -RENAME4:CALL NONE ; FILE NOT THERE. - JP GETBACK -RENAME5:CALL RESETDR ; BAD COMMAND FORMAT. - JP SYNERR -RENAME6:LD BC,#EXISTS ; DESTINATION FILE ALREADY EXISTS. - CALL PLINE - JP GETBACK -EXISTS: .asciz "File Exists" -; -;************************************************************** -;* -;* U S E R C O M M A N D -;* -;************************************************************** -; -USER: CALL DECODE ; GET NUMERIC VALUE FOLLOWING COMMAND. - CP #16 ; LEGAL USER NUMBER? - JP NC,SYNERR - LD E,A ; YES BUT IS THERE ANYTHING ELSE? - LD A,(FCB+1) - CP #ASCSPACE - JP Z,SYNERR ; YES, THAT IS NOT ALLOWED. - CALL GETSETUC ; OK, SET USER CODE. - JP GETBACK1 -; -;************************************************************** -;* -;* T R A N S I A N T P R O G R A M C O M M A N D -;* -;************************************************************** -; -UNKNOWN:LD A,(FCB+1) ; ANYTHING TO EXECUTE? - CP #ASCSPACE - JP NZ,UNKWN1 - LD A,(CHGDRV) ; NOPE, ONLY A DRIVE CHANGE? - OR A - JP Z,GETBACK1 ; NEITHER??? - DEC A - LD (CDRIVE),A ; OK, STORE NEW DRIVE. - CALL MOVECD ; SET (TDRIVE) ALSO. - CALL DSKSEL ; AND SELECT THIS DRIVE. - JP GETBACK1 ; THEN RETURN. -; -; HERE A FILE NAME WAS TYPED. PREPARE TO EXECUTE IT. -; -UNKWN1: LD DE,#FCB+9 ; AN EXTENSION SPECIFIED? - LD A,(DE) - CP #ASCSPACE - JP NZ,SYNERR ; YES, NOT ALLOWED. -UNKWN2: PUSH DE - CALL DSELECT ; SELECT SPECIFIED DRIVE. - POP DE - LD HL,#COMFILE ; SET THE EXTENSION TO 'COM'. LD HL,COMFILE - CALL MOVE3 ; move 3 bytes from (HL) to (DE) to add .COM - CALL OPENFCB ; AND OPEN THIS FILE. - JP NZ,UNKWNA ;GOT IT - .IF CHKU0B - LD E,#0 ;TRY USER 0, THIS DRIVE - CALL GETSETUC ; OK, SET USER CODE. - CALL OPENFCB - JP NZ,UNKWNA ;GOT IT - LD HL,#FCB ;SEE IF ON DRIVE B, USER 0 - LD (HL),#2 - CALL OPENFCB - JP Z,UNKWN9 ;NOPE - .ENDIF -; -; LOAD IN THE PROGRAM. -; -UNKWNA: LD HL,#TBASE ; STORE THE PROGRAM STARTING HERE. -UNKWN3: PUSH HL - EX DE,HL - CALL DMASET ; SET TRANSFER ADDRESS. - LD DE,#FCB ; AND READ THE NEXT RECORD. - CALL RDREC - JP NZ,UNKWN4 ; END OF FILE OR READ ERROR? - POP HL ; NOPE, BUMP POINTER FOR NEXT SECTOR. - LD DE,#128 - ADD HL,DE - LD DE,#CBASE ; ENOUGH ROOM FOR THE WHOLE FILE? - LD A,L - SUB E - LD A,H - SBC A,D - JP NC,UNKWN0 ; NO, IT CAN'T FIT. - JP UNKWN3 -; -; GET HERE AFTER FINISHED READING. -; -UNKWN4: POP HL - DEC A ; NORMAL END OF FILE? - JP NZ,UNKWN0 - CALL RESETDR ; YES, RESET PREVIOUS DRIVE. - CALL CONVFST ; CONVERT THE FIRST FILE NAME THAT FOLLOWS - LD HL,#CHGDRV ; COMMAND NAME. - PUSH HL - LD A,(HL) ; SET DRIVE CODE IN DEFAULT FCB. - LD (FCB),A - LD A,#16 ; PUT SECOND NAME 16 BYTES LATER. - CALL CONVERT ; CONVERT SECOND FILE NAME. - POP HL - LD A,(HL) ; AND SET THE DRIVE FOR THIS SECOND FILE. - LD (FCB+16),A - XOR A ; CLEAR RECORD BYTE IN FCB. - LD (FCB+32),A - LD DE,#TFCB ; MOVE IT INTO PLACE AT(005CH). - LD HL,#FCB - LD B,#33 - CALL HL2DE - LD HL,#INBUFF+2 ; NOW MOVE THE REMAINDER OF THE INPUT -UNKWN5: LD A,(HL) ; LINE DOWN TO (0080H). LOOK FOR A NON BLANK. - OR A ; OR A NULL. - JP Z,UNKWN6 - CP #ASCSPACE - JP Z,UNKWN6 - INC HL - JP UNKWN5 -; -; DO THE LINE MOVE NOW. IT ENDS IN A NULL BYTE. -; -UNKWN6: LD B,#0 ; KEEP A CHARACTER COUNT. - LD DE,#TBUFF+1 ; DATA GETS PUT HERE. -UNKWN7: LD A,(HL) ; MOVE IT NOW. - LD (DE),A - OR A - JP Z,UNKWN8 - INC B - INC HL - INC DE - JP UNKWN7 -UNKWN8: LD A,B ; NOW STORE THE CHARACTER COUNT. - LD (TBUFF),A - CALL CRLF ; CLEAN UP THE SCREEN. - CALL STDDMA ; SET STANDARD TRANSFER ADDRESS. - CALL SETCDRV ; RESET CURRENT DRIVE. - CALL TBASE ; AND EXECUTE THE PROGRAM. -; -; TRANSIANT PROGRAMS RETURN HERE (OR REBOOT). -; - LD SP,#BATCH ; SET STACK FIRST OFF. - CALL MOVECD ; MOVE CURRENT DRIVE INTO PLACE (TDRIVE). - CALL DSKSEL ; AND RESELECT IT. - JP CMMND1 ; BACK TO COMAND MODE. -; -; GET HERE IF SOME ERROR OCCURED. -; -UNKWN9: CALL RESETDR ; INPROPER FORMAT. - JP SYNERR -UNKWN0: LD BC,#BADLOAD ; READ ERROR OR WON'T FIT. - CALL PLINE - JP GETBACK -BADLOAD:.asciz "Bad Load" -COMFILE:.ascii "COM" ; COMMAND FILE EXTENSION. -; -; GET HERE TO RETURN TO COMMAND LEVEL. WE WILL RESET THE -; PREVIOUS ACTIVE DRIVE AND THEN EITHER RETURN TO COMMAND -; LEVEL DIRECTLY OR PRINT ERROR MESSAGE AND THEN RETURN. -; -GETBACK:CALL RESETDR ; RESET PREVIOUS DRIVE. -GETBACK1: - CALL CONVFST ; CONVERT FIRST NAME IN (FCB). - LD A,(FCB+1) ; IF THIS WAS JUST A DRIVE CHANGE R.EQUEST, - SUB #ASCSPACE ; MAKE SURE IT WAS VALID. - LD HL,#CHGDRV - OR (HL) - JP NZ,SYNERR - JP CMMND1 ; OK, RETURN TO COMMAND LEVEL. -; -; CCP STACK AREA. -; - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -CCPSTACK: -;dwg; .EQU $ ;END OF CCP STACK AREA. - -; -; BATCH (OR SUBMIT) PROCESSING INFORMATION STORAGE. -; -BATCH: .DB 0 ; BATCH MODE FLAG (0=NOT ACTIVE). -BATCHFCB:.DB 0 - .ascii "$$$ SUB" - .DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -; -; FILE CONTROL BLOCK SETUP BY THE CCP. -; -FCB: .DB 0 - .asciz " " - .DB 0,0,0,0 - - .asciz " " - .DB 0,0,0,0 - -RTNCODE:.DB 0 ; STATUS RETURNED FROM BDOS CALL. -CDRIVE: .DB 0 ; CURRENTLY ACTIVE DRIVE. -CHGDRV: .DB 0 ; CHANGE IN DRIVES FLAG (0=NO CHANGE). -NBYTES: .DW 0 ; BYTE COUNTER USED BY TYPE. - -;dwg; .IF ENDFIL -;dwg; .ORG CCPO+07FFH -;dwg; .DB 055H -;dwg; .ENDIF -;dwg; .END - - -_ccp_end:: - .area _CODE - .area _CABS diff --git a/branches/s100/cpurom/src/copyfile.c b/branches/s100/cpurom/src/copyfile.c deleted file mode 100644 index e4b7716d..00000000 --- a/branches/s100/cpurom/src/copyfile.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * copyfile.c 5/11/2011 dwg - - * Main C module uses cpmbdos.h bindings to access system services - * Copyright (C) Douglas Goodall All Rights Reserved - * For non-commercial use by N8VEM Community -*/ - -#include -#include -#include -#include "stdlib.h" -#include "cpmbdos.h" -#include "cprintf.h" - -char sine[] = "copyfile.c(com) 5/11/2011 dwg - $"; - -struct FCB * prifcb = (struct FCB *)0x5c; -struct FCB * secfcb = (struct FCB *)0x6c; - -struct FCB srcfcb; -struct FCB dstfcb; - -struct BDOSCALL writestr = { C_WRITESTR, { (unsigned int)&sine } }; -struct BDOSCALL makedst = { F_MAKE, { (unsigned int)&dstfcb } }; -struct BDOSCALL opensrc = { F_OPEN, { (unsigned int)&srcfcb } }; -struct BDOSCALL readsrc = { F_READ, { (unsigned int)&srcfcb } }; -struct BDOSCALL writedst = { F_WRITE, { (unsigned int)&dstfcb } }; -struct BDOSCALL closesrc = { F_CLOSE, { (unsigned int)&srcfcb } }; -struct BDOSCALL closedst = { F_CLOSE, { (unsigned int)&dstfcb } }; - -struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)'?' } }; -struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - -/* THESE ARE USED BY THE LIBRARY ROUTINES */ -char getchar(void) -{ - struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - return cpmbdos(&cread); -} -void outchar(char c) -{ - struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)c } }; - cpmbdos(&cwrite); -} - -int main(void) -{ - int rc; - - cpmbdos(&writestr); - - strncpy(srcfcb.filename,prifcb->filename,8+3); - srcfcb.ex = srcfcb.rc = srcfcb.cr = 0; - rc = cpmbdos(&opensrc); printf("\nrc from opensrc was %2d, ",rc); - if(rc != 0) { - printf("\nSorry, cannot open source file\n"); - return(EXIT_FAILURE); - } - - strncpy(dstfcb.filename,secfcb->filename,8+3); - dstfcb.ex = dstfcb.rc = dstfcb.cr = 0; - rc = cpmbdos(&makedst); printf("rc from makedst was %2d",rc); - if(rc != 0) { - printf("\nSorry, cannot open destination file\n"); - cpmbdos(&closesrc); - return(EXIT_FAILURE); - } - - rc = cpmbdos(&readsrc); printf("\nrc from read was %2d, ",rc); - while(0 == rc) { - rc = cpmbdos(&writedst); printf( "rc from write was %2d", rc); - rc = cpmbdos(&readsrc); printf("\nrc from read was %2d, ",rc); - } - rc = cpmbdos(&closesrc); printf("\nrc from closesrc was %2d, ",rc); - rc = cpmbdos(&closedst); printf( "rc from closedst was %2d", rc); - - return EXIT_SUCCESS; -} - diff --git a/branches/s100/cpurom/src/cpm0.s b/branches/s100/cpurom/src/cpm0.s deleted file mode 100644 index 59186c76..00000000 --- a/branches/s100/cpurom/src/cpm0.s +++ /dev/null @@ -1,46 +0,0 @@ -;-------------------------------------------------------------------------- -; cpm0.s - Generic cpm0.s for a Z80 CP/M-80 v2.2 Application -; Copyright (C) 2011, Douglas Goodall All Rights Reserved. -;-------------------------------------------------------------------------- - - .globl _main - .area _CODE - - .ds 0x0100 -init: - ;; Define an adequate stack - ld sp,#stktop - - ;; Initialise global variables - call gsinit - - ;; Call the C main routine - call _main - - ld c,#0 - call 5 - - ;; Ordering of segments for the linker. - .area _TPA - - .area _HOME - .area _CODE - .area _GSINIT - .area _GSFINAL - .area _DATA - - .area _STACK - .ds 256 -stktop: - - .area _GSINIT -gsinit:: - - .area _GSFINAL - ret - .db 0xe5 - -;;;;;;;;;;;;;;;; -; eof - cpm0.s ; -;;;;;;;;;;;;;;;; - diff --git a/branches/s100/cpurom/src/cpmbdos.s b/branches/s100/cpurom/src/cpmbdos.s deleted file mode 100644 index a7c6592f..00000000 --- a/branches/s100/cpurom/src/cpmbdos.s +++ /dev/null @@ -1,65 +0,0 @@ -;-------------------------------------------------------- -; File Created by SDCC : free open source ANSI-C Compiler -; Version 3.0.2 #6489 (May 10 2011) (Mac OS X x86_64) -; This file was generated Wed May 11 05:28:20 2011 -;-------------------------------------------------------- - .module cpmbdos - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _cpmbdos -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _CODE -;cpmbdos.c:1: unsigned char cpmbdos(void * p) -; --------------------------------- -; Function cpmbdos -; --------------------------------- -_cpmbdos_start:: -_cpmbdos: - push ix - ld ix,#0 - add ix,sp -;cpmbdos.c:3: return 2; - ld l,4(ix) - ld h,5(ix) - ld c,(hl) - inc hl - ld e,(hl) - inc hl - ld d,(hl) - call 5 - pop ix - ret -_cpmbdos_end:: - .area _CODE - .area _CABS diff --git a/branches/s100/cpurom/src/cprintf.c b/branches/s100/cpurom/src/cprintf.c deleted file mode 100644 index 7f94e9bb..00000000 --- a/branches/s100/cpurom/src/cprintf.c +++ /dev/null @@ -1,267 +0,0 @@ -/* Copyright (C) 1996 Robert de Bath - * This file is part of the Linux-8086 C library and is distributed - * under the GNU Library General Public License. - */ - -/* Modified 14-Jan-2002 by John Coffman for inclusion - * in the set of LILO diagnostics. This code is the property of Robert - * de Bath, and is used with his permission. - */ - -/* Modified 14-Sep-2010 by John Coffman for use with - * the N8VEM SBC-188 BIOS project. - */ -#include -#include - -#undef printf -#define ASM_CVT 0 -#ifndef strlen -int strlen(char *s); -#endif - -void outchar(char ch); -#define putch(ch) outchar((char)ch) - - -#ifndef NULL -# define NULL ((void*)0L) -#endif - -#define __fastcall -#define NUMLTH 11 -static unsigned char * __fastcall __numout(long i, int base, unsigned char out[]); - -int cprintf(const char * fmt, ...) -{ - register int c; - int count = 0; - int type, base; - long val; - char * cp; - char padch=' '; - int minsize, maxsize; - unsigned char out[NUMLTH+1]; - va_list ap; - - va_start(ap, fmt); - - while(c=*fmt++) - { - count++; - if(c!='%') - { - if (c=='\n') putch('\r'); - putch(c); - } - else - { - type=1; - padch = *fmt; - maxsize=minsize=0; - if(padch == '-') fmt++; - - for(;;) - { - c=*fmt++; - if( c<'0' || c>'9' ) break; - minsize*=10; minsize+=c-'0'; - } - - if( c == '.' ) - for(;;) - { - c=*fmt++; - if( c<'0' || c>'9' ) break; - maxsize*=10; maxsize+=c-'0'; - } - - if( padch == '-' ) minsize = -minsize; - else - if( padch != '0' ) padch=' '; - - if( c == 0 ) break; - if(c=='h') - { - c=*fmt++; - type = 0; - } - else if(c=='l') - { - c=*fmt++; - type = 2; - } - - switch(c) - { - case 'X': - case 'x': base=16; type |= 4; if(0) { - case 'o': base= 8; type |= 4; } if(0) { - case 'u': base=10; type |= 4; } if(0) { - case 'd': base=-10; } - switch(type) - { - case 0: val=va_arg(ap, short); break; - case 1: val=va_arg(ap, int); break; - case 2: val=va_arg(ap, long); break; - case 4: val=va_arg(ap, unsigned short); break; - case 5: val=va_arg(ap, unsigned int); break; - case 6: val=va_arg(ap, unsigned long); break; - default:val=0; break; - } - cp = __numout(val,base,out); - if(0) { - case 's': - cp=va_arg(ap, char *); - } - count--; - c = strlen(cp); - if( !maxsize ) maxsize = c; - if( minsize > 0 ) - { - minsize -= c; - while(minsize>0) { putch(padch); count++; minsize--; } - minsize=0; - } - if( minsize < 0 ) minsize= -minsize-c; - while(*cp && maxsize-->0 ) - { - putch(*cp++); - count++; - } - while(minsize>0) { putch(' '); count++; minsize--; } - break; - case 'c': - putch(va_arg(ap, int)); - break; - default: - putch(c); - break; - } - } - } - va_end(ap); - return count; -} - -const char nstring[]="0123456789ABCDEF"; - -#if ASM_CVT==0 - -static unsigned char * -__fastcall -__numout(long i, int base, unsigned char *out) -{ - int n; - int flg = 0; - unsigned long val; - - if (base<0) - { - base = -base; - if (i<0) - { - flg = 1; - i = -i; - } - } - val = i; - - out[NUMLTH] = '\0'; - n = NUMLTH-1; - do - { -#if 1 - out[n] = nstring[val % base]; - val /= base; - --n; -#else - out[n--] = nstring[remLS(val,base)]; - val = divLS(val,base); -#endif - } - while(val); - if(flg) out[n--] = '-'; - - return &out[n+1]; -} -#else - -#asm -! numout.s -! -#if 0 -.data -_nstring: -.ascii "0123456789ABCDEF" -.byte 0 -#endif - -.bss -___out lcomm $C - -.text -___numout: -push bp -mov bp,sp -push di -push si -add sp,*-4 -mov byte ptr -8[bp],*$0 ! flg = 0 -mov si,4[bp] ; i or val.lo -mov di,6[bp] ; i or val.hi -mov cx,8[bp] ; base -test cx,cx ! base < 0 ? -jge .3num -neg cx ! base = -base -or di,di ! i < 0 ? -jns .5num -mov byte ptr -8[bp],*1 ! flg = 1 -neg di ! i = -i -neg si -sbb di,*0 -.5num: -.3num: -mov byte ptr [___out+$B],*$0 ! out[11] = nul -mov -6[bp],*$A ! n = 10 - -.9num: -!!! out[n--] = nstring[val % base]; -xor dx,dx -xchg ax,di -div cx -xchg ax,di -xchg ax,si -div cx -xchg ax,si ! val(new) = val / base - -mov bx,dx ! dx = val % base - -mov al,_nstring[bx] -mov bx,-6[bp] -dec word ptr -6[bp] -mov ___out[bx],al - -mov ax,si -or ax,di ! while (val) -jne .9num - -cmp byte ptr -8[bp],*$0 ! flg == 0 ? -je .Dnum - -mov bx,-6[bp] -dec word ptr -6[bp] -mov byte ptr ___out[bx],*$2D ! out[n--] = minus - -.Dnum: -mov ax,-6[bp] -add ax,#___out+1 - -add sp,*4 -pop si -pop di -pop bp -ret -#endasm - -#endif diff --git a/branches/s100/cpurom/src/crt0.s b/branches/s100/cpurom/src/crt0.s deleted file mode 100644 index cd5212df..00000000 --- a/branches/s100/cpurom/src/crt0.s +++ /dev/null @@ -1,97 +0,0 @@ -; modified 4/22/2011 for the N8VEM Home Computer Z180 -- John Coffman -; -;-------------------------------------------------------------------------- -; crt0.s - Generic crt0.s for a Z80 -; -; Copyright (C) 2000, Michael Hope -; -; This library is free software; you can redistribute it and/or modify it -; under the terms of the GNU General Public License as published by the -; Free Software Foundation; either version 2.1, or (at your option) any -; later version. -; -; This library is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this library; see the file COPYING. If not, write to the -; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, -; MA 02110-1301, USA. -; -; As a special exception, if you link this library with other files, -; some of which are compiled with SDCC, to produce an executable, -; this library does not by itself cause the resulting executable to -; be covered by the GNU General Public License. This exception does -; not however invalidate any other reasons why the executable file -; might be covered by the GNU General Public License. -;-------------------------------------------------------------------------- - -;;; .module crt0 - .globl _main - - .area _HEADER (ABS) - ;; Reset vector - .org 0 - jp init - - .org 0x08 - ret - .org 0x10 - ret - .org 0x18 - ret - .org 0x20 - ret - .org 0x28 - ret - .org 0x30 - ret - .org 0x38 - ret - .org 0x66 ; NMI interrupt - retn - - .org 0x100 -init: - ;; Stack at the top of memory. - ld sp,#0xffff - - ;; Initialise global variables - call gsinit - call _main - jp _exit - - ;; Ordering of segments for the linker. - .area _HOME - .area _CODE - .area _GSINIT - .area _GSFINAL - - .area _DATA - .area _BSEG - .area _BSS - .area _HEAP - - .area _CODE -.if 0 -__clock:: - ld a,#2 - rst 0x08 - ret -.endif - -_exit:: - ;; Exit - special code to the emulator - ld a,#0 - rst 0x08 -1$: - halt - jr 1$ - - .area _GSINIT -gsinit:: - - .area _GSFINAL - ret diff --git a/branches/s100/cpurom/src/crt0jplp.s b/branches/s100/cpurom/src/crt0jplp.s deleted file mode 100644 index 41005105..00000000 --- a/branches/s100/cpurom/src/crt0jplp.s +++ /dev/null @@ -1,9 +0,0 @@ -;-------------------------------------------------------------------------- -; crt0jplp.s 8/7/2011 dwg - - Generic crt0.s for a Z80 with jump loop -;-------------------------------------------------------------------------- - - .area _HEADER (ABS) - .org 0 -jploop: jp jploop - - diff --git a/branches/s100/cpurom/src/crt0scrm.s b/branches/s100/cpurom/src/crt0scrm.s deleted file mode 100644 index b787bde5..00000000 --- a/branches/s100/cpurom/src/crt0scrm.s +++ /dev/null @@ -1,44 +0,0 @@ -;-------------------------------------------------------------------------- -; crt0scrm.s 8/7/2011 dwg - - Generic crt0.s for a Z80 with jump loop -;-------------------------------------------------------------------------- - - - .area _HEADER (ABS) - .org 0 - - .include "scsi2ide.inc" - .include "ns16550.inc" - -scream: - - ld a,#UART_DLAB - out (wUART_LCR),a - - ld a,#0x00 - out (wUART_DIV_HI),a - - ld a,#UART_BAUD_9600 - out (wUART_DIV_LO),a - - ld a,#0 - out (wUART_LCR),a - - ld a,#0x03 - out (wUART_LCR),a - - ld a,#0x03 - out (wUART_MCR),a - -scrmlp: - in a,(rUART_LSR) - and a,#UART_TBE - jp z,scrmlp - - ld a,#0x30 ; ascii 0 (zero) - out (wUART_TDR),a - - jp scrmlp - - - - diff --git a/branches/s100/cpurom/src/dbgmon.s b/branches/s100/cpurom/src/dbgmon.s deleted file mode 100644 index b39b1a84..00000000 --- a/branches/s100/cpurom/src/dbgmon.s +++ /dev/null @@ -1,1764 +0,0 @@ - .title dbgmon.s derived from dbgmon.asm - .sbttl Ported by Douglas Goodall - - .module dbgmon - .optsdcc -mz80 - -;-------------------------------------------------------- -; Public variables in this module -;-------------------------------------------------------- - .globl _dbgmon -;-------------------------------------------------------- -; special function registers -;-------------------------------------------------------- -;-------------------------------------------------------- -; ram data -;-------------------------------------------------------- - .area _DATA -;-------------------------------------------------------- -; overlayable items in ram -;-------------------------------------------------------- - .area _OVERLAY -;-------------------------------------------------------- -; external initialized ram data -;-------------------------------------------------------- -;-------------------------------------------------------- -; global & static initialisations -;-------------------------------------------------------- - .area _HOME - .area _GSINIT - .area _GSFINAL - .area _GSINIT -;-------------------------------------------------------- -; Home -;-------------------------------------------------------- - .area _HOME - .area _HOME -;-------------------------------------------------------- -; code -;-------------------------------------------------------- - .area _DBGMON -_dbgmon_start:: -_dbgmon: - - -;___ROM_MONITOR_PROGRAM_____________________________________________________________________________________________________________ -; -; ORIGINAL CODE BY: ANDREW LYNCH (LYNCHAJ@YAHOO COM) 13 FEB 2007 -; -; MODIFIED BY : DAN WERNER 03 09.2009 -; -;__REFERENCES________________________________________________________________________________________________________________________ -; THOMAS SCHERRER BASIC HAR.DWARE TEST ASSEMBLER SOURCES FROM THE Z80 INFO PAGE -; INCLUDING ORIGINAL SCHEMATIC CONCEPT -; HTTP://Z80 INFO/Z80SOURC.TXT -; CODE SAMPLES FROM BRUCE JONES PUBLIC DOMAIN ROM MONITOR FOR THE SBC-200C -; HTTP://WWW RETROTECHNOLOGY.COM/HERBS_STUFF/SD_BRUCE_CODE.ZIP -; INSPIRATION FROM JOEL OWENS "Z-80 SPACE-TIME PRODUCTIONS SINGLE BOARD COMPUTER" -; HTTP://WWW JOELOWENS.ORG/Z80/Z80INDEX.HTML -; GREAT HELP AND TECHNICAL ADVICE FROM ALLISON AT ALPACA_DESIGNERS -; HTTP://GROUPS YAHOO.COM/GROUP/ALPACA_DESIGNERS -; INTEL SDK-85 ROM DEBUG MONITOR -; -;__HARDWARE_INTERFACES________________________________________________________________________________________________________________ -; -; PIO 82C55 I/O IS DECODED TO PORT 60-67 -; -PORTA = 0x60 -PORTB = 0x61 -PORTC = 0x62 -PIOCONT = 0x63 -; -; UART 16C450 SERIAL IS DECODED TO 68-6F -; -UART0 = 0x68 ; DATA IN/OUT -UART1 = 0x69 ; CHECK RX -UART2 = 0x6A ; INTERRUPTS -UART3 = 0x6B ; LINE CONTROL -UART4 = 0x6C ; MODEM CONTROL -UART5 = 0x6D ; LINE STATUS -UART6 = 0x6E ; MODEM STATUS -UART7 = 0x6F ; SCRATCH REG. -; -; MEMORY PAGE CONFIGURATION LATCH IS DECODED TO 78 -; -MPCL = 0x78 ; CONTROL PORT, SHOULD ONLY BE CHANGED WHILE -; IN UPPER MEMORY PAGE 08000h-$FFFF OR LIKELY -MPCL_RAM = 0x78 ; BASE IO ADDRESS OF RAM MEMORY PAGER CONFIGURATION LATCH -MPCL_ROM = 0x7C ; BASE IO ADDRESS OF ROM MEMORY PAGER CONFIGURATION LATCH -; LOSS OF CPU MEMORY CONTEXT -; -; MEMORY PAGE CONFIGURATION LATCH CONTROL PORT ( IO_Y3 ) INFORMATION -; -; 7 6 5 4 3 2 1 0 ONLY APPLICABLE TO THE LOWER MEMORY PAGE 00000h-$7FFF -; ^ ^ ^ ^ ^ ^ ^ ^ -; : : : : : : : :--0 = A15 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : : : : :----0 = A16 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : : : :------0 = A17 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : : :--------0 = A18 RAM/ROM ADDRESS LINE DEFAULT IS 0 -; : : : :-----------0 = A19 ROM ONLY ADDRESS LINE DEFAULT IS 0 -; : : :-------------0 = -; : :---------------0 = -; :-----------------0 = ROM SELECT (0=ROM, 1=RAM) DEFAULT IS 0 -; -; -;IDE REGISTER IO PORT ; FUNCTION -IDELO = 0x020 ; DATA PORT (LOW BYTE) -IDEERR = 0x021 ; READ: ERROR REGISTER; WRITE: PRECOMP -IDESECTC = 0x022 ; SECTOR COUNT -IDESECTN = 0x023 ; SECTOR NUMBER -IDECYLLO = 0x024 ; CYLINDER LOW -IDECYLHI = 0x025 ; CYLINDER HIGH -IDEHEAD = 0x026 ; DRIVE/HEAD -IDESTTS = 0x027 ; READ: STATUS; WRITE: COMMAND -IDEHI = 0x028 ; DATA PORT (HIGH BYTE) -IDECTRL = 0x02E ; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL -IDEADDR = 0x02F ; DRIVE ADDRESS (READ ONLY) - -; -; -;__CONSTANTS_________________________________________________________________________________________________________________________ -; -RAMTOP = 0x0FFFF ; HIGHEST ADDRESSABLE MEMORY LOCATION -STACKSTART = 0x0CFFF ; START OF STACK -RAMBOTTOM = 0x08000 ; START OF FIXED UPPER 32K PAGE OF 512KB X 8 RAM 8000H-FFFFH -MONSTARTCOLD = 0x08000 ; COLD START MONITOR IN HIGH RAM -ENDT = 0x0FF ; MARK END OF TEXT -CR = 0x0D ; ASCII CARRIAGE RETURN CHARACTER -LF = 0x0A ; ASCII LINE FEED CHARACTER -ESC = 0x1B ; ASCII ESCAPE CHARACTER -BS = 0x08 ; ASCII BACKSPACE CHARACTER - -ASCIIA = 0x41 -ASCIIB = 0x42 -ASCIIC = 0x43 -ASCIID = 0x44 -ASCIIE = 0x45 -ASCIIF = 0x46 -ASCIIG = 0x47 -ASCIIH = 0x48 -ASCIII = 0x49 -ASCIIJ = 0x4A -ASCIIK = 0x4B -ASCIIL = 0x4C -ASCIIM = 0x4D -ASCIIN = 0x4E -ASCIIO = 0x4F -ASCIIP = 0x50 -ASCIIQ = 0x51 -ASCIIR = 0x52 -ASCIIS = 0x53 -ASCIIT = 0x54 -ASCIIU = 0x55 -ASCIIV = 0x56 -ASCIIW = 0x57 -ASCIIX = 0x58 -ASCIIY = 0x59 -ASCIIZ = 0x5A - -; -; -; -;__MAIN_PROGRAM_____________________________________________________________________________________________________________________ -; -; ORG 00100h ; FOR DEBUG IN CP/M (AS .COM) - -;dwg; .ORG 8000H ; NORMAL OP - - LD SP,#STACKSTART ; SET THE STACK POINTER TO STACKSTART - CALL INITIALIZE ; INITIALIZE SYSTEM - - - -;__FRONT_PANEL_STARTUP___________________________________________________________________________________________________________ -; -; START UP THE SYSTEM WITH THE FRONT PANEL INTERFACE -; -;________________________________________________________________________________________________________________________________ -; - CALL MTERM_INIT ; INIT 8255 FOR MTERM - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - - - -FRONTPANELLOOP: - CALL KB_GET ; GET KEY FROM KB - - CP #0x10 ; IS PORT READ? - JP Z,DOPORTREAD ; YES, JUMP - CP #0x11 ; IS PORT WRITE? - JP Z,DOPORTWRITE ; YES, JUMP - CP #0x14 ; IS DEPOSIT? - JP Z,DODEPOSIT ; YES, JUMP - CP #0x15 ; IS EXAMINE? - JP Z,DOEXAMINE ; YES, JUMP - CP #0x16 ; IS GO? - JP Z,DOGO ; YES, JUMP - CP #0x17 ; IS BO? - JP Z,DOBOOT ; YES, JUMP - - JR FRONTPANELLOOP ; LOOP -EXIT: - RET - - -;__DOBOOT________________________________________________________________________________________________________________________ -; -; PERFORM BOOT FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOBOOT: - LD A,#0 ; LOAD VALUE TO SWITCH OUT ROM - OUT (MPCL_ROM),A ; SWITCH OUT ROM, BRING IN LOWER 32K RAM PAGE - ; - ; - OUT (MPCL_RAM),A ; - JP 0 ; GO TO CP/M - - -;__DOPORTREAD____________________________________________________________________________________________________________________ -; -; PERFORM PORT READ FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOPORTREAD: - CALL GETPORT ; GET PORT INTO A -PORTREADLOOP: - LD C,A ; STORE PORT IN "C" - SRL A ; ROTATE HIGH NIB TO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; SHOW HIGH NIB IN DISP 5 - LD A,C ; RESTORE PORT VALUE INTO "A" - AND #0x0F ; CLEAR HIGH NIB, LEAVING LOW - LD (DISPLAYBUF+4),A ; SHOW LOW NIB IN DISP 4 - IN A,(C) ; GET PORT VALUE FROM PORT IN "C" - LD C,A ; STORE VALUE IN "C" - SRL A ; ROTATE HIGH NIB TO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; SHOW HIGH NIB IN DISP 1 - LD A,C ; RESTORE VALUE TO "A" - AND #0x0F ; CLEAR HIGH NIB, LEAVING LOW - LD (DISPLAYBUF),A ; DISPLAY LOW NIB IN DISP 0 - LD A,#0x10 ; CLEAR OTHER DISPLAYS - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - LD A,#0x13 ; "P" - LD (DISPLAYBUF+7),A ; STORE IN DISP 7 - LD A,#0x14 ; "O" - LD (DISPLAYBUF+6),A ; STORE IN DISP 6 - LD HL,#DISPLAYBUF ; SET POINTER TO DISPLAY BUFFER - CALL HEXDISPLAY ; DISPLAY BUFFER CONTENTS -PORTREADGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP #0x12 ; [CL] PRESSED, EXIT - JP Z,PORTREADEXIT ; - CP #0x10 ; [PR] PRESSED, PROMPT FOR NEW PORT - JR Z,DOPORTREAD ; - JR PORTREADGETKEY ; NO VALID KEY, LOOP -PORTREADEXIT: - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - -;__DOPORTWRITE____________________________________________________________________________________________________________________ -; -; PERFORM PORT WRITE FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOPORTWRITE: - CALL GETPORT ; GET PORT INTO A -PORTWRITELOOP: - LD C,A ; STORE PORT IN "C" - SRL A ; ROTATE HIGH NIB INTO LOW - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; DISPLAY HIGH NIB IN DISPLAY 5 - LD A,C ; RESTORE PORT VALUE INTO "A" - AND #0x0F ; CLEAR OUT HIGH NIB - LD (DISPLAYBUF+4),A ; DISPLAY LOW NIB IN DISPLAY 4 - LD A,#0x10 ; CLEAR OUT DISPLAYS 2 AND 3 - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - LD A,#0x13 ; DISPLAY "P" IN DISP 7 - LD (DISPLAYBUF+7),A ; - LD A,#0x14 ; DISPLAY "O" IN DISP 6 - LD (DISPLAYBUF+6),A ; - LD HL,#DISPLAYBUF ; POINT TO DISPLAY BUFFER - CALL GETVALUE ; INPUT A BYTE VALUE, RETURN IN "A" - OUT (C),A ; OUTPUT VALUE TO PORT STORED IN "C" - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - -;__DOGO__________________________________________________________________________________________________________________________ -; -; PERFORM GO FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOGO: - CALL GETADDR ; GET ADDRESS INTO HL - JP (HL) ; GO THERE! - - - -;__DODEPOSIT________________________________________________________________________________________________________________________ -; -; PERFORM DEPOSIT FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DODEPOSIT: - CALL GETADDR ; GET ADDRESS INTO HL - PUSH HL -DEPOSITLOOP: - LD A,H ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,H ; - AND #0x0F ; - LD (DISPLAYBUF+6),A ; - LD A,L ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,L ; - AND #0x0F ; - LD (DISPLAYBUF+4),A ; - LD A,#0x10 ; - LD (DISPLAYBUF+3),A ; - LD HL,#DISPLAYBUF ; - CALL GETVALUE ; - POP HL ; - LD (HL),A ; -DEPOSITGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP #0x12 ; [CL] PRESSED, EXIT - JP Z,DEPOSITEXIT ; - CP #0x13 ; [EN] PRESSED, INC ADDRESS AND LOOP - JR Z,DEPOSITFW ; - CP #0x14 ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - JR Z,DODEPOSIT ; - JR DEPOSITGETKEY ; NO VALID KEY, LOOP -DEPOSITFW: - INC HL ; - PUSH HL ; STORE HL - JR DEPOSITLOOP ; -DEPOSITEXIT: - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - - - -;__DOEXAMINE________________________________________________________________________________________________________________________ -; -; PERFORM EXAMINE FRONT PANEL ACTION -;________________________________________________________________________________________________________________________________ -; -DOEXAMINE: - CALL GETADDR ; GET ADDRESS INTO HL - PUSH HL ; STORE HL -EXAMINELOOP: - LD A,H ; MOVE HIGH BYTE IN "A" - SRL A ; SHOW HIGH NIBBLE IN DISP 7 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+7),A ; - LD A,H ; RESTORE HIGH BYTE - AND #0x0F ; CLEAR HIGH NIBBLE - LD (DISPLAYBUF+6),A ; DISPLAY LOW NIBBLE IN DISP 6 - LD A,L ; PUT LOW BYTE IN "A" - SRL A ; SHOW HIGH NIBBLE IN DISP 5 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+5),A ; - LD A,L ; RESTORE LOW BYTE IN "A" - AND #0x0F ; CLEAR OUT HIGH NIBBLE - LD (DISPLAYBUF+4),A ; DISPLAY LOW NIBBLE IN DISP 4 - LD A,#0x10 ; CLEAR OUT DISP 3 - LD (DISPLAYBUF+3),A ; - LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - SRL A ; DISPLAY HIGH NIB IN DISPLAY 1 - SRL A ; - SRL A ; - SRL A ; - LD (DISPLAYBUF+1),A ; - LD A,(HL) ; GET VALUE FROM ADDRESS IN HL - AND #0x0F ; CLEAR OUT HIGH NIBBLE - LD (DISPLAYBUF),A ; DISPLAY LOW NIBBLE IN DISPLAY 0 - LD HL,#DISPLAYBUF ; POINT TO DISPLAY BUFFER - CALL HEXDISPLAY ; DISPLAY BUFFER ON DISPLAYS - POP HL ; RESTORE HL -EXAMINEGETKEY: - CALL KB_GET ; GET KEY FROM KB - CP #0x12 ; [CL] PRESSED, EXIT - JP Z,EXAMINEEXIT ; - CP #0x13 ; [EN] PRESSED, INC ADDRESS AND LOOP - JR Z,EXAMINEFW ; - CP #0x15 ; [DE] PRESSED, PROMPT FOR NEW ADDRESS - JR Z,DOEXAMINE ; - JR EXAMINEGETKEY ; NO VALID KEY, LOOP -EXAMINEFW: - INC HL ; HL++ - PUSH HL ; STORE HL - JR EXAMINELOOP ; -EXAMINEEXIT: - LD HL,#CPUUP ; SET POINTER TO DATA BUFFER - CALL SEGDISPLAY ; DISPLAY - JP FRONTPANELLOOP ; - - -;__GETADDR_______________________________________________________________________________________________________________________ -; -; GET ADDRESS FROM FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -GETADDR: - PUSH BC ; STORE BC - JR GETADDRCLEAR ; -GETADDR1: - LD HL,#ADDR ; DISPLAY PROMPT - CALL SEGDISPLAY ; -GETADDRLOOP: - CALL KB_GET ; - CP #0x10 ; - JP M,GETADDRNUM ; NUMBER PRESSED, STORE IT - CP #0x13 ; EN PRESSED, DONE - JR Z,GETADDRDONE ; - CP #0x12 ; CLEAR PRESSED, CLEAR - JR Z,GETADDRCLEAR ; - JR GETADDRLOOP ; INVALID KEY, LOOP -GETADDRDONE: - LD HL,#0 ; HL=0 - LD A,(DISPLAYBUF+1) ; GET DIGIT IN DISPLAY 1 - SLA A ; ROTATE IT TO HIGH NIBBLE - SLA A ; - SLA A ; - SLA A ; - LD C,A ; STORE IT IN "C" - LD A,(DISPLAYBUF) ; GET DIGIT IN DISPLAY 0 - AND #0x0F ; CLEAR HIGH NIBBLE - OR C ; ADD IN NIBBLE STORED IN C - LD L,A ; STORE IT IN LOW BYTE OF ADDRESS POINTER - LD A,(DISPLAYBUF+3) ; GET DIGIT IN DISPLAY 3 - SLA A ; ROTATE IT TO HIGH NIBBLE - SLA A ; - SLA A ; - SLA A ; - LD C,A ; STORE IT IN "C" - LD A,(DISPLAYBUF+2) ; GET DIGIT IN DISPLAY 2 - AND #0x0F ; CLEAR HIGH NIBBLE - OR C ; ADD IN NIBBLE STORED IN "C" - LD H,A ; STORE BYTE IN HIGH BYTE OF ADDRESS POINTER - LD A,#0x10 ; CLEAR OUT DISPLAYS 0,1,2 & 3 - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; - POP BC ; RESTORE BC - RET -GETADDRNUM: - LD C,A ; - LD A,(DISPLAYBUF+2) ; SHIFT BYTES IN DISPLAY BUF TO THE LEFT - LD (DISPLAYBUF+3),A ; - LD A,(DISPLAYBUF+1) ; - LD (DISPLAYBUF+2),A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; DISPLAY KEYSTROKE IN RIGHT MOST DISPLAY (0) - LD (DISPLAYBUF+0),A ; - JR GETADDRDISP ; -GETADDRCLEAR: - LD A,#0x12 ; CLEAR OUT DISPLAYS 0,1,2 & 3 - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD (DISPLAYBUF+2),A ; - LD (DISPLAYBUF+3),A ; -GETADDRDISP: - LD A,(DISPLAYBUF) ; ENCODE DIGITS IN DISPLAY BUFFER TO DISPLAY - CALL DECODEDISPLAY ; - LD (ADDR),A ; - LD A,(DISPLAYBUF+1) ; - CALL DECODEDISPLAY ; - LD (ADDR+1),A ; - LD A,(DISPLAYBUF+2) ; - CALL DECODEDISPLAY ; - LD (ADDR+2),A ; - LD A,(DISPLAYBUF+3) ; - CALL DECODEDISPLAY ; - LD (ADDR+3),A ; - JP GETADDR1 ; - - - -;__DSPSECTOR_______________________________________________________________________________________________________________________ -; -; DISPLAY SECTOR IN HL ON FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -DSPSECTOR: - PUSH BC ; STORE BC - PUSH HL ; STORE HL - LD A,H ; DISPLAY HIGH BYTE, HIGH NIBBLE - SRL A ; - SRL A ; - SRL A ; - SRL A ; - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC+3),A ; - LD A,H ; DISPLAY HIGH BYTE, LOW NIBBLE - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC+2),A ; - LD A,L ; DISPLAY LOW BYTE, HIGH NIBBLE - AND #0x0F0 ; - SRL A ; - SRL A ; - SRL A ; - SRL A ; - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC+1),A ; DISPLAY LOW BYTE, LOW NIBBLE - LD A,L ; - AND #0x0F ; - CALL DECODEDISPLAY ; - LD (SEC),A ; - LD HL,#SEC ; DISPLAY PROMPT - CALL SEGDISPLAY ; - POP HL ; RESTORE HL - POP BC ; RESTORE BC - RET - - - -;__GETPORT_______________________________________________________________________________________________________________________ -; -; GET PORT FROM FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -GETPORT: - PUSH BC ; STORE BC - JR GETPORTCLEAR ; -GETPORT1: - LD HL,#PORT ; DISPLAY PROMPT - CALL SEGDISPLAY ; -GETPORTLOOP: - CALL KB_GET ; - CP #0x10 ; - JP M,GETPORTNUM ; NUMBER PRESSED, STORE IT - CP #0x13 ; EN PRESSED, DONE - JR Z,GETPORTDONE ; - CP #0x12 ; CLEAR PRESSED, CLEAR - JR Z,GETPORTCLEAR ; - JR GETPORTLOOP ; INVALID KEY, LOOP -GETPORTDONE: - LD A,(DISPLAYBUF+1) ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - LD C,A ; - LD A,(DISPLAYBUF) ; - AND #0x0F ; - OR C ; - LD C,A ; - LD A,#0x10 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - POP BC ; RESTORE BC - RET -GETPORTNUM: - LD C,A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - LD (DISPLAYBUF+0),A ; - JR GETPORTDISP ; -GETPORTCLEAR: - LD A,#0x12 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; -GETPORTDISP: - LD A,(DISPLAYBUF) ; - CALL DECODEDISPLAY ; - LD (PORT),A ; - LD A,(DISPLAYBUF+1) ; - CALL DECODEDISPLAY ; - LD (PORT+1),A ; - JP GETPORT1 ; - - -;__GETVALUE______________________________________________________________________________________________________________________ -; -; GET VALUE FROM FRONT PANEL -;________________________________________________________________________________________________________________________________ -; -GETVALUE: - PUSH BC ; STORE BC - JR GETVALUECLEAR ; -GETVALUE1: - CALL HEXDISPLAY ; - -GETVALUELOOP: - CALL KB_GET ; - CP #0x10 ; - JP M,GETVALUENUM ; NUMBER PRESSED, STORE IT - CP #0x13 ; EN PRESSED, DONE - JR Z,GETVALUEDONE ; - CP #0x12 ; CLEAR PRESSED, CLEAR - JR Z,GETVALUECLEAR ; - JR GETVALUELOOP ; INVALID KEY, LOOP -GETVALUEDONE: - LD A,(DISPLAYBUF+1) ; - SLA A ; - SLA A ; - SLA A ; - SLA A ; - LD C,A ; - LD A,(DISPLAYBUF) ; - AND #0x0F ; - OR C ; - LD C,A ; - LD A,#0x10 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - POP BC ; RESTORE BC - RET -GETVALUENUM: - LD C,A ; - LD A,(DISPLAYBUF) ; - LD (DISPLAYBUF+1),A ; - LD A,C ; - LD (DISPLAYBUF+0),A ; - JR GETVALUE1 ; -GETVALUECLEAR: - LD A,#0x12 ; - LD (DISPLAYBUF),A ; - LD (DISPLAYBUF+1),A ; - JP GETVALUE1 ; - - -;__MONSTARTWARM___________________________________________________________________________________________________________________ -; -; SERIAL MONITOR STARTUP -;________________________________________________________________________________________________________________________________ -; - -MONSTARTWARM: ; CALL HERE FOR SERIAL MONITOR WARM START - LD SP,#STACKSTART ; SET THE STACK POINTER TO STACKSTART - CALL INITIALIZE ; INITIALIZE SYSTEM - - XOR A ;ZERO OUT ACCUMULATOR (ADDED) - PUSH HL ;PROTECT HL FROM OVERWRITE - LD HL,#TXT_READY ;POINT AT TEXT - CALL MSG ;SHOW WE'RE HERE - POP HL ;PROTECT HL FROM OVERWRITE - -; -;__SERIAL_MONITOR_COMMANDS_________________________________________________________________________________________________________ -; -; B XX BOOT CPM FROM DRIVE XX -; D XXXXH YYYYH DUMP MEMORY FROM XXXX TO YYYY -; F XXXXH YYYYH ZZH FILL MEMORY FROM XXXX TO YYYY WITH ZZ -; H LOAD INTEL HEX FORMAT DATA -; I INPUT FROM PORT AND SHOW HEX DATA -; K ECHO KEYBOARD INPUT -; M XXXXH YYYYH ZZZZH MOVE MEMORY BLOCK XXXX TO YYYY TO ZZZZ -; O OUTPUT TO PORT HEX DATA -; P XXXXH YYH PROGRAM RAM FROM XXXXH WITH VALUE IN YYH, WILL PROMPT FOR NEXT LINES FOLLOWING UNTIL CR -; R RUN A PROGRAM FROM CURRENT LOCATION - - - -;__COMMAND_PARSE_________________________________________________________________________________________________________________ -; -; PROMPT USER FOR COMMANDS, THEN PARSE THEM -;________________________________________________________________________________________________________________________________ -; - -SERIALCMDLOOP: - CALL CRLFA ; CR,LF,> - LD HL,#KEYBUF ; SET POINTER TO KEYBUF AREA - CALL GETLN ; GET A LINE OF INPUT FROM THE USER - LD HL,#KEYBUF ; RESET POINTER TO START OF KEYBUF - LD A,(HL) ; LOAD FIRST CHAR INTO A (THIS SHOULD BE THE COMMAND) - INC HL ; INC POINTER - - CP #ASCIIB ; IS IT "B" (Y/N) - JP Z,DOBOOT ; IF YES DO BOOT - CP #ASCIIR ; IS IT "R" (Y/N) - JP Z,RUN ; IF YES GO RUN ROUTINE - CP #ASCIIP ; IS IT "P" (Y/N) - JP Z,PROGRM ; IF YES GO PROGRAM ROUTINE - CP #ASCIIO ; IS IT AN "O" (Y/N) - JP Z,POUT ; PORT OUTPUT - CP #ASCIIH ; IS IT A "H" (Y/N) - JP Z,HXLOAD ; INTEL HEX FORMAT LOAD DATA - CP #ASCIII ; IS IT AN "I" (Y/N) - JP Z,PIN ; PORT INPUT - CP #ASCIID ; IS IT A "D" (Y/N) - JP Z,DUMP ; DUMP MEMORY - CP #ASCIIK - JP Z,KLOP ; LOOP ON KEYBOARD - CP #ASCIIM ; IS IT A "M" (Y/N) - JP Z,MOVE ; MOVE MEMORY COMMAND - CP #ASCIIF ; IS IT A "F" (Y/N) - JP Z,FILL ; FILL MEMORY COMMAND - LD HL,#TXT_COMMAND ; POINT AT ERROR TEXT - CALL MSG ; PRINT COMMAND LABEL - - JR SERIALCMDLOOP - - - - - -;__KLOP__________________________________________________________________________________________________________________________ -; -; READ FROM THE SERIAL PORT AND ECHO, MONITOR COMMAND "K" -;________________________________________________________________________________________________________________________________ -; -KLOP: - CALL KIN ; GET A KEY - CALL COUT ; OUTPUT KEY TO SCREEN - CP #ESC ; IS ? - JR NZ,KLOP ; NO, LOOP - JP SERIALCMDLOOP ; - -;__GETLN_________________________________________________________________________________________________________________________ -; -; READ A LINE(80) OF TEXT FROM THE SERIAL PORT, HANDLE , TERM ON -; EXIT IF TOO MANY CHARS STORE RESULT IN HL. CHAR COUNT IN C. -;________________________________________________________________________________________________________________________________ -; -GETLN: - LD C,#0 ; ZERO CHAR COUNTER - PUSH DE ; STORE DE -GETLNLOP: - CALL KIN ; GET A KEY - CALL COUT ; OUTPUT KEY TO SCREEN - CP #CR ; IS ? - JR Z,GETLNDONE ; YES, EXIT - CP #BS ; IS ? - JR NZ,GETLNSTORE ; NO, STORE CHAR - LD A,C ; A=C - CP #0 ; - JR Z,GETLNLOP ; NOTHING TO BACKSPACE, IGNORE & GET NEXT KEY - DEC HL ; PERFORM BACKSPACE - DEC C ; LOWER CHAR COUNTER - LD A,#0 ; - LD (HL),A ; STORE NULL IN BUFFER - LD A,#0x20 ; BLANK OUT CHAR ON TERM - CALL COUT ; - LD A,#BS ; - CALL COUT ; - JR GETLNLOP ; GET NEXT KEY -GETLNSTORE: - LD (HL),A ; STORE CHAR IN BUFFER - INC HL ; INC POINTER - INC C ; INC CHAR COUNTER - LD A,C ; A=C - CP #0x4D ; OUT OF BUFFER SPACE? - JR NZ,GETLNLOP ; NOPE, GET NEXT CHAR -GETLNDONE: - LD (HL),#0 ; STORE NULL IN BUFFER - POP DE ; RESTORE DE - RET ; - - -;__KIN___________________________________________________________________________________________________________________________ -; -; READ FROM THE SERIAL PORT AND ECHO & CONVERT INPUT TO UCASE -;________________________________________________________________________________________________________________________________ -; -KIN: - IN A,(UART5) ; READ LINE STATUS REGISTER - BIT 0,A ; TEST IF DATA IN RECEIVE BUFFER - JP Z,KIN ; LOOP UNTIL DATA IS READY - IN A,(UART0) ; THEN READ THE CHAR FROM THE UART - AND #0x7F ; STRIP HI BIT - CP #ASCIIA ; KEEP NUMBERS, CONTROLS - RET C ; AND UPPER CASE - CP #0x7B ; SEE IF NOT LOWER CASE - RET NC ; - AND #0x5F ; MAKE UPPER CASE - RET - - -;__COUT__________________________________________________________________________________________________________________________ -; -; WRITE THE VALUE IN "A" TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -COUT: - PUSH AF ; STORE AF -TX_BUSYLP: - IN A,(UART5) ; READ LINE STATUS REGISTER - BIT 5,A ; TEST IF UART IS READY TO SEND - JP Z,TX_BUSYLP ; IF NOT REPEAT - POP AF ; RESTORE AF - OUT (UART0),A ; THEN WRITE THE CHAR TO UART - RET ; DONE - - -;__CRLF__________________________________________________________________________________________________________________________ -; -; SEND CR & LF TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -CRLF: - PUSH HL ; PROTECT HL FROM OVERWRITE - LD HL,#TCRLF ; LOAD MESSAGE POINTER - CALL MSG ; SEBD MESSAGE TO SERIAL PORT - POP HL ; PROTECT HL FROM OVERWRITE - RET ; - - -;__LDHL__________________________________________________________________________________________________________________________ -; -; GET ONE WORD OF HEX DATA FROM BUFFER POINTED TO BY HL SERIAL PORT, RETURN IN HL -;________________________________________________________________________________________________________________________________ -; -LDHL: - PUSH DE ; STORE DE - CALL HEXIN ; GET K B. AND MAKE HEX - LD D,A ; THATS THE HI BYTE - CALL HEXIN ; DO HEX AGAIN - LD L,A ; THATS THE LOW BYTE - LD H,D ; MOVE TO HL - POP DE ; RESTORE BC - RET ; GO BACK WITH ADDRESS - - -;__HEXIN__________________________________________________________________________________________________________________________ -; -; GET ONE BYTE OF HEX DATA FROM BUFFER IN HL, RETURN IN A -;________________________________________________________________________________________________________________________________ -; -HEXIN: - PUSH BC ;SAVE BC REGS - CALL NIBL ;DO A NIBBLE - RLC A ;MOVE FIRST BYTE UPPER NIBBLE - RLC A ; - RLC A ; - RLC A ; - LD B,A ; SAVE ROTATED BYTE - CALL NIBL ; DO NEXT NIBBLE - ADD A,B ; COMBINE NIBBLES IN ACC - POP BC ; RESTORE BC - RET ; DONE -NIBL: - LD A,(HL) ; GET K B. DATA - INC HL ; INC KB POINTER - CP #0x40 ; TEST FOR ALPHA - JR NC,ALPH ; - AND #0x0F ; GET THE BITS - RET ; -ALPH: - AND #0x0F ; GET THE BITS - ADD A,#9 ; MAKE IT HEX A-F - RET ; - - -;__HEXINS_________________________________________________________________________________________________________________________ -; -; GET ONE BYTE OF HEX DATA FROM SERIAL PORT, RETURN IN A -;________________________________________________________________________________________________________________________________ -; -HEXINS: - PUSH BC ;SAVE BC REGS - CALL NIBLS ;DO A NIBBLE - RLC A ;MOVE FIRST BYTE UPPER NIBBLE - RLC A ; - RLC A ; - RLC A ; - LD B,A ; SAVE ROTATED BYTE - CALL NIBLS ; DO NEXT NIBBLE - ADD A,B ; COMBINE NIBBLES IN ACC - POP BC ; RESTORE BC - RET ; DONE -NIBLS: - CALL KIN ; GET K B. DATA - INC HL ; INC KB POINTER - CP #0x40 ; TEST FOR ALPHA - JR NC,ALPH ; - AND #0x0F ; GET THE BITS - RET ; - - -;__HXOUT_________________________________________________________________________________________________________________________ -; -; PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -HXOUT: - PUSH BC ; SAVE BC - LD B,A ; - RLC A ; DO HIGH NIBBLE FIRST - RLC A ; - RLC A ; - RLC A ; - AND #0x0F ; ONLY THIS NOW - ADD A,#0x30 ; TRY A NUMBER - CP #0x3A ; TEST IT - JR C,OUT1 ; IF CY SET PRINT 'NUMBER' - ADD A,#0x07 ; MAKE IT AN ALPHA -OUT1: - CALL COUT ; SCREEN IT - LD A,B ; NEXT NIBBLE - AND #0x0F ; JUST THIS - ADD A,#0x30 ; TRY A NUMBER - CP #0x3A ; TEST IT - JR C,OUT2 ; PRINT 'NUMBER' - ADD A,#7 ; MAKE IT ALPHA -OUT2: - CALL COUT ; SCREEN IT - POP BC ; RESTORE BC - RET ; - - -;__SPACE_________________________________________________________________________________________________________________________ -; -; PRINT A SPACE CHARACTER ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -SPACE: - PUSH AF ; STORE AF - LD A,#0x20 ; LOAD A "SPACE" - CALL COUT ; SCREEN IT - POP AF ; RESTORE AF - RET ; DONE - -;__PHL_________________________________________________________________________________________________________________________ -; -; PRINT THE HL REG ON THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -PHL: - LD A,H ; GET HI BYTE - CALL HXOUT ; DO HEX OUT ROUTINE - LD A,L ; GET LOW BYTE - CALL HXOUT ; HEX IT - CALL SPACE ; - RET ; DONE - -;__POUT__________________________________________________________________________________________________________________________ -; -; OUTPUT TO AN I/O PORT, MONITOR COMMAND "O" -;________________________________________________________________________________________________________________________________ -; -POUT: -POUT1: - INC HL ; - CALL HEXIN ; GET PORT - LD C,A ; SAVE PORT POINTER - INC HL ; - CALL HEXIN ; GET DATA -OUTIT: - OUT (C),A ; - JP SERIALCMDLOOP ; - - -;__PIN___________________________________________________________________________________________________________________________ -; -; INPUT FROM AN I/O PORT, MONITOR COMMAND "I" -;________________________________________________________________________________________________________________________________ -; -PIN: - INC HL ; - CALL HEXIN ; GET PORT - LD C,A ; SAVE PORT POINTER - CALL CRLF ; - IN A,(C) ; GET DATA - CALL HXOUT ; SHOW IT - JP SERIALCMDLOOP ; - - - - - -;__CRLFA_________________________________________________________________________________________________________________________ -; -; PRINT COMMAND PROMPT TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -CRLFA: - PUSH HL ; PROTECT HL FROM OVERWRITE - LD HL,#PROMPT ; - CALL MSG ; - POP HL ; PROTECT HL FROM OVERWRITE - RET ; DONE - - -;__MSG___________________________________________________________________________________________________________________________ -; -; PRINT A STRING TO THE SERIAL PORT -;________________________________________________________________________________________________________________________________ -; -MSG: - -TX_SERLP: - LD A,(HL) ; GET CHARACTER TO A - CP #ENDT ; TEST FOR END BYTE - JP Z,TX_END ; JUMP IF END BYTE IS FOUND - CALL COUT ; - INC HL ; INC POINTER, TO NEXT CHAR - JP TX_SERLP ; TRANSMIT LOOP -TX_END: - RET ;ELSE DONE - -;__RUN___________________________________________________________________________________________________________________________ -; -; TRANSFER OUT OF MONITOR, USER OPTION "R" -;________________________________________________________________________________________________________________________________ -; -RUN: - INC HL ; SHOW READY - CALL LDHL ; GET START ADDRESS - JP (HL) ; - - -;__PROGRM________________________________________________________________________________________________________________________ -; -; PROGRAM RAM LOCATIONS, USER OPTION "P" -;________________________________________________________________________________________________________________________________ -; -PROGRM: - INC HL ; SHOW READY - PUSH HL ; STORE HL - CALL LDHL ; GET START ADDRESS - LD D,H ; - LD E,L ; DE POINTS TO ADDRESS TO PROGRAM - POP HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; -PROGRMLP: - CALL HEXIN ; GET NEXT HEX NUMBER - LD (DE),A ; STORE IT - INC DE ; NEXT ADDRESS; - CALL CRLFA ; CR,LF,> - LD A,#ASCIIP ; - CALL COUT ; - CALL SPACE ; - LD H,D ; - LD L,E ; - CALL PHL ; - LD HL,#KEYBUF ; SET POINTER TO KEYBUF AREA - CALL GETLN ; GET A LINE OF INPUT FROM THE USER - LD HL,#KEYBUF ; RESET POINTER TO START OF KEYBUF - LD A,(HL) ; LOAD FIRST CHAR INTO A - CP #0 ; END OF LINE? - JP Z,PROGRMEXIT ; YES, EXIT - JP PROGRMLP ; NO, LOOP -PROGRMEXIT: - JP SERIALCMDLOOP - - - - - - - -;__DUMP__________________________________________________________________________________________________________________________ -; -; PRINT A MEMORY DUMP, USER OPTION "D" -;________________________________________________________________________________________________________________________________ -; -DUMP: - INC HL ; SHOW READY - PUSH HL ; STORE HL - CALL LDHL ; GET START ADDRESS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; SAVE START - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; - CALL LDHL ; GET END ADDRESS - INC HL ; ADD ONE MORE FOR LATER COMPARE - EX DE,HL ; PUT END ADDRESS IN DE - POP HL ; GET BACK START -GDATA: - CALL CRLF ; -BLKRD: - CALL PHL ; PRINT START LOCATION - LD C,#16 ; SET FOR 16 LOCS - PUSH HL ; SAVE STARTING HL -NXTONE: - EXX ; - LD C,E ; - IN A,(C) ; - EXX ; - AND #0x7F ; - CP #ESC ; - JP Z,SERIALCMDLOOP ; - CP #19 ; - JR Z,NXTONE ; - LD A,(HL) ; GET BYTE - CALL HXOUT ; PRINT IT - CALL SPACE ; -UPDH: - INC HL ; POINT NEXT - DEC C ; DEC LOC COUNT - JR NZ,NXTONE ; IF LINE NOT DONE - ; NOW PRINT 'DECODED' DATA TO RIGHT OF DUMP -PCRLF: - CALL SPACE ; SPACE IT - LD C,#16 ; SET FOR 16 CHARS - POP HL ; GET BACK START -PCRLF0: - LD A,(HL) ; GET BYTE - AND #0x060 ; SEE IF A 'DOT' - LD A,(HL) ; O K. TO GET - JR NZ,PDOT ; -DOT: - LD A,#0x2E ; LOAD A DOT -PDOT: - CALL COUT ; PRINT IT - INC HL ; - LD A,D ; - CP H ; - JR NZ,UPDH1 ; - LD A,E ; - CP L ; - JP Z,SERIALCMDLOOP ; -; -;IF BLOCK NOT DUMPED, DO NEXT CHARACTER OR LINE -UPDH1: - DEC C ; DEC CHAR COUNT - JR NZ,PCRLF0 ; DO NEXT -CONTD: - CALL CRLF ; - JP BLKRD ; - - -;__HXLOAD__________________________________________________________________________________________________________________________ -; -; LOAD INTEL HEX FORMAT FILE FROM THE SERIAL PORT, USER OPTION "H" -; -; [INTEL HEX FORMAT IS: -; 1) COLON (FRAME 0) -; 2) RECORD LENGTH FIELD (FRAMES 1 AND 2) -; 3) LOAD ADDRESS FIELD (FRAMES 3,4,5,6) -; 4) RECORD TYPE FIELD (FRAMES 7 AND 8) -; 5) DATA FIELD (FRAMES 9 TO 9+2*(RECORD LENGTH)-1 -; 6) CHECKSUM FIELD - SUM OF ALL BYTE VALUES FROM RECORD LENGTH TO AND -; INCLUDING CHECKSUM FIELD = 0 ] -; -; EXAMPLE OF INTEL HEX FORMAT FILE -; EACH LINE CONTAINS A CARRIAGE RETURN AS THE LAST CHARACTER -; :18F900002048454C4C4F20574F524C4420FF0D0AFF0D0A3EFF0D0A54BF -; :18F918006573742050726F746F7479706520524F4D204D6F6E69746FF1 -; :18F9300072205265616479200D0AFF0D0A434F4D4D414E4420524543F2 -; :18F948004549564544203AFF0D0A434845434B53554D204552524F52CD -; :16F96000FF0A0D20202D454E442D4F462D46494C452D20200A0DA4 -; :00000001FF -;________________________________________________________________________________________________________________________________ -HXLOAD: - CALL CRLF ; SHOW READY -HXLOAD0: - CALL KIN ; GET THE FIRST CHARACTER, EXPECTING A ':' -HXLOAD1: - CP #0x3A ; IS IT COLON ':'? START OF LINE OF INTEL HEX FILE - JR NZ,HXLOADERR ; IF NOT, MUST BE ERROR, ABORT ROUTINE - LD E,#0 ; FIRST TWO CHARACTERS IS THE RECORD LENGTH FIELD - CALL HEXINS ; GET US TWO CHARACTERS INTO BC, CONVERT IT TO A BYTE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD D,A ; LOAD RECORD LENGTH COUNT INTO D - CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD H,A ; PUT VALUE IN H REGISTER - CALL HEXINS ; GET NEXT TWO CHARACTERS, MEMORY LOAD ADDRESS - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD L,A ; PUT VALUE IN L REGISTER - CALL HEXINS ; GET NEXT TWO CHARACTERS, RECORD FIELD TYPE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - CP #1 ; RECORD FIELD TYPE 00 IS DATA, 01 IS END OF FILE - JR NZ,HXLOAD2 ; MUST BE THE END OF THAT FILE - CALL HEXINS ; GET NEXT TWO CHARACTERS, ASSEMBLE INTO BYTE - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD A,E ; RECALL THE CHECKSUM BYTE - AND A ; IS IT ZERO? - JP Z,HXLOADEXIT ; MUST BE O K., GO BACK FOR SOME MORE, ELSE - JR HXLOADERR ; CHECKSUMS DON'T ADD UP, ERROR OUT -HXLOAD2: - LD A,D ; RETRIEVE LINE CHARACTER COUNTER - AND A ; ARE WE DONE WITH THIS LINE? - JR Z,HXLOAD3 ; GET TWO MORE ASCII CHARACTERS, BUILD A BYTE AND CHECKSUM - CALL HEXINS ; GET NEXT TWO CHARS, CONVERT TO BYTE IN A, CHECKSUM IT - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD (HL),A ; CHECKSUM OK, MOVE CONVERTED BYTE IN A TO MEMORY LOCATION - INC HL ; INCREMENT POINTER TO NEXT MEMORY LOCATION - DEC D ; DECREMENT LINE CHARACTER COUNTER - JR HXLOAD2 ; AND KEEP LOADING INTO MEMORY UNTIL LINE IS COMPLETE -HXLOAD3: - CALL HEXINS ; GET TWO CHARS, BUILD BYTE AND CHECKSUM - CALL HXCHKSUM ; UPDATE HEX CHECK SUM - LD A,E ; CHECK THE CHECKSUM VALUE - AND A ; IS IT ZERO? - JR Z,HXLOADAGAIN ; IF THE CHECKSUM IS STILL OK, CONTINUE ON, ELSE -HXLOADERR: - LD HL,#TXT_CKSUMERR ; GET "CHECKSUM ERROR" MESSAGE - CALL MSG ; PRINT MESSAGE FROM (HL) AND TERMINATE THE LOAD - JP HXLOADEXIT ; RETURN TO PROMPT -HXCHKSUM: - LD C,A ; BUILD THE CHECKSUM - LD A,E ; - SUB C ; THE CHECKSUM SHOULD ALWAYS .EQUAL ZERO WHEN CHECKED - LD E,A ; SAVE THE CHECKSUM BACK WHERE IT CAME FROM - LD A,C ; RETRIEVE THE BYTE AND GO BACK - RET ; BACK TO CALLER -HXLOADAGAIN: - CALL KIN ; CATCH THE TRAILING CARRIAGE RETURN - JP HXLOAD0 ; LOAD ANOTHER LINE OF DATA -HXLOADEXIT: - CALL KIN ; CATCH ANY STRAY TRAILING CHARACTERS - JP SERIALCMDLOOP ; RETURN TO PROMPT - - -;__MOVE__________________________________________________________________________________________________________________________ -; -; MOVE MEMORY, USER OPTION "M" -;________________________________________________________________________________________________________________________________ -; -MOVE: - LD C,#3 - ; START GETNM REPLACEMENT - ; GET SOURCE STARTING MEMORY LOCATION - INC HL ; SHOW EXAMINE READY - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - CALL LDHL ; LOAD IN HL REGS - PUSH HL ; PUSH MEMORY ADDRESS ON STACK - ; END GETNM REPLACEMENT - POP DE ; DEST - POP BC ; SOURCE END - POP HL ; SOURCE - PUSH HL ; - LD A,L ; - CPL ; - LD L,A ; - LD A,H ; - CPL ; - LD H,A ; - INC HL ; - ADD HL,BC ; - LD C,L ; - LD B,H ; - POP HL ; - CALL MOVE_LOOP ; - JP SERIALCMDLOOP ; EXIT MOVE COMMAND ROUTINE -MOVE_LOOP: - LD A,(HL) ; FETCH - LD (DE),A ; DEPOSIT - INC HL ; BUMP SOURCE - INC DE ; BUMP DEST - DEC BC ; DEC COUNT - LD A,C ; - OR B ; - JP NZ,MOVE_LOOP ; TIL COUNT=0 - RET ; - -;__FILL__________________________________________________________________________________________________________________________ -; -; FILL MEMORY, USER OPTION "M" -;________________________________________________________________________________________________________________________________ -; -FILL: - LD C,#3 ; - ; START GETNM REPLACEMENT - ; GET FILL STARTING MEMORY LOCATION - INC HL ; SHOW EXAMINE READY - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - ; GET FILL ENDING MEMORY LOCATION - PUSH HL ; - CALL LDHL ; LOAD IN HL REGS - LD D,H ; - LD E,L ; - POP HL ; - PUSH DE ; PUSH MEMORY ADDRESS ON STACK - INC HL ; - INC HL ; - INC HL ; - INC HL ; - INC HL ; PRINT SPACE SEPARATOR - ; GET TARGET STARTING MEMORY LOCATION - CALL HEXIN ; GET K B. AND MAKE HEX - LD C,A ; PUT FILL VALUE IN F SO IT IS SAVED FOR LATER - PUSH BC ; PUSH FILL VALUE BYTE ON STACK - ; END GETNM REPLACEMENT - POP BC ; BYTE - POP DE ; END - POP HL ; START - LD (HL),C ; -FILL_LOOP: - LD (HL),C ; - INC HL ; - LD A,E ; - SUB L ; - LD B,A ; - LD A,D ; - SUB H ; - OR B ; - JP NZ,FILL_LOOP ; - JP SERIALCMDLOOP ; - -;__GOCPM_________________________________________________________________________________________________________________________ -; -; BOOT CP/M FROM ROM DRIVE, USER OPTION "C" -;________________________________________________________________________________________________________________________________ -; -GOCPM: -;___________________________ -; REMOVE COMMENTS WHEN BURNED IN ROM -;___________________________ - -; LD A,000000000b ; RESET MPCL LATCH TO DEFAULT ROM -; OUT (MPCL),A ; -; LD HL,ROMSTART_CPM ; WHERE IN ROM CP/M IS STORED (FIRST BYTE) -; LD DE,RAMTARG_CPM ; WHERE IN RAM TO MOVE MONITOR TO (FIRST BYTE) -; LD BC,MOVSIZ_CPM ; NUMBER OF BYTES TO MOVE FROM ROM TO RAM -; LDIR ; PERFORM BLOCK COPY OF CP/M TO UPPER RAM PAGE -; LD A,010000000b ; RESET MPCL LATCH TO DEFAULT CP/M WITH 64K SETTING -; OUT (MPCL),A ; - - JP 0x0EA00 ; CP/M COLD BOOT ENTRY POINT - -; -;__INIT_UART_____________________________________________________________________________________________________________________ -; -; INITIALIZE UART -; PARAMS: SER_BAUD NEEDS TO BE SET TO BAUD RATE -; 1200: 96 = 1,843,200 / ( 16 X 1200 ) -; 2400: 48 = 1,843,200 / ( 16 X 2400 ) -; 4800: 24 = 1,843,200 / ( 16 X 4800 ) -; 9600: 12 = 1,843,200 / ( 16 X 9600 ) -; 19K2: 06 = 1,843,200 / ( 16 X 19,200 ) -; 38K4: 03 -; 57K6: 02 -; 115K2: 01 -; -;_________________________________________________________________________________________________________________________________ -; -INIT_UART: - LD A,#0x80 ; - OUT (UART3),A ; SET DLAB FLAG - LD A,(SER_BAUD) ; - OUT (UART0),A ; - LD A,#0 ; - OUT (UART1),A ; - LD A,#3 ; - OUT (UART3),A ; SET 8 BIT DATA, 1 STOPBIT - LD A,#3 ; set DTR & RTS - OUT (UART4),A ; - RET - - -; -;__FILL_MEM_______________________________________________________________________________________________________________________ -; -; FUNCTION : FILL MEMORY WITH A VALUE -; INPUT : HL = START ADDRESS BLOCK -; : BC = LENGTH OF BLOCK -; : A = VALUE TO FILL WITH -; USES : DE, BC -; OUTPUT : -; CALLS : -; TESTED : 13 FEB 2007 -;_________________________________________________________________________________________________________________________________ -; -FILL_MEM: - LD E,L ; - LD D,H ; - INC DE ; - LD (HL),A ; INITIALISE FIRST BYTE OF BLOCK WITH DATA BYTE IN A - DEC BC ; - LDIR ; FILL MEMORY - RET ; RETURN TO CALLER - -; -;__INITIALIZE_____________________________________________________________________________________________________________________ -; -; INITIALIZE SYSTEM -;_________________________________________________________________________________________________________________________________ -; -INITIALIZE: - LD A,#12 ; SPECIFY BAUD RATE 9600 BPS (9600,8,NONE,1) - LD (SER_BAUD),A ; - CALL INIT_UART ; INIT THE UART - RET ; -; - -;__MTERM_INIT________________________________________________________________________________________ -; -; SETUP 8255, MODE 0, PORT A=OUT, PORT B=IN, PORT C=OUT/OUT -; -;____________________________________________________________________________________________________ -MTERM_INIT: - LD A,#0x82 - OUT (PIOCONT),A - RET - -;__KB_GET____________________________________________________________________________________________ -; -; GET A SINGLE KEY AND DECODE -; -;____________________________________________________________________________________________________ -KB_GET: - PUSH HL ; STORE HL -KB_GET_LOOP: ; WAIT FOR KEY - CALL KB_SCAN ; SCAN KB ONCE - CP #0 ; NULL? - JR Z,KB_GET_LOOP ; LOOP WHILE NOT ZERO - LD D,A ; STORE A - LD A,#0x4F ; SCAN ALL COL LINES - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE -KB_CLEAR_LOOP: ; WAIT FOR KEY TO CLEAR - IN A,(PORTB) ; GET ROWS - CP #0 ; ANYTHING PRESSED? - JR NZ,KB_CLEAR_LOOP ; YES, EXIT - LD A,D ; RESTORE A - LD D,#0x00 ; - LD HL,#KB_DECODE ; POINT TO BEGINNING OF TABLE -KB_GET_LLOOP: - CP (HL) ; MATCH? - JR Z,KB_GET_DONE ; FOUND, DONE - INC HL - INC D ; D + 1 - JP NZ,KB_GET_LLOOP ; NOT FOUND, LOOP UNTIL EOT -KB_GET_DONE: - LD A,D ; RESULT INTO A - POP HL ; RESTORE HL - RET - - - -;__KB_SCAN____________________________________________________________________________________________ -; -; SCAN KEYBOARD MATRIX FOR AN INPUT -; -;____________________________________________________________________________________________________ -KB_SCAN: - - LD C,#0 - LD A,#0x41 ; SCAN COL ONE - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0x00 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,#0x0040 - LD A,#0x42 ; SCAN COL TWO - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,#0x0080 - LD A,#0x44 ; SCAN COL THREE - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0x00 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD C,#0x00C0 ; - LD A,#0x48 ; SCAN COL FOUR - OUT (PORTC),A ; SEND TO COLUMN LINES - CALL KB_SCAN_DELAY ; DELAY TO ALLOW LINES TO STABILIZE - IN A,(PORTB) ; GET ROWS - CP #0x00 ; ANYTHING PRESSED? - JR NZ,KB_SCAN_FOUND ; YES, EXIT - - LD A, #0x40 ; TURN OFF ALL COLUMNS - OUT (PORTC),A ; SEND TO COLUMN LINES - LD A, #0x00 ; RETURN NULL - RET ; EXIT - -KB_SCAN_FOUND: - AND #0x3F ; CLEAR TOP TWO BITS - OR C ; ADD IN ROW BITS - LD C,A ; STORE VALUE - LD A,#0x00 ; TURN OFF ALL COLUMNS - OUT (PORTC),A ; SEND TO COLUMN LINES - LD A,C ; RESTORE VALUE - RET - -PAUSE: -KB_SCAN_DELAY: - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - RET - - - -;__HEXDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;____________________________________________________________________________________________________ -HEXDISPLAY: - PUSH HL ; STORE HL - PUSH AF ; STORE AF - PUSH BC ; STORE BC - LD BC,#0007 - ADD HL,BC - LD B,#0x08 ; SET DIGIT COUNT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL PAUSE ; WAIT - LD A,#0x0F0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - OUT (PORTA),A ; OUTPUT TO PORT - LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PORTC),A ; OUTPUT TO PORT - CALL PAUSE ; WAIT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT -HEXDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - CALL DECODEDISPLAY ; DECODE DISPLAY - OUT (PORTA),A ; OUT TO PORTA - LD A,#0x00 ; SET WRITE STROBE - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; DELAY - LD A,#0x40 ; SET CONTROL PORT OFF - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; WAIT - DEC HL ; INC POINTER - DJNZ HEXDISPLAY_LP ; LOOP FOR NEXT DIGIT - POP BC ; RESTORE BC - POP AF ; RESTORE AF - POP HL ; RESTORE HL - RET - -;__DECODEDISPLAY_____________________________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;____________________________________________________________________________________________________ -DECODEDISPLAY: - PUSH BC ; STORE BC - PUSH HL ; STORE HL - LD HL,#SEGDECODE ; POINT HL TO DECODE TABLE - LD B,#0x00 ; RESET HIGH BYTE - LD C,A ; CHAR INTO LOW BYTE - ADD HL,BC ; SET TABLE POINTER - LD A,(HL) ; GET VALUE - POP HL ; RESTORE HL - POP BC ; RESTORE BC - RET - - -;__SEGDISPLAY________________________________________________________________________________________ -; -; DISPLAY CONTENTS OF DISPLAYBUF IN DECODED HEX BITS 0-3 ARE DISPLAYED DIG, BIT 7 IS DP -; -;____________________________________________________________________________________________________ -SEGDISPLAY: - PUSH AF ; STORE AF - PUSH BC ; STORE BC - LD BC,#0x0007 - ADD HL,BC - LD B,#0x08 ; SET DIGIT COUNT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT - CALL PAUSE ; WAIT - LD A,#0x0F0 ; SET CONTROL TO 1111 (DATA COMING, HEX DECODE,NO DECODE, NORMAL) - OUT (PORTA),A ; OUTPUT TO PORT - LD A,#0x80 ; STROBE WRITE PULSE WITH CONTROL=1 - OUT (PORTC),A ; OUTPUT TO PORT - CALL PAUSE ; WAIT - LD A,#0x40 ; SET CONTROL PORT 7218 TO OFF - OUT (PORTC),A ; OUTPUT -SEGDISPLAY_LP: - LD A,(HL) ; GET DISPLAY DIGIT - OUT (PORTA),A ; OUT TO PORTA - LD A,#0x00 ; SET WRITE STROBE - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; DELAY - LD A,#0x40 ; SET CONTROL PORT OFF - OUT (PORTC),A ; OUT TO PORTC - CALL PAUSE ; WAIT - DEC HL ; INC POINTER - DJNZ SEGDISPLAY_LP ; LOOP FOR NEXT DIGIT - POP BC ; RESTORE BC - POP AF ; RESTORE AF - RET - -; -;__WORK_AREA___________________________________________________________________________________________________________________ -; -; RESERVED RAM FOR MONITOR WORKING AREA -;_____________________________________________________________________________________________________________________________ -; -SER_BAUD: .DS 1 ; SPECIFY DESIRED UART COM RATE IN BPS -KEYBUF: .ascii " " - .ascii " " -DISPLAYBUF: .DB 00,00,00,00,00,00,00,00 -IDEDEVICE: .DB 1 ; IDE DRIVE SELECT FLAG (00H=PRIAMRY, 10H = SECONDARY) -IDE_SECTOR_BUFFER: - .DS 0x00200 - - - - -; -;__TEXT_STRINGS_________________________________________________________________________________________________________________ -; -; SYSTEM TEXT STRINGS -;_____________________________________________________________________________________________________________________________ -; -TCRLF: - .DB CR,LF,ENDT - -PROMPT: - .DB CR,LF - .ascii ">" - .DB ENDT - -TXT_READY: - .DB CR,LF - .ascii " NN NN 8888 VV VV EEEEEEEEEE MM MM" - .DB CR,LF - .ascii " NNNN NN 88 88 VV VV EE MMMM MMMM" - .DB CR,LF - .ascii " NN NN NN 88 88 VV VV EE MM MM MM MM" - .DB CR,LF - .ascii " NN NNNN 88 88 VV VV EE MM MM MM" - .DB CR,LF - .ascii " NN NN 8888 VV VV EEEEEEE MM MM" - .DB CR,LF - .ascii " NN NN 88 88 VV VV EE MM MM" - .DB CR,LF - .ascii " NN NN 88 88 VV VV EE MM MM" - .DB CR,LF - .ascii " NN NN 88 88 VVV EE MM MM" - .DB CR,LF - .ascii " NN NN 8888 V EEEEEEEEEE MM MM S B C" - .DB CR,LF - .DB CR,LF - .ascii " ****************************************************************************" - .DB CR,LF - .ascii "MONITOR READY " - .DB CR,LF,ENDT - -TXT_COMMAND: - .DB CR,LF - .ascii "UNKNOWN COMMAND." - .DB ENDT - -TXT_CKSUMERR: - .DB CR,LF - .ascii "CHECKSUM ERROR." - .DB ENDT -CPUUP: - .DB 0x084,0x0EE,0x0BB,0x080,0x0BB,0x0EE,0x0CB,0x084 -ADDR: - .DB 0x00,0x00,0x00,0x00,0x08C,0x0BD,0x0BD,0x0FE - - -PORT: - .DB 0x00,0x00,0x80,0x80,0x094,0x08C,0x09D,0x0EE -SEC: - .DB 0x80,0x80,0x80,0x80,0x80,0x0CB,0x0CF,0x0D7 - - -;_KB DECODE TABLE__________________________________________________________________________________________________________ -; -; -KB_DECODE: -; 0 1 2 3 4 5 6 7 8 9 A B C D E F - .DB 0x41,0x02,0x42,0x82,0x04,0x44,0x84,0x08,0x48,0x88,0x10,0x50,0x90,0x20,0x60,0x0A0 -; FW BK CL EN DP EX GO BO - .DB 0x01,0x81,0x0C1,0x0C2,0x0C4,0x0C8,0x0D0,0x0E0 -; -; F-KEYS, -; FW = FORWARD -; BK = BACKWARD -; CL = CLEAR -; EN = ENTER -; DP = DEPOSIT (INTO MEM) -; EX = EXAMINE (MEM) -; GO = GO -; BO = BOOT -;_________________________________________________________________________________________________________________________ -;_HEX 7_SEG_DECODE_TABLE__________________________________________________________________________________________________ -; -; 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, ,- -; AND WITH 7FH TO TURN ON DP -;_________________________________________________________________________________________________________________________ -SEGDECODE: - .DB 0x0FB,0x0B0,0x0ED,0x0F5,0x0B6,0x0D7,0x0DF,0x0F0,0x0FF,0x0F7,0x0FE,0x09F,0x0CB,0x0BD,0x0CF,0x0CE,0x080,0x084,0x00,0x0EE,0x09D - -;********************* END OF PROGRAM *********************************** - -;dwg; .ORG 08FFFh -;dwg; .DB 000h -;dwg; .END - -_dbgmon_end:: - .area _CODE - .area _CABS diff --git a/branches/s100/cpurom/src/dwgh2b.c b/branches/s100/cpurom/src/dwgh2b.c deleted file mode 100644 index cc70ad9a..00000000 --- a/branches/s100/cpurom/src/dwgh2b.c +++ /dev/null @@ -1,128 +0,0 @@ -// --------------------------------------------------- -// hex2bin.c 21-May-11 Running on Mac OS X 10.6.6 -// S/n 2011-1042-654321 Written by Douglas W. Goodall -// Copyright(c)2011 Douglas W. Goodall, United States. -// --------------------------------------------------- -// This file is part of Vintage Modern Assembler Plus Tools. -// -// VMAPT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// VMAPT is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with VMAPT. If not, see . -// - -#include -#include -#include - -#define DATA_RECORD 0x00 -#define EOF_RECORD 0x01 - -int main(int argc,char **argv) -{ - char g_szBuffer2[128]; - char szByteBuffer[2+1]; - char *p; - int i; - int iTemp; - - char cColon; - - char szLength[2+1]; - int iLength; - - char szAddress[4+1]; - unsigned int uiAddress; - - char szRecordType[2+1]; - unsigned char ucRecordType; - - char szData[80]; - unsigned char ucBinBuffer[32+1]; - - char szChecksum[2+1]; - unsigned char ucChecksum; - - unsigned int uiLastByte = 0; - - if(1 == argc) { - printf("usage - hex2bin \n"); - exit(EXIT_FAILURE); - } - - char szBinFile[255]; - char szHexFile[255]; - - strcpy(szHexFile,argv[1]); - strcpy(szBinFile,argv[1]); - - strcat(szBinFile,".bin"); - strcat(szHexFile,".hex"); - - unsigned char memory[0xfff0]; - memset(memory,0,sizeof(memory)); - - FILE * fhex = fopen(szHexFile,"r"); - if(NULL == fhex) { - printf("Sorry, cannot open %s for input\n",szHexFile); - exit(EXIT_FAILURE); - } - p = fgets(g_szBuffer2,sizeof(g_szBuffer2),fhex); - while(NULL != p) { - g_szBuffer2[strlen(g_szBuffer2)-1] = 0; - cColon = g_szBuffer2[0]; - - memset(szLength,0,sizeof(szLength)); - memcpy(szLength,&g_szBuffer2[1],2); - sscanf(szLength,"%02X",&iLength); - - memset(szAddress,0,sizeof(szAddress)); - memcpy(szAddress,&g_szBuffer2[3],4); - sscanf(szAddress,"%04X",&uiAddress); - - memset(szRecordType,0,sizeof(szRecordType)); - memcpy(szRecordType,&g_szBuffer2[7],2); - - sscanf(szRecordType,"%02X",&iTemp); - ucRecordType = (unsigned char)iTemp; - - if(0 == ucRecordType) { - memset(szData,0,sizeof(szData)); - memcpy(szData,&g_szBuffer2[9],iLength*2); - for(i=0;i -#include -#include - -#include "portab.h" -#ifndef __GNUC__ -#include "cpmbdos.h" -#include "cprintf.h" -#endif - -/* - * 1MB = 1,048,576 bytes - * 32MB = 1,048,576 * 32 = 33,554,432 - * - * physical sector is 512 bytes - * physical track is 256 sectors = 131,072 - * physical drive is 33,554,432 - * physical tracks are 33,554,432 / 131,072 = 256 - * physical tracks per physical drive are 256 - * - * logical sector is 128 bytes - * logical track is 256 sectors (aka ) - * logical drive is 8192KB (aka 8192KB/32KB = 256 logical tracks) - * - * - * 8,388,608 bytes is a logical drive - * 131,072 bytes is a physical track - * 8,388,608 / 131,072 = 64 physical tracks per logical drive - * - * One byte (0-255) will just hold the number of physical tracks needing - * to be shared amoung up to four logical drives. - * - * physical track 0 - partition sector and second-stage loader if needed - * physical tracks 1 - 64 = 8.0MB partition ( 64 * 131,072 = 8,388,608 ) - * physical tracks 65 - 128 = 8.0MB partition ( 64 * 131,072 = 8,388,608 ) - * physical tracks 129 - 192 = 8.0MB partition ( 64 * 131,072 = 8,388,608 ) - * physical tracks 193 - 255 = 7.9MB partition ( 63 * 131,072 = 8,257,536 ) - * - */ - -#define MAX_PARTS 4 -#define TRKS_PER_PHY_DRV 256 -#define TRKS_PER_LOG_DRV 64 /* 256 sectors * 512 = 128k */ - -#define SAFESTRING 80 /* make large enough to avoid accidental overrun */ - -#define U8 unsigned char - -struct PART_TABLE { /* in-memory instance of partition table */ - U8 start; /* starting track of a partition */ - U8 end; /* ending track of a partition */ -} pt[MAX_PARTS] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; - -U8 bRunning; /* scratchpad used used by the main loop */ -U8 end; /* scratchpad used to hold ending track of a part */ -U8 Index; /* scratchpad used as index for for loops */ -U8 NumParts; /* scratchpad to hold the current number of parts */ -U8 LastEnd; /* scratchpad to hold the last track allocated */ -U8 NewEnd; /* scratchpad to hold the proposed ending track */ -U8 NewMax; /* scratchpad to hold the proposed max part size */ -U8 NewSize; /* scratchpad to hold the decided new part size */ -U8 NewStart; /* scratchpad to hold the decided starting track */ -U8 start; /* scratchpad to hold the starting track of a part */ -U8 Avail; /* scratchpad to hold the remaining avialable tracks */ - -char szChoice[SAFESTRING]; /* string used to receive keystrokes */ -char szTemp[SAFESTRING]; /* string used for general purposes */ - -/* THESE ARE USED BY THE LIBRARY ROUTINES */ -#ifndef __GNUC__ -char getchar(void) -{ - struct BDOSCALL cread = { C_READ, { (unsigned int)0 } }; - return cpmbdos(&cread); -} -void outchar(char c) -{ - struct BDOSCALL cwrite = { C_WRITE, { (unsigned int)c } }; - cpmbdos(&cwrite); -} -#endif - -void display_menu(void) -{ - if(NumParts < MAX_PARTS) { - if(0 < Avail) { - printf("a - add partition #%d\n",NumParts+1); - } - } - if(0 < NumParts) { - printf("d - delete partition #%d\n",NumParts); - } - if(1 < NumParts) { - printf("D - delete all partitions, 1 - %d\n",NumParts); - } - if(0 == NumParts) { - printf("A - create all 8MB partitions\n"); - } - printf("q - quit fdisk\n\n"); -} - -char query(char *str) -{ - printf("%s",str); - gets(szTemp); - if('Y' == szTemp[0]) { - return TRUE; - } else { - return FALSE; - } -} - -void delete(void) -{ - if(0 < NumParts) { - if(TRUE == query("Delete partition(Y/n)?")) { - pt[NumParts-1].start = 0; - pt[NumParts-1].end = 0; - } - } -} - -void deleteall(void) -{ - if(0 < NumParts) { - if(TRUE == query("Delete all partitions(Y/n)?")) { - for(Index=0;Index. -*********************************************************************** - When invoked as 'hex2bin' read a sequence of Intel hex files - and create an overlaid binary file. - - When invoked as 'bin2hex' read a binary file and create an - Intel hex file. - - All command line numeric constants may be specified in any - radix. -*********************************************************************** - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - in the file COPYING in the distribution directory along with this - program. If not, see . - -**********************************************************************/ -#include -#include -#include -#include "jrctypes.h" - -#define true 1 -#define false 0 -#define SEG_MASK 0x00FFFFu -#define LBA_MASK 0x00FF0000ul -#define MAX_MASK (LBA_MASK|SEG_MASK) -#define ONE_MEG 0x100000ul - -dword upper_lba = 0; /* upper address */ -dword address_mask = SEG_MASK; /* address mask */ -byte pad = 0xFF; -byte *buffer; -dword rom_size = 0; -dword overwrite; /* count of possible overwrites */ -byte h2b, verbose; -char *outfilename = NULL; -char *binfilename = NULL; -dword source_address, source_limit; -dword dest_address, dest_limit; -FILE *infile; -FILE *outfile; -byte checksum; -char line[1024]; -char *lp; -long int lineno; - - - -dword convert_constant(char *str) -{ - char *final; - dword value = strtoul(str, &final, 0); - - if (*final == 'k' || *final == 'K') value *= 1024ul; - else if (*final == 'M' || *final == 'm') value *= ONE_MEG; - - return value; -} - -void error(byte level, char *msg) -{ - printf("%s(%d): %s\n", - level>1 ? "Error" : "Warning", (int)level, msg); - if (level>1) exit(level); - else if (level==0) printf("line %ld %s", lineno, line); -} - - -int getnibble(void) -{ - char ch; - - if (lp) { - ch = *lp++; - if (ch>='0' && ch<='9') ch -= '0'; - else if (ch>='A' && ch<='F') ch -= 'A'-10; - else if (ch>='a' && ch<='f') ch -= 'a'-10; - else { - error(0,"Illegal hex digit"); - ch = -1; - } - } - else error(0,"Line is too short"); - return (int)ch; -} - -int getbyte(void) -{ - int b = getnibble(); - b <<= 4; - b += getnibble(); - checksum += b; - return b; -} - -int getword(void) -{ - int w = getbyte(); - w <<= 8; - w += getbyte(); - return w; -} - -dword getdword(void) -{ - dword d = getword(); - d <<= 16; - d += getword(); - return d; -} - - -void putbyte(dword address, byte data) -{ - if (address < source_address || address > source_limit) return; - address -= source_address; - address += dest_address; - if (address > dest_limit) return; - if (address >= rom_size) { - printf("Line %ld ",lineno); error(2,"Data beyond end of ROM"); - } - if (buffer[address] != pad) { - overwrite++; - if (verbose || overwrite<=100) printf("Warning(1): Overwrite at ROM address 0x%lX\n", address); - } - buffer[address] = data; -} - - -void usage(void) -{ - printf("hex2bin.c (bin2hex) -- " __DATE__ " " __TIME__ ".\n" - "Copyright (c) 2011 John R Coffman. All rights reserved.\n" - "Distributed under the GNU General Public License, a copy of which\n" - "is contained in the file COPYING in the distribution directory.\n\n"); - if (h2b) printf( - "Usage:\n" - " hex2bin [ ]+\n\n" - " Options:\n" - " -o \n" - " -p \n" - " -R default 64K\n" - " -v []\n" - " Flags:\n" - " -d \n" - " -D \n" - " -s \n" - " -S \n" - ); - else printf( - "Usage:\n" - " bin2hex [ ]+\n\n" - " Options:\n" - " -o \n" - " -p \n" - " -R default 1024K\n" - " -v []\n" - " Flags:\n" - " -d \n" - " -D \n" - " -s \n" - " -S \n" - ); -} - - -void hout_byte(byte data) -{ - checksum -= data; - fprintf(outfile, "%02X", (int)data); -} -void hout_word(word data) -{ - hout_byte(data>>8); - hout_byte(data); -} -void begin_record(byte length) -{ - checksum = 0; - fputc(':', outfile); - hout_byte(length); -} -void end_record(void) -{ - hout_byte(checksum); - fputc('\n', outfile); -} - -void write_lba(dword address) -{ - if (verbose==5) printf("Address: %06lX\n", address); - - if ((address & LBA_MASK) != upper_lba) { - upper_lba = address & LBA_MASK; - begin_record(2); - hout_word(0); - if (rom_size > ONE_MEG) { - hout_byte(4); /* linear address */ - hout_word(upper_lba>>16); - } - else { /* handle ROMs 1meg and smaller */ - hout_byte(2); /* segment address */ - hout_word(upper_lba>>4); - } - end_record(); - } -} - -void write_data(word nbytes, byte *buf, dword address) -{ - /* compress from the high end */ - while (nbytes && buf[nbytes-1]==pad) --nbytes; - /* compress from the low end */ - while (nbytes && *buf==pad) { - ++buf; - ++address; - --nbytes; - } - if (nbytes) { - write_lba(address); - begin_record(nbytes); - hout_word(address & 0xFFFFu); - hout_byte(0); /* data record */ - while(nbytes--) hout_byte(*buf++); - end_record(); - } -} - -#define min(a,b) ((a)<(b)?(a):(b)) -#define NREC 16 - -void write_hex_file(FILE *outfile) -{ - dword nbytes; - dword vaddr; - dword n; - byte *buf; - - buf = buffer; - vaddr = 0; - nbytes = rom_size; - n = min(nbytes, NREC); - do { - write_data(n, buf, vaddr); - buf += n; - vaddr += n; - nbytes -= n; - n = min(nbytes, NREC); - } while (n); -/* write the end-of-file record */ - fprintf(outfile,":00000001FF\n"); -} - - -void scan_bin_file(char *filename) -{ - dword length; - dword nbytes; - int data; - dword inaddr; - - infile = fopen(filename, "rb"); - if (!infile) { - strcpy(line,"Cannot find file: "); - error(5, strcat(line, filename)); - } - - fseek(infile,0L,SEEK_END); - length = ftell(infile); - -// length = filelength(fileno(infile)); - - nbytes = 0; - inaddr = dest_address; - if (source_address < length) { - fseek(infile, source_address, SEEK_SET); - while (inaddr=3) printf("%s", lp-1); - checksum = 0; - ldata = getbyte(); - laddr = getword(); - rectype = getbyte(); - switch (rectype) { - case 0: /* data record */ - index = 0; - while (ldata--) { - data = getbyte(); - putbyte(upper_lba + ((laddr + index)&address_mask), data); - index++; - } - break; - case 1: /* end of file record */ - EndOfFile = 1; - break; - case 2: /* segment address */ - address_mask = SEG_MASK; - value = getword(); - upper_lba = value<<4; /* start of segment */ - ldata -= 2; - break; - case 4: /* linear upper address */ - address_mask = MAX_MASK; - value = getword(); - upper_lba = value<<16; /* full 32-bit address range */ - ldata -= 2; - break; - case 3: /* start CS:IP */ - case 5: /* linear start address */ - value = getdword(); - ldata -= 4; - default: - error(0,"Unknown record type:"); - } - getbyte(); /* get final checksum */ - if (checksum) { - error(0,"Checksum failure"); - } - } while (lp && !EndOfFile); - fclose(infile); -} - - -void global_options(int argc, char *argv[]) -{ - int iarg; - char *cp; - char *tp; - char ch; - - h2b = false; - rom_size = ONE_MEG; /* bin2hex default value */ -/* decide which conversion to do */ - if (strstr(argv[0],"hex2bin") -#ifdef MSDOS - || strstr(argv[0],"HEX2BIN") -#endif - ) { - h2b = true; - rom_size = 64 * 1024ul; /* default value */ - } /* assume 'bin2hex' otherwise */ - - if (argc<2) { usage(); exit(0); } - -/* scan the global command line options */ - for (iarg = 0; iarg MAX_MASK+1) error(5, "ROM size too big"); - if (rom_size < 256) error(5, "ROM size too small"); - *cp = *tp = 0; - break; - case 'v': /* print verbose statistics */ - verbose++; - if (!*tp) tp = argv[++iarg]; - if (*tp>='1' && *tp<='5' && tp[1]==0) verbose += (*tp - '1'); - else tp = cp; - *cp = *tp = 0; - break; - case 'Y': { - int i; - for (i=0; i -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index2) { - printf(" "); - strcpy(szTemp,argv[2]); - for(index=0;index3) { - printf(" "); - strcpy(szTemp,argv[3]); - for(index=0;index4) { - printf(" "); - strcpy(szTemp,argv[4]); - for(index=0;index -#include -#include - -int main(int argc,char **argv) -{ - char szTemp[128]; - int index; - - strcpy(szTemp,argv[1]); - for(index=0;index. -// - -#include -#include -#include - -#define DATA_RECORD 0x00 -#define EOF_RECORD 0x01 - -int main(int argc,char **argv) -{ - FILE * fcom, * fhex; - char g_szBuffer2[128]; - char szByteBuffer[2+1]; - char *p; - int iTemp; - - char cColon; - - char szLength[2+1]; - int iLength; - - char szAddress[4+1]; - unsigned int uiAddress; - - char szRecordType[2+1]; - unsigned char ucRecordType; - - char szData[80]; - unsigned char ucBinBuffer[32+1]; - - char szChecksum[2+1]; - unsigned char ucChecksum; - - unsigned int uiLastByte = 0; - - char szComFile[255]; - char szHexFile[255]; - int i; - - unsigned char memory[0xfff0]; - - if(1 == argc) { - printf("usage - load \n"); - exit(EXIT_FAILURE); - } - - strcpy(szHexFile,argv[1]); - strcpy(szComFile,argv[1]); - - strcat(szComFile,".com"); - strcat(szHexFile,".hex"); - - memset(memory,0,sizeof(memory)); - - fhex = fopen(szHexFile,"r"); - if(NULL == fhex) { - printf("Sorry, cannot open %s for input\n",szHexFile); - exit(EXIT_FAILURE); - } - p = fgets(g_szBuffer2,sizeof(g_szBuffer2),fhex); - while(NULL != p) { - g_szBuffer2[strlen(g_szBuffer2)-1] = 0; - cColon = g_szBuffer2[0]; - - memset(szLength,0,sizeof(szLength)); - memcpy(szLength,&g_szBuffer2[1],2); - sscanf(szLength,"%02X",&iLength); - - memset(szAddress,0,sizeof(szAddress)); - memcpy(szAddress,&g_szBuffer2[3],4); - sscanf(szAddress,"%04X",&uiAddress); - - memset(szRecordType,0,sizeof(szRecordType)); - memcpy(szRecordType,&g_szBuffer2[7],2); - - sscanf(szRecordType,"%02X",&iTemp); - ucRecordType = (unsigned char)iTemp; - - if(0 == ucRecordType) { - memset(szData,0,sizeof(szData)); - memcpy(szData,&g_szBuffer2[9],iLength*2); - for(i=0;i -#include -#include -#include -#include -#include -#include - - -void usage(void) -{ - printf("N8VEM sysgen v1.0\n"); - printf("usage:\n"); - printf("sysgen -C xx filename - Create filename xx KB in size\n"); - printf("sysgen -i importfile imagefile - Import the contents of importfile to Imagefile\n"); - printf("sysgen -e exportfile imagefile - Export system track to exportfile\n"); - exit(1); -} - -int main(int argc, char *argv[]) - -{ - - int i, size, fd1, fd2, nwritten, nread; - int ntotal = 0; - char buffer [10240]; - - if (argc != 4) - { - printf("\nIncorrect number of parameters\n\n"); - usage(); - } - - - if (strcmp(argv[1], "-C") == 0) /* Create command */ - { - for (i=0; i<1024; i++) buffer[i] = 229; - - fd1 = creat(argv[3],O_WRONLY|S_IRWXU); - - if ( fd1 == -1) - { - printf("error creating file %s\n",argv[3]); - exit(1); - } - for (i=0; i< (atoi(argv[2])) ; i++) - { - nwritten = write (fd1, &buffer, 1024); - if (nwritten == -1) - { - printf ("error writing file %s\n",argv[3]); - exit(1); - } - ntotal+=nwritten; - } - printf("wrote %d bytes to file %s\n",ntotal,argv[3]); - close(fd1); - exit(0); - } - - if (strcmp(argv[1], "-i") == 0) /* Import command */ - { - - fd1 = open (argv[2],O_RDONLY); - if (fd1 == -1) - { - printf("error opening input file %s\n",argv[2]); - exit(1); - } - fd2 = open (argv[3], O_WRONLY); - if ( fd2 == -1) - { - printf("error opening output file %s\n",argv[3]); - exit(1); - } - - nread = read( fd1, &buffer, 10240); - - if (nread == -1) - { - printf ("error reading from input file %s\n", argv[2]); - exit(1); - } - nwritten = write ( fd2, &buffer, nread); - if (nwritten == -1) - { - printf ("error writing to output file %s\n", argv[3]); - exit(1); - } - printf("wrote %d bytes to file %s\n",nwritten,argv[3]); - - close(fd1); - close(fd2); - - exit(0); - } - - if (strcmp(argv[1], "-e") == 0) /* Export command */ - { - - fd1 = creat(argv[2],O_WRONLY|S_IRWXU); /* export file */ - - if (fd1 == -1) - { - printf("error creating export file %s\n",argv[2]); - exit(1); - } - - fd2 = open(argv[3],O_RDONLY); /* romimage file */ - if (fd2 == -1) - { - printf("error opening romimage file %s\n",argv[3]); - exit(1); - } - nread = read( fd2, &buffer, 10240); - if (nread == -1) - { - printf ("error reading from romimage file %s\n",argv[3]); - exit(1); - } - nwritten = write( fd1, &buffer, nread); - if (nwritten == -1) - { - printf ("error writing to outputfile %s\n",argv[2]); - exit(1); - } - printf("wrote %d bytes to file %s\n",nwritten,argv[2]); - - close(fd1); - close(fd2); - - exit(0); - } - - usage(); - - return EXIT_SUCCESS; -} - - diff --git a/branches/s100/cpurom/tmp/stuff/baseline.arf b/branches/s100/cpurom/tmp/stuff/baseline.arf deleted file mode 100644 index e78d4aa5..00000000 --- a/branches/s100/cpurom/tmp/stuff/baseline.arf +++ /dev/null @@ -1,15 +0,0 @@ --mjx --i baseline.ihx --k /Developer/sdcc/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0xD000 --b _BDOSB01 = 0xD800 --b _CBIOS = 0xE600 --b _DBGMON = 0x8000 -obj/crt0.rel -obj/baseline.rel -obj/dbgmon.rel -obj/ccpb03.rel -obj/bdosb01.rel -obj/cbios.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/baseline.lk b/branches/s100/cpurom/tmp/stuff/baseline.lk deleted file mode 100644 index e78d4aa5..00000000 --- a/branches/s100/cpurom/tmp/stuff/baseline.lk +++ /dev/null @@ -1,15 +0,0 @@ --mjx --i baseline.ihx --k /Developer/sdcc/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0xD000 --b _BDOSB01 = 0xD800 --b _CBIOS = 0xE600 --b _DBGMON = 0x8000 -obj/crt0.rel -obj/baseline.rel -obj/dbgmon.rel -obj/ccpb03.rel -obj/bdosb01.rel -obj/cbios.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/baseline.lnk b/branches/s100/cpurom/tmp/stuff/baseline.lnk deleted file mode 100644 index e78d4aa5..00000000 --- a/branches/s100/cpurom/tmp/stuff/baseline.lnk +++ /dev/null @@ -1,15 +0,0 @@ --mjx --i baseline.ihx --k /Developer/sdcc/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0xD000 --b _BDOSB01 = 0xD800 --b _CBIOS = 0xE600 --b _DBGMON = 0x8000 -obj/crt0.rel -obj/baseline.rel -obj/dbgmon.rel -obj/ccpb03.rel -obj/bdosb01.rel -obj/cbios.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/n8.arf b/branches/s100/cpurom/tmp/stuff/n8.arf deleted file mode 100644 index e280f65a..00000000 --- a/branches/s100/cpurom/tmp/stuff/n8.arf +++ /dev/null @@ -1,13 +0,0 @@ --mjx --i n8.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0x0900 --b _BDOSB01 = 0x1100 --b _CBIOS = 0x1f00 -obj/loadern8.rel -obj/dbgmon.rel -obj/ccpb03.rel -obj/bdosb01.rel -obj/cbiosn8.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/n8.lk b/branches/s100/cpurom/tmp/stuff/n8.lk deleted file mode 100644 index e280f65a..00000000 --- a/branches/s100/cpurom/tmp/stuff/n8.lk +++ /dev/null @@ -1,13 +0,0 @@ --mjx --i n8.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0x0900 --b _BDOSB01 = 0x1100 --b _CBIOS = 0x1f00 -obj/loadern8.rel -obj/dbgmon.rel -obj/ccpb03.rel -obj/bdosb01.rel -obj/cbiosn8.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/n8.lnk b/branches/s100/cpurom/tmp/stuff/n8.lnk deleted file mode 100644 index e280f65a..00000000 --- a/branches/s100/cpurom/tmp/stuff/n8.lnk +++ /dev/null @@ -1,13 +0,0 @@ --mjx --i n8.ihx --k /usr/local/share/sdcc/lib/z80 --l z80 --b _CCPB03 = 0x0900 --b _BDOSB01 = 0x1100 --b _CBIOS = 0x1f00 -obj/loadern8.rel -obj/dbgmon.rel -obj/ccpb03.rel -obj/bdosb01.rel -obj/cbiosn8.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/scsi2ide.arf b/branches/s100/cpurom/tmp/stuff/scsi2ide.arf deleted file mode 100644 index 8ddee2c4..00000000 --- a/branches/s100/cpurom/tmp/stuff/scsi2ide.arf +++ /dev/null @@ -1,9 +0,0 @@ --mjx --i scsi2ide.ihx --k /Developer/sdcc/share/sdcc/lib/z80 --l z80 --b _DBGMON = 0x8000 -obj/crt0.rel -obj/scsi2ide.rel -obj/dbgmon.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/scsi2ide.lk b/branches/s100/cpurom/tmp/stuff/scsi2ide.lk deleted file mode 100644 index 8ddee2c4..00000000 --- a/branches/s100/cpurom/tmp/stuff/scsi2ide.lk +++ /dev/null @@ -1,9 +0,0 @@ --mjx --i scsi2ide.ihx --k /Developer/sdcc/share/sdcc/lib/z80 --l z80 --b _DBGMON = 0x8000 -obj/crt0.rel -obj/scsi2ide.rel -obj/dbgmon.rel --e diff --git a/branches/s100/cpurom/tmp/stuff/scsi2ide.lnk b/branches/s100/cpurom/tmp/stuff/scsi2ide.lnk deleted file mode 100644 index 8ddee2c4..00000000 --- a/branches/s100/cpurom/tmp/stuff/scsi2ide.lnk +++ /dev/null @@ -1,9 +0,0 @@ --mjx --i scsi2ide.ihx --k /Developer/sdcc/share/sdcc/lib/z80 --l z80 --b _DBGMON = 0x8000 -obj/crt0.rel -obj/scsi2ide.rel -obj/dbgmon.rel --e