Knowledge Base (2003)

Sprinter Computer http://sprinter.nedopc.org

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Knowledge Base (2003)

Post by Shaos »

It's taken from my local archive - in 2003 it was copied from petersplus.com web-site (creators of computer Sprinter).

How-to articles
Q10001. How to parse the command line in my programm?

Summary

This article contain example for getting command line.

More information

Code: Select all

	ORG	8100h-512
;EXE-file header:
	dw	5845h	  ; EXE Signature
	db	45h	  ; Reserved (EXE type)
	db	00h	  ; Version of EXE file
	dd	00000200h ; Code offset
	dw	0000h	  ; Primary loader size or 0 (no primary loader)
	dd	00000000h ; Reserved
	dw	0000h	  ; Reserved
	dw	START	  ; Loading address
	dw	START	  ; Starting address (register PC)
	dw	0BFFFh	  ; Stack address (register SP)
	ds	490	  ; Reserved 
 
;code of program
 
START	PUSH	IX	;IX pointer to Command line parameters
	POP	HL	;ld hl,ix
	INC	HL	;skip size of Command line
			;Now, HL pointer to first simbol of parameters
			;If you typed "TEST.EXE Hello", then HL pointer to " Hello"
			;with first space.
	LD	C,5Ch	;system call number (PCHARS)
	RST	10h	;call kernel
 
;return from your program
	LD      C,41h   ;system call number (EXIT)
	RST     10h     ;call kernel
	RET
24 April 2002.
PETERS PLUS LTD.
Q10002. How to access the modem from Sprinter computer?

Summary

This article describe ISA-8 interaction.

More information

If you want to interaction with ISA devices, you have to make following steps:
1) send 10h value to port 1FFDh(system port);
2) send control byte to port 0E2h(third memory window port);
control byte (corrected in Jan 2021):

Code: Select all

