forked from MirrorRepos/RomWBW
Browse Source
- Added KBDINFO which dumps low level info about keyboards. - Updated KBDTEST and VDCTEST to put the keyboard controller into translation mode which is what these programs were intended to use.patch
11 changed files with 835 additions and 79 deletions
@ -1,5 +1,5 @@ |
|||
OBJECTS = |
|||
SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz kbdtest vdctest |
|||
SUBDIRS = DMAmon I2C inttest ppidetst ramtest tstdskng rzsz vdctest kbdtest kbdinfo |
|||
DEST = ../../../Binary/Apps/Test |
|||
TOOLS =../../../Tools |
|||
|
|||
|
|||
@ -0,0 +1,10 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
set TOOLS=../../../../Tools |
|||
set PATH=%TOOLS%\tasm32;%PATH% |
|||
set TASMTABS=%TOOLS%\tasm32 |
|||
|
|||
tasm -t180 -g3 -fFF kbdinfo.asm kbdinfo.com kbdinfo.lst || exit /b |
|||
|
|||
copy /Y kbdinfo.com ..\..\..\..\Binary\Apps\Test\ || exit /b |
|||
@ -0,0 +1,6 @@ |
|||
@echo off |
|||
setlocal |
|||
|
|||
if exist *.com del *.com |
|||
if exist *.lst del *.lst |
|||
if exist *.bin del *.bin |
|||
@ -0,0 +1,7 @@ |
|||
OBJECTS = kbdinfo.com |
|||
DEST = ../../../../Binary/Apps/Test |
|||
TOOLS =../../../../Tools |
|||
|
|||
USETASM=1 |
|||
|
|||
include $(TOOLS)/Makefile.inc |
|||
@ -0,0 +1,699 @@ |
|||
; |
|||
;======================================================================= |
|||
; Keyboard Information Utility (KBDINFO) |
|||
;======================================================================= |
|||
; |
|||
; Simple utility that attempts to determine the type of keyboard you |
|||
; have attached to an 8242 keyboard controller. |
|||
; |
|||
;======================================================================= |
|||
; |
|||
; Keyboard controller port addresses (adjust as needed) |
|||
; |
|||
iocmd .equ $E3 ; keyboard controller command port address |
|||
iodat .equ $E2 ; keyboard controller data port address |
|||
; |
|||
; General operational equates (should not requre adjustment) |
|||
; |
|||
stksiz .equ $40 ; Working stack size |
|||
; |
|||
timeout .equ $00 ; Controller timeout constant |
|||
; |
|||
restart .equ $0000 ; CP/M restart vector |
|||
bdos .equ $0005 ; BDOS invocation vector |
|||
; |
|||
;======================================================================= |
|||
; |
|||
.org $100 ; standard CP/M executable |
|||
; |
|||
; |
|||
; setup stack (save old value) |
|||
ld (stksav),sp ; save stack |
|||
ld sp,stack ; set new stack |
|||
; |
|||
call crlf |
|||
ld de,str_banner ; banner |
|||
call prtstr |
|||
; |
|||
call main ; do the real work |
|||
; |
|||
exit: |
|||
call crlf2 |
|||
ld de,str_exit |
|||
call prtstr |
|||
;call crlf |
|||
|
|||
; clean up and return to command processor |
|||
call crlf ; formatting |
|||
ld sp,(stksav) ; restore stack |
|||
jp restart ; return to CP/M via restart |
|||
; |
|||
; |
|||
;======================================================================= |
|||
; Main Program |
|||
;======================================================================= |
|||
; |
|||
main: |
|||
; |
|||
; Display active keyboard controller port addresses |
|||
; |
|||
call crlf2 |
|||
ld de,str_cmdport |
|||
call prtstr |
|||
ld a,iocmd |
|||
call prthex |
|||
call crlf |
|||
ld de,str_dataport |
|||
call prtstr |
|||
ld a,iodat |
|||
call prthex |
|||
; |
|||
; Attempt self-test command on keyboard controller |
|||
; |
|||
; Keyboard controller should respond with an 0x55 on data port |
|||
; after being sent a 0xAA on the command port. |
|||
; |
|||
call crlf2 |
|||
ld de,str_ctrl_test |
|||
call prtstr |
|||
ld a,$aa ; self-test command |
|||
call put_cmd_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $55 ; expected value? |
|||
jp nz,err_ctlr_test ; handle self-test error |
|||
call crlf |
|||
ld de,str_ctrl_test_ok |
|||
call prtstr |
|||
; |
|||
; Disable translation on keyboard controller to get raw scan codes! |
|||
; |
|||
call crlf2 |
|||
ld de,str_trans_off |
|||
call prtstr |
|||
ld a,$60 ; write to command register 0 |
|||
call put_cmd_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
ld a,$20 ; xlat disabled, mouse disabled, no ints |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
; |
|||
; |
|||
; |
|||
call test2 |
|||
; |
|||
; Enable translation on keyboard controller |
|||
; |
|||
call crlf2 |
|||
ld de,str_trans_on |
|||
call prtstr |
|||
ld a,$60 ; write to command register 0 |
|||
call put_cmd_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
ld a,$60 ; xlat disabled, mouse disabled, no ints |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
; |
|||
; fall thru |
|||
; |
|||
test2: |
|||
; |
|||
; Perform a keyboard reset |
|||
; |
|||
call crlf2 |
|||
ld de,str_kbd_reset |
|||
call prtstr |
|||
ld a,$ff ; Keyboard reset |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $FA ; Is it an ack as expected? |
|||
jp nz,err_kbd_reset |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $AA ; Success? |
|||
jp nz,err_kbd_reset |
|||
call crlf |
|||
ld de,str_kbd_reset_ok |
|||
call prtstr |
|||
; |
|||
; Identify keyboard |
|||
; |
|||
call crlf2 |
|||
ld de,str_kbd_ident |
|||
call prtstr |
|||
ld a,$f2 ; Identify keyboard command |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $FA ; Is it an ack as expected? |
|||
jp nz,err_kbd_ident |
|||
; Now we need to receive 0-2 bytes. There is no way to know |
|||
; how many are coming, so we receive bytes until there is a |
|||
; timeout error. |
|||
ld ix,workbuf |
|||
ld iy,workbuf_len |
|||
xor a |
|||
ld (iy),a |
|||
ident_loop: |
|||
call get_data_dbg |
|||
jr c,ident_done |
|||
ld (ix),a |
|||
inc ix |
|||
inc (iy) |
|||
jr ident_loop |
|||
ident_done: |
|||
call crlf |
|||
ld de,str_kbd_ident_disp |
|||
call prtstr |
|||
ld a,'[' |
|||
call prtchr |
|||
ld ix,workbuf |
|||
ld b,(iy) |
|||
xor a |
|||
cp b |
|||
jr z,ident_done2 |
|||
ident_done1: |
|||
ld a,(ix) |
|||
call prthex |
|||
inc ix |
|||
djnz ident_done1 |
|||
ident_done2: |
|||
ld a,']' |
|||
call prtchr |
|||
; |
|||
; Get active scan code set being used |
|||
; |
|||
call crlf2 |
|||
ld de,str_kbd_getsc |
|||
call prtstr |
|||
ld a,$f0 ; Keyboard get/set scan code |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $FA ; Is it an ack as expected? |
|||
jp nz,err_kbd_getsc |
|||
ld a,$00 ; Get active scan code set |
|||
call put_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
cp $FA ; Is it an ack as expected? |
|||
jp nz,err_kbd_getsc |
|||
call get_data_dbg |
|||
jp c,err_ctlr_io ; handle controller error |
|||
push af |
|||
call crlf |
|||
ld de,str_kbd_dispsc |
|||
call prtstr |
|||
pop af |
|||
call prtdecb |
|||
;;;; |
|||
;;;; Set active scan code set to 2 |
|||
;;;; |
|||
;;; call crlf2 |
|||
;;; ld de,str_kbd_setsc |
|||
;;; call prtstr |
|||
;;; ld a,$f0 ; Keyboard get/set scan code |
|||
;;; call put_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; call get_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; cp $FA ; Is it an ack as expected? |
|||
;;; jp nz,err_kbd_getsc |
|||
;;; ld a,$02 ; Set scan code set to 2 |
|||
;;; call put_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; call get_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; cp $FA ; Is it an ack as expected? |
|||
;;; jp nz,err_kbd_getsc |
|||
;;;; |
|||
;;;; Get active scan code set being used |
|||
;;;; |
|||
;;; call crlf2 |
|||
;;; ld de,str_kbd_getsc |
|||
;;; call prtstr |
|||
;;; ld a,$f0 ; Keyboard get/set scan code |
|||
;;; call put_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; call get_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; cp $FA ; Is it an ack as expected? |
|||
;;; jp nz,err_kbd_getsc |
|||
;;; ld a,$00 ; Get active scan code set |
|||
;;; call put_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; call get_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; cp $FA ; Is it an ack as expected? |
|||
;;; jp nz,err_kbd_getsc |
|||
;;; call get_data_dbg |
|||
;;; jp c,err_ctlr_io ; handle controller error |
|||
;;; push af |
|||
;;; call crlf |
|||
;;; ld de,str_kbd_dispsc |
|||
;;; call prtstr |
|||
;;; pop af |
|||
;;; and $0f |
|||
;;; call prtdecb |
|||
; |
|||
; Read and display raw scan codes |
|||
; |
|||
call crlf2 |
|||
ld de,str_disp_scan_codes |
|||
call prtstr |
|||
read_loop: |
|||
ld c,$06 ; BDOS direct console I/O |
|||
ld e,$FF ; Subfunction = read |
|||
call bdos |
|||
cp $1B ; Escape key? |
|||
jp z,done |
|||
call check_read |
|||
jr nz,read_loop |
|||
call get_data |
|||
jp c,err_ctlr_io ; handle controller error |
|||
push af |
|||
ld a,' ' |
|||
call prtchr |
|||
ld a,'[' |
|||
call prtchr |
|||
pop af |
|||
call prthex |
|||
ld a,']' |
|||
call prtchr |
|||
jr read_loop |
|||
|
|||
done: |
|||
ret |
|||
; |
|||
;======================================================================= |
|||
; Keyboard Controller I/O Routines |
|||
;======================================================================= |
|||
; |
|||
wait_write: |
|||
; |
|||
; Wait for keyboard controller to be ready for a write |
|||
; A=0 indicates success (ZF set) |
|||
; |
|||
ld b,timeout ; setup timeout constant |
|||
wait_write1: |
|||
in a,(iocmd) ; get status |
|||
ld c,a ; save status |
|||
and $02 ; isolate input buf status bit |
|||
ret z ; 0 means ready, all done |
|||
call delay ; wait a bit |
|||
djnz wait_write1 ; loop until counter exhausted |
|||
ld de,str_timeout_write ; write timeout message |
|||
call crlf |
|||
call prtstr |
|||
ld a,c ; recover last status value |
|||
call prthex |
|||
or $ff ; signal error |
|||
ret |
|||
; |
|||
wait_read: |
|||
; |
|||
; Wait for keyboard controller to be ready to read a byte |
|||
; A=0 indicates success (ZF set) |
|||
; |
|||
ld b,timeout ; setup timeout constant |
|||
wait_read1: |
|||
in a,(iocmd) ; get status |
|||
ld c,a ; save status |
|||
and $01 ; isolate input buf status bit |
|||
xor $01 ; invert so 0 means ready |
|||
ret z ; if 0, all done |
|||
call delay ; wait a bit |
|||
djnz wait_read1 ; loop until counter exhausted |
|||
ld de,str_timeout_read ; write timeout message |
|||
call crlf |
|||
call prtstr |
|||
ld a,c ; recover last status value |
|||
call prthex |
|||
or $ff ; signal error |
|||
ret |
|||
; |
|||
check_read: |
|||
; |
|||
; Check for data ready to read |
|||
; A=0 indicates data available (ZF set) |
|||
; |
|||
in a,(iocmd) ; get status |
|||
and $01 ; isolate input buf status bit |
|||
xor $01 ; invert so 0 means ready |
|||
ret |
|||
; |
|||
put_cmd: |
|||
; |
|||
; Put a cmd byte from A to the keyboard interface with timeout |
|||
; CF set indicates timeout error |
|||
; |
|||
ld e,a ; save incoming value |
|||
call wait_write ; wait for controller ready |
|||
jr z,put_cmd1 ; if ready, move on |
|||
scf ; else, signal timeout error |
|||
ret ; and bail out |
|||
put_cmd1: |
|||
ld a,e ; recover value to write |
|||
out (iocmd),a ; write it |
|||
or a ; clear CF for success |
|||
ret |
|||
; |
|||
put_cmd_dbg: |
|||
call put_cmd |
|||
ret c |
|||
push af |
|||
call crlf |
|||
ld de,str_put_cmd |
|||
call prtstr |
|||
call prthex |
|||
pop af |
|||
ret |
|||
; |
|||
put_data: |
|||
; |
|||
; Put a data byte from A to the keyboard interface with timeout |
|||
; CF set indicates timeout error |
|||
; |
|||
ld e,a ; save incoming value |
|||
call wait_write ; wait for controller ready |
|||
jr z,put_data1 ; if ready, move on |
|||
scf ; else, signal timeout error |
|||
ret ; and bail out |
|||
put_data1: |
|||
ld a,e ; recover value to write |
|||
out (iodat),a ; write it |
|||
or a ; clear CF for success |
|||
ret |
|||
; |
|||
put_data_dbg: |
|||
call put_data |
|||
ret c |
|||
push af |
|||
call crlf |
|||
ld de,str_put_data |
|||
call prtstr |
|||
call prthex |
|||
pop af |
|||
ret |
|||
|
|||
; |
|||
; Get a data byte from the keyboard interface to A with timeout |
|||
; CF set indicates timeout error |
|||
; |
|||
get_data: |
|||
call wait_read ; wait for byte to be ready |
|||
jr z,get_data1 ; if readym, move on |
|||
scf ; else signal timeout error |
|||
ret ; and bail out |
|||
get_data1: |
|||
in a,(iodat) ; get data byte |
|||
or a ; clear CF for success |
|||
ret |
|||
; |
|||
get_data_dbg: |
|||
call get_data |
|||
ret c |
|||
push af |
|||
call crlf |
|||
ld de,str_get_data |
|||
call prtstr |
|||
call prthex |
|||
pop af |
|||
ret |
|||
; |
|||
; Error Handlers |
|||
; |
|||
err_ctlr_io: |
|||
ld de,str_err_ctrl_io |
|||
jr err_ret |
|||
; |
|||
err_ctlr_test: |
|||
ld de,str_err_ctrl_test |
|||
jr err_ret |
|||
; |
|||
err_kbd_reset: |
|||
ld de,str_err_kbd_reset |
|||
jr err_ret |
|||
; |
|||
err_kbd_getsc: |
|||
ld de,str_err_kbd_getsc |
|||
jr err_ret |
|||
; |
|||
err_kbd_setsc: |
|||
ld de,str_err_kbd_setsc |
|||
jr err_ret |
|||
; |
|||
err_kbd_ident: |
|||
ld de,str_err_kbd_ident |
|||
jr err_ret |
|||
; |
|||
err_ret: |
|||
call crlf2 |
|||
call prtstr |
|||
or $ff ; signal error |
|||
ret |
|||
; |
|||
;======================================================================= |
|||
; Utility Routines |
|||
;======================================================================= |
|||
; |
|||
; |
|||
; Print character in A without destroying any registers |
|||
; |
|||
prtchr: |
|||
push bc ; save registers |
|||
push de |
|||
push hl |
|||
ld e,a ; character to print in E |
|||
ld c,$02 ; BDOS function to output a character |
|||
call bdos ; do it |
|||
pop hl ; restore registers |
|||
pop de |
|||
pop bc |
|||
ret |
|||
; |
|||
prtdot: |
|||
; |
|||
; shortcut to print a dot preserving all regs |
|||
push af ; save af |
|||
ld a,'.' ; load dot char |
|||
call prtchr ; print it |
|||
pop af ; restore af |
|||
ret ; done |
|||
; |
|||
; Print a zero terminated string at (de) without destroying any registers |
|||
; |
|||
prtstr: |
|||
push af |
|||
push de |
|||
; |
|||
prtstr1: |
|||
ld a,(de) ; get next char |
|||
or a |
|||
jr z,prtstr2 |
|||
call prtchr |
|||
inc de |
|||
jr prtstr1 |
|||
; |
|||
prtstr2: |
|||
pop de ; restore registers |
|||
pop af |
|||
ret |
|||
; |
|||
; Print the value in A in hex without destroying any registers |
|||
; |
|||
prthex: |
|||
push af ; save AF |
|||
push de ; save DE |
|||
call hexascii ; convert value in A to hex chars in DE |
|||
ld a,d ; get the high order hex char |
|||
call prtchr ; print it |
|||
ld a,e ; get the low order hex char |
|||
call prtchr ; print it |
|||
pop de ; restore DE |
|||
pop af ; restore AF |
|||
ret ; done |
|||
; |
|||
; print the hex word value in hl |
|||
; |
|||
prthexword: |
|||
push af |
|||
ld a,h |
|||
call prthex |
|||
ld a,l |
|||
call prthex |
|||
pop af |
|||
ret |
|||
; |
|||
; print the hex dword value in de:hl |
|||
; |
|||
prthex32: |
|||
push bc |
|||
push de |
|||
pop bc |
|||
call prthexword |
|||
push hl |
|||
pop bc |
|||
call prthexword |
|||
pop bc |
|||
ret |
|||
; |
|||
; Convert binary value in A to ascii hex characters in DE |
|||
; |
|||
hexascii: |
|||
ld d,a ; save A in D |
|||
call hexconv ; convert low nibble of A to hex |
|||
ld e,a ; save it in E |
|||
ld a,d ; get original value back |
|||
rlca ; rotate high order nibble to low bits |
|||
rlca |
|||
rlca |
|||
rlca |
|||
call hexconv ; convert nibble |
|||
ld d,a ; save it in D |
|||
ret ; done |
|||
; |
|||
; Convert low nibble of A to ascii hex |
|||
; |
|||
hexconv: |
|||
and $0F ; low nibble only |
|||
add a,$90 |
|||
daa |
|||
adc a,$40 |
|||
daa |
|||
ret |
|||
; |
|||
; Print value of A or HL in decimal with leading zero suppression |
|||
; Use prtdecb for A or prtdecw for HL |
|||
; |
|||
prtdecb: |
|||
push hl |
|||
ld h,0 |
|||
ld l,a |
|||
call prtdecw ; print it |
|||
pop hl |
|||
ret |
|||
; |
|||
prtdecw: |
|||
push af |
|||
push bc |
|||
push de |
|||
push hl |
|||
call prtdec0 |
|||
pop hl |
|||
pop de |
|||
pop bc |
|||
pop af |
|||
ret |
|||
; |
|||
prtdec0: |
|||
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 prtchr |
|||
ret |
|||
; |
|||
; Start a new line |
|||
; |
|||
crlf2: |
|||
call crlf ; two of them |
|||
crlf: |
|||
push af ; preserve AF |
|||
ld a,13 ; <CR> |
|||
call prtchr ; print it |
|||
ld a,10 ; <LF> |
|||
call prtchr ; print it |
|||
pop af ; restore AF |
|||
ret |
|||
; |
|||
; Brief delay |
|||
; |
|||
delay: |
|||
push bc |
|||
ld b,0 |
|||
delay1: |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
ex (sp),hl |
|||
djnz delay1 |
|||
pop bc |
|||
ret |
|||
; |
|||
;======================================================================= |
|||
; Constants |
|||
;======================================================================= |
|||
; |
|||
str_banner .db "Keyboard Information, v0.1",0 |
|||
str_exit .db "Done, Thank you for using KBDINFO!",0 |
|||
str_cmdport .db "Keyboard Controller Command Port: 0x",0 |
|||
str_dataport .db "Keyboard Controller Data Port: 0x",0 |
|||
str_timeout_write .db "Keyboard Controller Write Timeout, Status: 0x",0 |
|||
str_timeout_read .db "Keyboard Controller Read Timeout, Status: 0x",0 |
|||
str_err_ctrl_io .db "Keyboard Controller I/O Failure",0 |
|||
str_err_ctrl_test .db "Keyboard Controller Self-Test Failed",0 |
|||
str_put_cmd .db "Sent Command 0x",0 |
|||
str_put_data .db "Sent Data 0x",0 |
|||
str_get_data .db "Got Data 0x",0 |
|||
str_ctrl_test .db "Attempting Controller Self-Test",0 |
|||
str_ctrl_test_ok .db "Controller Self-Test OK",0 |
|||
str_trans_off .db "Disabling Controller Translation",0 |
|||
str_trans_on .db "Enabling Controller Translation",0 |
|||
str_kbd_reset .db "Attempting Keyboard Reset",0 |
|||
str_kbd_reset_ok .db "Keyboard Reset OK",0 |
|||
str_err_kbd_reset .db "Keyboard Reset Failed",0 |
|||
|
|||
str_kbd_getsc .db "Requesting Active Scan Code Set from Keyboard",0 |
|||
str_kbd_dispsc .db "Active Keyboard Scan Code Set is ",0 |
|||
str_err_kbd_getsc .db "Error getting active keyboard scan code set",0 |
|||
str_kbd_setsc .db "Setting Active Keyboard Scan Code Set",0 |
|||
str_err_kbd_setsc .db "Error setting keyboard scan code set",0 |
|||
str_kbd_ident .db "Keyboard Identification",0 |
|||
str_kbd_ident_disp .db "Keyboard Identify: ",0 |
|||
str_err_kbd_ident .db "Error performing Keyboard Identification",0 |
|||
str_disp_scan_codes .db "Displaying Raw Scan Codes",13,10 |
|||
.db " Press keys on keyboard to display scan codes",13,10 |
|||
.db " Press <esc> on CP/M console to end",13,10,13,10,0 |
|||
; |
|||
;======================================================================= |
|||
; Working data |
|||
;======================================================================= |
|||
; |
|||
stksav .dw 0 ; stack pointer saved at start |
|||
.fill stksiz,0 ; stack |
|||
stack .equ $ ; stack top |
|||
; |
|||
workbuf .fill 8 |
|||
workbuf_len .db 0 |
|||
; |
|||
;======================================================================= |
|||
; |
|||
.end |
|||
Loading…
Reference in new issue