;D7...should be 1
;D6...should be 1
;D5...should be 0
;D4...should be 1
;D3...should be 0
;D2...specify access mode (0 - ISA memory, 1 - ISA ports)
;D1...specify index of ISA slot (0 - ISA#1, 1 - ISA#2)
;D0...should be 0
The read/write signals are forming from read/write signals memory range 0C000h-0FFFFh.

And the address lines A13...A0 has taken from processor data-BUS. The other ISA-signals such as RESET, AEN, A19...A14 can be set in port 9FBDh. And default value is 00h.
port 9FBDh:

Code: Select all

D7...RESET
D6...AEN
D5...A19
D4...A18
D3...A17
D2...A16
D1...A15
D0...A14

Code: Select all

ISA_DIR      EQU 9FBDh
SC_PORT      EQU 1FFDh
PAGE3        EQU 0E2h

SAVE_PAGE    DB 0           ;variable for previous status of third memory port

RESET_ISA:                  ; reset ISA device
        LD C, ISA_DIR
        LD A,0C0h
        OUT (C),A
	CALL Pause_10ms
        LD A,0
        OUT (C),A
        RET

Pause_10ms:
        LD HL,10000
Loop:
        DEC HL
        LD A,H
        XOR L
        JR NZ,Loop
        RET

OPEN_ISA_PORTS:             ; open access to ISA
        LD BC,SC_PORT
        LD A,11h ; <<<<<<<<<< corrected in Jan 2021
        OUT (C),A
        IN A,(PAGE3)        ; read value from memory port
        LD (SAVE_PAGE),A    ; save previous status of memory port
        LD A,0D4h           ; control byte for (ports of the 1st ISA slot)
        OUT (PAGE3), A      ; opening ISA port address space
        LD C,ISA_DIR
        LD A,0              ; high ISA addresses RESET and AEN signals.
        OUT (C),A
        RET

CLOSE_ISA_PORTS:            ; close access to ISA
        LD A,(SAVE_PAGE)
        OUT (PAGE3),A       ; restore value of memory port
        LD BC,SC_PORT
        LD A,1 ; <<<<<<<<<< corrected in Jan 2021
        OUT (C),A           ;
        RET

WRITE_ISA_PORT:
        LD HL,ADRESS_PORT+0C000h     ; ISA port address + 0C000h offset 3
memory page
        LD A,DATA_OUT                ; data for writing
        LD (HL),A                    ; write data to port which pointered HL
        RET

READ_ISA_PORT:
        LD HL, ADRESS_PORT+0C000h    ; ISA port address + 0C000h offset 3
memory page
        LD A,(HL)                    ; read data from port which pointered HL
        RET
When you work with ISA, the access to third memory page are disabled. If you want to address ISA-memory more than 3FFFh, you should specify high bits in port 9FBDh.

27 April 2002
PETERS PLUS LTD.
Q10008. How to make Sprinter's EXE program?

Summary

This article contain simple example of Sprinter's EXE program.

More information

You can use any assemblers, which have Z80 support. You have to add Sprinter's EXE-header only.

Code: Select all

        ORG     8100h-512
;EXE-file header:
        dw 5845h     ; EXE Signature
        db 45h       ; Reserved (EXE type)
        db 00h       ; Version of EXE file
        dd 00000200h ; Code offset
        dw 0000h     ; Primary loader size or 0 (no primary loader)
        dd 00000000h ; Reserved
        dw 0000h     ; Reserved
        dw START     ; Loading address
        dw START     ; Starting address (register PC)
        dw 0BFFFh    ; Stack address (register SP)
        ds 490       ; Reserved 

;code of program

START

;your program here

;return from your program
        LD BC,0041h  ;exit with 0 error code
        RST 10h      ;system call
        RET
Also, we recommend to you use as STACK address value between 8000h-0BFFFh. It will care you to avoid mistakes with STACK. The DSS and BIOS functions can opened another memory pages in third memory window 0C000h-0FFFFh.

30 May 2002.
PETERS PLUS LTD.
Q10010. How to use FastRAM?

Summary

This article describe features of using FastRAM.

Guide

For activating FastRAM you need execute CPU instruction IN A,(#FB). After that, in the first memory frame (0000h-3FFFh) will paged empty 16K of FastRAM memory. You may use this memory for more fast routine speed. FastRAM not require any allocation calls for use it. And you shouldn't stored the actual data there.
Remember, if you execute external program, it may destroy your data and code in FastRAM.
And you must do copy your code to FastRAM again for restore it.
Also you can't call BIOS or DSS function during FastRAM are activated.
For deactivating FastRAM you need execute CPU instruction IN A,(#7B).
After that, a first memory frame will paged back 16K of normal memory.

We recommend to disable interrupts for avoid any errors when you will switch FastRAM.

More information

Today, only 16K of FastRAM are available for use.
If you want to use the interrupts, you should put interrupt handler in #0038.
If you plan to use Accelerator in your FastRAM-routine, you must placed data for it more high than #3FFF.

FastRAM will be useful in following cases:

1. If you not use the Accelerator.
2. If you use the RAM data not so often.
3. If program stack was placed into the FastRAM.

1 August 2002.
PETERS PLUS LTD.
Q10015. How to load any palette or separate color?

Summary

This article contain examples of loading a palette and separated color.

More information

Code: Select all

;Set 5th color as GREEN
		LD	HL,COLOUR
		LD	DE,#0105
		LD	BC,#FFA4
		XOR	A
		RST	#08

;			 B   G   R
COLOUR		DB	#00,#80,#00,#00

...

;Change all colors of palette
		LD	HL,COLOURS
		LD	DE,#0000
		LD	BC,#FFA4
		XOR	A
		RST	#08

;Color's parameters
;			 B   G   R
COLOUR		DB	#00,#80,#00,#00

;Palette
COLOURS		DB	#00,#00,#00,#00	;Colour 0
		DB	#00,#00,#80,#00	;Colour 1
		DB	#00,#80,#00,#00	;Colour 2
		DB	#00,#80,#80,#00	;Colour 3

		DB	#FF,#FF,#FF,#00	;Colour 255
19 March 2003.
PETERS PLUS LTD.
Q10017. How the DSS/BIOS can be paged out and replaced with RAM at $0000-$3fff?

Summary

This article contain an example of replacing memory page.

More information

You should disable interrupt before replacing memory page.

Code: Select all

Replace
        DI             ; disable interrupts
        IN A,($82)     ; get page which set $0000-$3FFFF
        LD (DSSPAGE),A ; store dss page number
        LD A,your_page ;
        OUT ($82),A    ; replace it with your page.

Restore
        LD A,(DSSPAGE) ; restore dss page number
        OUT ($82),A    ; back dss page
        EI             ; enable interrupts
7 April 2003.
PETERS PLUS LTD.
Q10021. How to call an Estex application from my program?

Summary

This article contain example for calling an external program.

More information

Code: Select all

	LD	HL,prog
	LD	BC,DSS_EXEC
	RST	#10

prog	db	"prog.exe",0
7 May 2003.
PETERS PLUS LTD.
Last edited by Shaos on 18 May 2013 00:02, edited 1 time in total.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Software issues
Q10005. Sometimes DOOM demo not work.

Symptoms

Error message of Spectrum Basic - "Out of memory".

Cause

Program need more memory. One or more RAM-disks are created.

Solution

1. Execute Setup Utility (by pressing "Delete" key during starting of computer)
2. Select 'Safe RAM-disks' item and disable it.
3. Press "F10" key for exit with changes.

30 May 2002.
PETERS PLUS LTD.
Q10011. FlashROM Writer work (update of BIOS) was aborted when the verify bar has reached its end.

Cause
First verifing is checking of integrity of the BIOSxxx.EXE file. Program work was aborted because check was finished not successfully.

Solution

1. Copy the BIOSxxx.EXE file to your disk by another floppy disk again.
2. Executing programm again.

7 June 2002.
PETERS PLUS LTD.
Q10016. The game Thunder In The Deep not works.

Symptoms

System message "Out of memory". There are no RAM-Disks in the memory.

Cause

Program requires more memory. Several programs were run before start of the game.

Solution

Run the game in Flex Navigator or in User Menu or in command line after computer reset.

3 April 2003.
PETERS PLUS LTD.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Hardware issues
Q10003. Hard disk was detected, but Estex DSS not start.

Symptoms

BIOS wrote "Detecting IDE Primary Slave - None"

Cause

Some old hard disks can't was detected as single hard disk.

Solution

1. Enter to the Setup Utility (by pressing "Delete" key during starting of computer)
2. Select 'IDE Slave' item and disable it.
3. Press "F10" key for save setting and exit.

30 May 2002.
PETERS PLUS LTD.
Q10004. Sprinter computer not work with two 3.5" floppy disk drives (FDD).

Symptoms

Two 3,5" FDD was connected to the crossed FDD ribbon cable. FDD "A" not work.

Cause

Usage of crossed FDD ribbon cable.

Solution

Use FDD which has jumper "A/B device" and FDD ribbon cable from Sprinter's mainboard package. If you haven't Sprinter's FDD ribbon cable, make Sprinter's FDD ribbon cable from a standard FDD ribbon cable. You should uncross the cable.

30 May 2002.
PETERS PLUS LTD.[/b]
Q10006. Video cable for Amstrad CTM644 monitor.

Summary

This article include info of video cable pins for Amstrad CTM644 monitor.

More information

Code: Select all

CTM644 pins		Sprinter DB15 pins

   2  		   	    GND 1 
   4  		   	    composite sync 13 
   6  		   	    green 10 
   7  		   	    red 11 
   8  		   	    blue 9 
30 May 2002.
PETERS PLUS LTD.
Q10007. How to install CD-ROM drive?

Summary

This article describe CD-ROM drive installation.
WARNING! Installing a new drive such as a CD-ROM drive or hard disk involves opening computer cover, and handling internal cables and wiring. Because of this, you should not try to install a CD-ROM drive or hard disk unless you are already very familiar with the process. For information about how to install a CD-ROM drive or hard disk, contact the manufacturer of the device, or view the documentation included with your device.

Solution

1. Check jumper position at the back side of the CD-ROM drive. CD-ROM drive must be set as Slave device if you have installed HDD as IDE Master.
2. Switch off your computer.
3. Install your CD-ROM drive in the computer case.
4. Switch on the computer.
5. Check BIOS autodetection message for SLAVE IDE device. BIOS must detect your CD-ROM drive and write its name.

More Information

Also you can specify CD-ROM drive for the IDE SLAVE manually by Setup Utility.
1. Enter to the Setup Utility (by press "Delete" key when a computer starting).
2. Select "IDE Slave" item and change it to the "CD-ROM".
3. Press "F10" key for exit with save changes.

19 June 2002.
PETERS PLUS LTD.
Q10012. Hard disk was detected, but BIOS says "Invalid partition table"

Symptoms

600Mb-2Gb hard disk was detected by BIOS, but then BIOS says "Invalid partition table".

Cause

Your hard disk hasn't "partition table" or uses another partition code, not 0x01 (FAT12), 0x04 (FAT16 'old' up to 32M), 0x06 (FAT16 over 32M), 0x0E (FAT16 'win95' LBA-mapped). Probably, it is 0x0B (FAT32 'win95'), 0x0C (FAT32 'win95' LBA-mapped), 0x1B (FAT32 'hidden'), 0x1C (FAT32 'hidden' LBA-mapped) or another code.

Solution

You should prepare your hard disk as MS-DOS FAT16 disk before formating it.

5 January 2003.
PETERS PLUS LTD.
Q10013. Hard disk was detected, but BIOS says "Invalid BOOT sector".

Symptoms

Hard disk was formated with boot sector, but computer .

Cause

Your hard disk was prepared as MS-DOS FAT32 disk. FAT32 and FAT16 has boot sectors with different structure.

Solution

You should prepare your hard disk as MS-DOS FAT16 disk and format it again with boot sector.

5 January 2003.
PETERS PLUS LTD. [/b]
Q10014. I've made a connector to load stuff from Tape but it not work.

Symptoms

Occasional flickering on load "".

Cause

Too high CPU frequency.

Solution

You should disable Turbo Mode by pressing F12 key before usage a Tape.

1 February 2003.
PETERS PLUS LTD.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Programming
Q10009. Screen memory location.

Summary

This article contain usage examples of graphic modes.

More information

Today, Estex DSS support four screen modes: text 40x32 with 16 colors (mode 02h); text 80x32 with 16 colors (mode 03h); graphic 320x256 with 256 colors (mode 81h); graphic 640x256 with 16 colors (mode 82h); The default mode for the DSS is 80x32 text mode, if your program need another screen mode then you need to switch it by DSS function 50h (SETVMOD). Also before switching you should ask DSS and save current screen mode by function 51h (GETVMOD). And when you program will be ready to finished, restore it by 50h (SETVMOD). for example:

Code: Select all

	LD	C,51h	;get screen mode
	RST	10h
	LD	C,A	;move mode number to register C
	PUSH	BC	;and save to stack BC (B - active page, C - mode)
	.
	. 		;your program
	.

	POP	BC	;restore mode from stack
	LD	A,C	;move screen mode to register A
	LD	C,50h	;set screen mode
	RST	10h
	LD	C,41h	;terminate program
	RST	10h
DSS has some functions for outing symbols and strings at the text screen. But for the graphic modes you need to write it yourself. for example:

Code: Select all

	LD	HL,STRING	;pointer to the string
	LD	C,5Ch		;outing string
	RST	10h

STRING	DB	"Thank you for using my program..."
	DB	13,10		;CR and LF codes
	DB	0		;End of string
For painting at the graphic screen memory, you need to set one of three memory frames 04000h-07FFFh, 08000h-0BFFFh, 0C000h-0FFFFh. It can be made by set value 50h to the ports 0A2h, 0C2h or 0E2h. Don't forgot about STACK place! for example: if you want to set one point then routine for 81h mode will look like:

Code: Select all

; HL - x coord
; DE - y coord
	IN	A,(0E2h)	;read page number
	LD	C,A		;move it to C (save)
	LD	A,50h		;page of video RAM
	OUT	(0E2h),A	;set it to third frame 0C000-0FFFFh
	LD	A,E		;Y-coord (0...255)
	OUT	(89h),A		;set to Y-port
	LD	DE,0C000h	;frame address
	ADD	HL,DE		;add x-coord
	LD	A,255		;point color (0...255) (index to palette)
	LD	(HL),A		;put pixel
	LD	A,C		;restore page number
	OUT	(0E2h)		;set it
Note: Before it, you need to set required colors at the palette.

30 May 2002.
PETERS PLUS LTD.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Routines collection
Q10018. Routine of transformation of half-byte to ASCII symbol.

Assembler

Any assembler.

Input

A = low 4 bits

Output

À = ASCII symbol (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)

Routine

Code: Select all

        And  #0F
        Cp   #0A
        Sbc  #69
        Daa
Added by
Mac Buster
Q10019. Routine (GetSwitch) of filling of ASCIIZ buffer with the command-line parameter value.

More information

Routine fills an ASCIIZ buffer with the string after the "=" sign of a predetermined command-line switch of the form /SWITCH=VALUE. The switch name is *NOT* case sensitive.

Assembler

Any assembler.

Input

(SP+0)=Ret address
(SP+2)=Address of cmdline ASCIIZ string, preceded by its len in ONE byte
(SP+4)=Address of ASCIIZ parameter to find its value
(SP+6)=Address of ASCIIZ buffer to fill with the parameter's value

Output

Carry flag reset=OK
Carry flag set=Error (no chars in cmdline, etc)
A : Zero
BC: Amount of chars remaining in command line
DE: Points to the terminating NULL of the buffer to fill
HL: Points to one after the last byte copied from the cmdline

Routine

Code: Select all

GetSwitch:	POP	HL		;Fetch return address in HL
		POP	DE		;Fetch cmdline address in DE
		POP	BC		;Fetch param address in BC
		EX	(SP),HL		;Push ret addr, buffer addr to HL
		LD	(GS_Param),BC	;Save param ASCIIZ address
		LD	(GS_OutBf),HL	;Save output buffer address
		EX	DE,HL		;CmdLine to HL, OutBuff to DE
		LD	C,(HL)		;CmdLine len to C (just-a-byte)
		LD	B,0		;Hi-byte of BC is zero
		INC	HL		;Point to first char in CmdLine
GS_GetSlash:	LD	A,"/"		;Char to find to A
		CPIR			;Find the slash
		JR	Z,GS_ChkParam	;Slash found. Check param.
		JR	GS_Error	;Outta chars or no slashes!
GS_ChkParam:	LD	DE,(GS_Param)	;Param name address to DE
		DEC	HL		;Compensate for first INC HL
GS_CP_Loop:	DEC	BC		;Take char into account
		INC	HL		;Point to next char
		LD	A,(DE)		;Param name char to A
		INC	DE		;Point to next char in param name
		OR	A		;Is End Of String?
		JR	Z,GS_Found	;Jump if so: Param found!
		CP	(HL)		;Same as (HL)?
		JR	Z,GS_CP_Loop	;Continue if so
		XOR	020h		;Toggle uppercase/lowercase bit
		CP	(HL)		;Same as (HL)?
		JR	Z,GS_CP_Loop	;Jump if so
		JR	GS_GetSlash	;Bad param: Continue search for "/"
GS_Found:	LD	A,(HL)		;Char should be "="
		CP	"="		;Is it?
		JR	NZ,GS_GetSlash	;Jump back if not: Wrong param
		INC	HL		;Point to char after equals sign
		LD	DE,(GS_OutBf)	;DE points to start of buffer
GS_CopyBuff:	LD	A,(HL)		;Move value char to A
		CP	" "		;Is space?
		JR	Z,GS_Done	;Jump if so. Transfer finished
		CP	00h		;End of cmdline?
		JR	Z,GS_Done	;Jump if so. No more to transfer
		LD	(DE),A		;Copy char to output buffer
		INC	HL		;Point to next char
		INC	DE		;Point to next placeholder
		JR	GS_CopyBuff	;Loop back until done
GS_Done:	XOR	A		;Reset A
		LD	(DE),A		;Terminate the string  
		RET			;Done :)
GS_Error:	SCF			;Flag "ERROR!!!"
		RET			;Done :(

GS_OutBf:	DB	00h,00h		;Output buffer address
GS_Param:	DB	00h,00h		;Parameter name address
Added by
Marcelo Lopez
Q10020. Routine (ExpandMacros) of expanded macros in an ASCII buffer with the nth ASCIIZ string from another buffer.

More information

Will replace occurrences of "%1" to "%9" in an ASCIIZ buffer for the Nth ASCIIZ string from a parameter buffer, delivering an ASCII (not ASCIIZ) string in a supplied address. The parameter string block MUST start with a NULL char (ASCII 0).

Example:

Code: Select all

	Src:	DB	"Marcelo %1 %2."
	Param:	DB	00,"made",00,"me.",00
	Desti:	DB	00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00
After executing the routine, DESTI will hold the following string (note that the destination string is not ASCIIZ):

Code: Select all

	Desti:	DB	"Marcelo made me."
Assembler

Any assembler.

Input

(SP+6) -> Source buffer start address (Src in the example)
(SP+4) -> Param buffer start address (Param in the example)
(SP+2) -> Destination buffer start address (Desti in the example)
(SP+0) -> Normal return address
Output
A : Zero
B : Zero (if strings replaced), Hi byte of param buff addr if not
C : Low byte of parameter buffer address
DE: Pointer to the last byte in the output buffer + 1
HL: Pointer to the last byte in the source buffer + 1

Routine

Code: Select all

ExpandMacros:	POP	HL		;Fetch ret addr briefly
		POP	DE		;Fetch OutBuffer in DE
		POP	BC		;Fetch ParBuffer in BC
		EX	(SP),HL		;Exchg Ret to (SP) and RawBuff to HL
EM_SavePtr:	LD	(EM_PBuff),BC	;Save param buffer ptr
EM_Loop:	LD	A,(HL)		;Char to A
		INC	HL		;Point to next char
		OR	A		;Is it a zero?
		RET	Z		;Finished if so
		CP	"%"		;Is it the macro indicator?
		JR	NZ,EM_CopyChr	;Jump if not
		LD	A,(HL)		;Char after "%" to A
		CP	"0"		;Is char > "0"?
		JR	NC,EM_ChkNine	;Jump if so
EM_CopyPct:	LD	A,"%"		;Restore percentage sign in A
		JR	EM_CopyChr	;And transfer it to out buffer
EM_ChkNine:	CP	"9"		;Is char lower than "9"?
		JR	NC,EM_CopyPct	;Jump if not to transfer the "%"
		SUB	"0"		;Now is 0 <= A <= 9
		PUSH	HL		;Save input buffer pointer
		LD	HL,(EM_PBuff)	;Get Param Buffer address in HL
		LD	B,A		;Param number to B
		XOR	A		;Reset A to zero
EM_FindPar:	PUSH	BC		;Save counter in B
		LD	BC,0		;Prepare to loop thru 64K
		CPIR			;Look for a zero char
		POP	BC		;Restore zeroes counter
		DJNZ	EM_FindPar	;Loop back until param is found
EM_CopyPar:	LD	A,(HL)		;Param char to A
		INC	HL		;Point to next char in param
		OR	A		;Is it zero?
		JR	NZ,EM_CopyPar2	;Go on to copy char
		POP	HL		;Restore main in buffer pointer
		INC	HL		;Skip param number
		JR	EM_Loop		;And continue looping
EM_CopyPar2:	LD	(DE),A		;Copy char in param to output buffer
		INC	DE		;Advance out buffer pointer
		JR	EM_CopyPar	;And loop thru all chars in param
EM_CopyChr:	LD	(DE),A		;Copy char in main to output buffer
		INC	DE		;Advance out buffer pointer
		JR	EM_Loop		;And loop thru all chars in main

EM_PBuff:	DW	0000h		;Param buffer save zone
Added by
Marcelo Lopez
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Routines collection (cont.)
Q10022. Routine (Ascii2Word) of converting an ASCIIZ buffer with numbers to a word.

More information

Routine converts an ASCIIZ number to a 2-byte value. The number can have a prefix character to preset the number base. In case of hex numbers, the letter case does NOT matter. This routine DOES NOT deal with negative or fractional numbers. All returned values are positive. The routine will work with values in the range 0 - 65,535 (dec), 0 - FFFF (hex), 0 - 177777 (oct), or 0 - 1111 1111 1111 1111 (bin).

Prefix:
"@": Means OCTAL number follows (ex: @345; bad ex: @87)
"#": Means HEXADECIMAL number follows (ex: #F00f; bad ex: #G0)
"%": Means BINARY number follows (ex: %1010; bad ex: %5)
'no prefix': Default, for DECIMAL numbers (ex: 987; bad ex: 3A57)

Assembler

Any assembler.

Input

(SP+2) -> ASCIIZ string starting address
(SP+0) -> Normal return address

Output

Carry flag reset: Operation was successful.
A=Lo-byte of converted word
HL=Converted word
Carry flag set: Error (overflow or invalid char in buffer)

Routine

Code: Select all

Ascii2Word:	POP	HL		;Fetch ret addr briefly
		EX	(SP),HL		;Exchg Ret (SP) with BufferAddr (HL)
A2W_Init:	LD	DE,0		;Reset...
		LD	(A2W_RetVal),DE	;...return value
		LD	A,(HL)		;Get first char in buffer
		LD	C,0Fh		;Prepare for HEX
		CP	"#"		;Is HEX prefix?
		JR	Z,A2W_Nxt	;Jump if so
		LD	C,07h		;Prepare for OCT
		CP	"@"		;Is OCT prefix?
		JR	Z,A2W_Nxt	;Jump if so
		LD	C,01h		;Prepare for BIN
		CP	"%"		;Is BIN prefix?
		JR	Z,A2W_Nxt	;Jump if so
		LD	C,09h		;Ok, number is DEC
		DEC	HL		;Compensate for next INC HL
A2W_Nxt:	INC	HL		;Point to next char in buffer
		LD	A,(HL)		;Char to A
		CP	0h		;End of string?
		JR	Z,A2W_Done	;Jump if so
		PUSH	HL		;Save buffer address while adding
		LD	HL,(A2W_RetVal)	;Get return value so far
		PUSH	HL		;Copy HL to...
		POP	DE		;... register DE
		LD	B,C		;Get loop index to B
A2W_Add:	ADC	HL,DE		;Perform sum...
		DJNZ	A2W_Add		;... B times
		JR	C,A2W_Ovfl	;Abort if overflow
		SUB	"0"		;Convert ASCII in A to number
		CP	9		;Less than 9?
		JR	C,A2W_Chk	;Jump if so.
		RES	5,A		;Force char uppercase (just in case)
		SUB	7		;Deduct "A" - "9" diff.
A2W_Chk:	LD	E,A		;Save number to E
		LD	D,0		;Reset hi-byte of DE
		INC	C		;Test if...
		CP	C		;... A > C, and...
		JR	NC,A2W_Ovfl	;... abort if so...
		DEC	C		;... 'cos it's invalid char.
		XOR	A		;Clear carry flag for next ADC
		ADC	HL,DE		;Add the number to the return value
		JR	C,A2W_Ovfl	;Jump if overflow
		LD	(A2W_RetVal),HL	;Store result so far
		POP	HL		;Fetch back string pointer
		JR	A2W_Nxt		;Keep looping
A2W_Ovfl:	SCF			;Set carry flag to say "Error!"
		POP	HL		;Stack balancing
		RET			;Return to caller
A2W_Done:	LD	HL,(A2W_RetVal)	;Fetch return value
		LD	A,L		;Lo-byte of result to A
		RET			;Back to caller

A2W_RetVal:	DEFW	0000h		;Return value storage
Added by
Marcelo Lopez
Q10023. Routine (Word2Hex) of preparing a 16 bit number to be printed in HEX form.

More information

Converts a 2-byte value to four hexadecimal characters. All values are considered positive. Uses Byte2Hex routine twice...

Assembler

Any assembler.

Input

(SP+4) -> Number to convert
(SP+2) -> Four-byte ASCII buffer start address
(SP+0) -> Normal return address

Output

ASCII buffer is filled with the converted number
A : Ascii code of lowest nibble of converted number
DE: Number to convert
HL: Pointer to last char in buffer

Routine

Code: Select all

Word2Hex:	POP	DE		;Get ret address temporarily
		POP	HL		;Get Buffer address
		LD	(W2HBuf),HL	;Save Buffer address
		POP	HL		;Get Number
		LD	(W2HNum),HL	;Save Number
		PUSH	DE		;Push return address
		LD	L,H		;MSB to LSB
		PUSH	HL		;Push MSB
		LD	HL,(W2HBuf)	;Retrieve buffer pointer
		PUSH	HL		;Push buffer address
		CALL	Byte2Hex	;Fill half buffer
		INC	HL		;HL points to third char in buffer
		LD	DE,(W2HNum)	;DE now holds LSB of Number
		PUSH	DE		;Number to Stack
		PUSH	HL		;Buffer to Stack
		CALL	Byte2Hex	;Fill rest of buffer
		RET			;Done.

W2HBuf:		DW	0000h
W2HNum:		DW	0000h
Added by
Marcelo Lopez
Q10024. Routine (Byte2Hex) of preparing an 8 bit number to be printed in HEX form.

More information

Converts a 1-byte value to four hexadecimal characters. All values are considered positive.

Assembler

Any assembler.

Input

(SP+4) -> Number to convert (in LSB, MSB is ignored)
(SP+2) -> Two-byte ASCII buffer start address
(SP+0) -> Normal return address

Output

ASCII buffer is filled with the converted number
A : Ascii code of lowest nibble of converted number
D : Ignored MSB of number to convert
E : Number to convert
HL: Pointer to last char in buffer

Routine

Code: Select all

Byte2Hex:	POP	HL		;Get ret address temporarily
		POP	DE		;Get Buffer address
		LD	(B2HBuf),DE	;Save Buffer address
		POP	DE		;Get Number
		PUSH	HL		;Push return value
		LD	HL,(B2HBuf)	;Make HL point to buffer
		LD	A,E		;Number to A (H=0, and ignored)
		RRCA			;Get hi-nibble of A into lo-nibble
		RRCA
		RRCA
		RRCA
		AND	0Fh		;Isolate lo-nibble
		ADD	A,"0"		;Add ASCII for zero
		CP	3Ah		;Greater than "9"?
		JR	C,B2HBig1	;Jump if so
		ADD	A,07h		;Add ASCII difference to "A"
B2HBig1:	LD	(HL),A		;Save char to buffer
		INC	HL		;Point to next char in buffer
		LD	A,E		;Rretrieve number
		AND	0Fh		;Isolate lo-nibble
		ADD	A,"0"		;Add ASCII for "0"
		CP	3Ah		;Greater than "9"?
		JR	C,B2HBig2	;Jump if so
		ADD	A,07h		;Add ASCII difference to "A"
B2HBig2:	LD	(HL),A		;Save char to buffer
		RET			;Done.

B2HBuf:		DW	0000h
Added by
Marcelo Lopez
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 23989
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Routines collection (cont.)
Q10025. Routine (Byte2Ascii) of preparing an 8 bit number to be printed in decimal form.

More information

Routine converts an 1-byte number to ASCII characters. Leading zeroes are replaced by spaces. All values are considered positive.

Assembler

Any assembler.

Input

(SP+4) -> Number to convert (in LSB, MSB is ignored)
(SP+2) -> Three-byte ASCII buffer start address
(SP+0) -> Normal return address

Output

ASCII buffer is filled with converted number
A : Ascii code of LSB
C : Ascii code of mid-significant digit (or space, if it was zero)
HL: Pointer to last char in buffer

Routine

Code: Select all

Byte2Ascii:	POP	BC		;Fetch ret address temporarily
		POP	HL		;Fetch ASCII buffer address
		POP	DE		;Fetch nmber to convert in E
		PUSH	BC		;Push back ret address
		LD	A,E		;Get number to convert in A
		LD	C,"0"-1		;Prepare character
B2A_3:		INC	C		;Inc char
		SUB	100		;Subtract 100 from A
		JR	NC,B2A_3	;Keep looping until negative
		ADD	A,100		;Restore positive value
		LD	E,A		;Save value temporarily
		LD	A,C		;Hundreds char to A
		CP	"0"		;Is zero?
		JR	NZ,B2A_Hundreds	;Jump if not
		LD	C," "		;Preset to put a space if Hundreds=0
B2A_Hundreds:	LD	(HL),C		;Save hundreds char
		LD	A,E		;Retrieve old value
		INC	HL		;Point to next char
		LD	C,"0"-1		;Prepare character
B2A_2:		INC	C		;Inc char
		SUB	10		;Subtract 10 from A
		JR	NC,B2A_2	;Keep looping until negative
		ADD	A,"0"+10	;Restore positive value (and ASCII)
		LD	E,A		;Save char briefly
		LD	A,C		;Tens char to A
		CP	"0"		;Is zero?
                JR	NZ,B2A_Tens	;Jump if not
		LD	C," "		;Change char to be a space
		LD	A,E		;Retrieve last char
B2A_Tens:	LD	(HL),C		;Save tens char
		INC	HL		;Point to next char
		LD	(HL),A		;Save units char (don't check for 0)
		RET			;Done 
Added by
Marcelo Lopez
Q10026. Routine (Word2Ascii) of preparing a 16 bit number to be printed in decimal form.

More information

Routine converts a 2-byte number to ASCII characters. All values are considered positive.

Assembler

Any assembler.

Input

(SP+4) -> Number to convert
(SP+2) -> Five-byte ASCII buffer start address
(SP+0) -> Normal return address

Output

ASCII buffer is filled with converted number
A : Ascii code of LSB
BC: 000Ah
DE: Buffer start address
HL: Least significant digit of number to convert

Routine

Code: Select all

;Word2Ascii:	POP	BC		;Retrieve ret address
;		POP	DE		;Fetch ASCII buffer
;		POP	HL		;Fetch number to convert
;		PUSH	BC		;Push ret address back
Word2Ascii:	POP	HL		;Ret addr briefly to HL
		POP	DE		;Fetch ASCII buffer to DE
		EX	(SP),HL		;Exchg Ret (SP) with Number (HL)
		LD	BC,10000	;Prepare BC to subtract
		PUSH	IX		;Save content of IX
		PUSH	DE		;Transfer content of
		POP	IX		;Register DE to IX
		LD	(IX+0),"0"-1	;Insert char in buffer
		XOR	A		;Clear carry flag
W2A_5:		INC	(IX+0)		;Inc char
                SBC	HL,BC		;Deduct 10K from HL
		JR	NC,W2A_5	;Loop until negative result
		ADD	HL,BC		;Restore positive in HL
		LD	BC,1000		;Prepare BC to subtract
		LD	(IX+1),"0"-1	;Insert char in buffer
		XOR	A		;Clear carry flag
W2A_4:		INC	(IX+1)		;Inc char
		SBC	HL,BC		;Deduct 1K from HL
		JR	NC,W2A_4	;Loop until negative result
		ADD	HL,BC		;Restore positive in HL
		LD	BC,100		;Prepare BC to subtract
		LD	(IX+2),"0"-1	;Insert char in buffer
		XOR	A		;Clear carry flag
W2A_3:		INC	(IX+2)		;Inc char
		SBC	HL,BC		;Deduct 100 from HL
		JR	NC,W2A_3	;Loop until negative result
		ADD	HL,BC		;Restore positive in HL
		LD	BC,10		;Prepare BC to subtract
		LD	(IX+3),"0"-1	;Insert char in buffer
		XOR	A		;Clear carry flag
W2A_2:		INC	(IX+3)		;Inc char
		SBC	HL,BC		;Deduct 10 from HL
		JR	NC,W2A_2	;Loop until negative result
		ADD	HL,BC		;Restore positive to HL
		LD	A,L		;Last number to A
		ADD	A,"0"		;Add the "0" difference
		LD	(IX+4),A	;Put last char in buffer
		POP	IX		;Restore original value in IX
		RET
Added by
Marcelo Lopez
Я тут за главного - если что шлите мыло на me собака shaos точка net