mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-02 16:10:55 +11:00
Compare commits
2 Commits
ab578159b7
...
aa8df95f7d
Author | SHA1 | Date | |
---|---|---|---|
|
aa8df95f7d | ||
|
64935d8b40 |
@ -62,8 +62,12 @@ instrNames:
|
||||
.equ I_RCALL 42
|
||||
.db "RCALL", 0
|
||||
.db "RJMP", 0
|
||||
.equ I_IN 44
|
||||
.db "IN", 0
|
||||
.equ I_OUT 45
|
||||
.db "OUT", 0
|
||||
; no arg (from here, instrUpMasks2)
|
||||
.equ I_BREAK 44
|
||||
.equ I_BREAK 46
|
||||
.db "BREAK", 0
|
||||
.db "CLC", 0
|
||||
.db "CLH", 0
|
||||
@ -91,7 +95,7 @@ instrNames:
|
||||
.db "SLEEP", 0
|
||||
.db "WDR", 0
|
||||
; Rd(5)
|
||||
.equ I_ASR 70
|
||||
.equ I_ASR 72
|
||||
.db "ASR", 0
|
||||
.db "COM", 0
|
||||
.db "DEC", 0
|
||||
@ -143,6 +147,9 @@ instrUpMasks1:
|
||||
; k(12): XXXXkkkk kkkkkkkk
|
||||
.db 0b11010000 ; RCALL
|
||||
.db 0b11000000 ; RJMP
|
||||
; IN and OUT
|
||||
.db 0b10110000 ; IN
|
||||
.db 0b10111000 ; OUT
|
||||
|
||||
; 16-bit constant masks associated with each instruction. In the same order as
|
||||
; in instrNames
|
||||
@ -239,8 +246,11 @@ parseInstruction:
|
||||
jr c, .spitRdK8
|
||||
cp I_RCALL
|
||||
jr c, .spitRdBit
|
||||
cp I_BREAK
|
||||
cp I_IN
|
||||
jr c, .spitK12
|
||||
jp z, .spitIN
|
||||
cp I_OUT
|
||||
jp z, .spitOUT
|
||||
cp I_ASR
|
||||
jr c, .spitNoArg
|
||||
; spitRd5
|
||||
@ -273,7 +283,7 @@ parseInstruction:
|
||||
ld b, a
|
||||
call .getUp1
|
||||
; now that's our MSB
|
||||
jr .spitMSB
|
||||
jp .spitMSB
|
||||
|
||||
.spitRdK8:
|
||||
ld ix, argSpecs+6 ; 'r', 8
|
||||
@ -293,7 +303,7 @@ parseInstruction:
|
||||
rra \ rra \ rra \ rra
|
||||
ld b, a
|
||||
call .getUp1
|
||||
jr .spitMSB
|
||||
jp .spitMSB
|
||||
|
||||
.spitRdBit:
|
||||
ld ix, argSpecs+8 ; 'R', 'b'
|
||||
@ -337,6 +347,36 @@ parseInstruction:
|
||||
or b
|
||||
jp ioPutB
|
||||
|
||||
.spitOUT:
|
||||
ld ix, argSpecs+12 ; 'A', 'R'
|
||||
call _parseArgs
|
||||
ret nz
|
||||
ld a, h
|
||||
ld h, l
|
||||
ld l, a
|
||||
jr .spitINOUT
|
||||
.spitIN:
|
||||
ld ix, argSpecs+14 ; 'R', 'A'
|
||||
call _parseArgs
|
||||
ret nz
|
||||
.spitINOUT:
|
||||
; Rd in H, A in L
|
||||
ld a, h
|
||||
call .placeRd
|
||||
ld a, l
|
||||
and 0xf
|
||||
or c
|
||||
; LSB ready
|
||||
call ioPutB
|
||||
; The two high bits of A go in bits 3:1 of MSB
|
||||
ld a, l
|
||||
rra \ rra \ rra
|
||||
and 0b110
|
||||
or b
|
||||
ld b, a
|
||||
; MSB is almost ready
|
||||
call .getUp1
|
||||
jr .spitMSB
|
||||
.spit:
|
||||
; LSB is spit *before* MSB
|
||||
inc hl
|
||||
@ -449,6 +489,8 @@ argSpecs:
|
||||
.db 'r', 8 ; Rd(4) + K(8)
|
||||
.db 'R', 'b' ; Rd(5) + bit
|
||||
.db 'b', 7 ; bit + k(7)
|
||||
.db 'A', 'R' ; A(6) + Rr(5)
|
||||
.db 'R', 'A' ; Rd(5) + A(6)
|
||||
|
||||
; Parse arguments in (HL) according to specs in IX
|
||||
; Puts the results in HL (which is not needed anymore after the parsing).
|
||||
@ -493,25 +535,44 @@ _parseArgs:
|
||||
jr z, _readR4
|
||||
cp 'b'
|
||||
jr z, _readBit
|
||||
cp 'A'
|
||||
jr z, _readA6
|
||||
cp 7
|
||||
jr z, _readk7
|
||||
cp 8
|
||||
jr z, _readK8
|
||||
ret ; something's wrong
|
||||
|
||||
_readBit:
|
||||
; Read expr and return success only if result in under number given in A
|
||||
; Z for success
|
||||
_readExpr:
|
||||
push ix
|
||||
push bc
|
||||
ld b, a
|
||||
call parseExpr
|
||||
ld a, 7
|
||||
jr nz, .end
|
||||
ld a, b
|
||||
call _IX2A
|
||||
jr nz, .end
|
||||
or c
|
||||
ld c, a
|
||||
cp a ; ensure Z
|
||||
.end:
|
||||
pop bc
|
||||
pop ix
|
||||
ret
|
||||
|
||||
_readBit:
|
||||
ld a, 7
|
||||
jr _readExpr
|
||||
|
||||
_readA6:
|
||||
ld a, 0x3f
|
||||
|
||||
_readK8:
|
||||
ld a, 0xff
|
||||
jr _readExpr
|
||||
|
||||
_readk7:
|
||||
push hl
|
||||
push de
|
||||
@ -549,16 +610,6 @@ _readk7:
|
||||
call unsetZ
|
||||
jr .end
|
||||
|
||||
_readK8:
|
||||
push ix
|
||||
call parseExpr
|
||||
jr nz, .end
|
||||
ld a, 0xff
|
||||
call _IX2A
|
||||
.end:
|
||||
pop ix
|
||||
ret
|
||||
|
||||
_readR4:
|
||||
call _readR5
|
||||
ret nz
|
||||
|
16
avr/README.md
Normal file
16
avr/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# AVR include files
|
||||
|
||||
This folder contains header files that can be included in AVR assembly code.
|
||||
|
||||
These definitions are organized in a manner that is very similar to other
|
||||
modern AVR assemblers, but most bits definitions (`PINB4`, `WGM01`, etc.) are
|
||||
absent. This is because there's a lot of them, each symbol takes memory during
|
||||
assembly and machines doing the assembling might be tight in memory. AVR code
|
||||
post collapse will have to take the habit of using numerical masks accompanied
|
||||
by comments describing associated symbols.
|
||||
|
||||
To avoid repeats, those includes are organized in 3 levels. First, there's the
|
||||
`avr.h` file containing definitions common to all AVR models. Then, there's the
|
||||
"family" file containing definitions common to a "family" (for example, the
|
||||
ATtiny 25/45/85). Those definitions are the beefiests. Then, there's the exact
|
||||
model file, which will typically contain RAM and Flash boundaries.
|
17
avr/avr.h
Normal file
17
avr/avr.h
Normal file
@ -0,0 +1,17 @@
|
||||
; *** CPU registers aliases ***
|
||||
|
||||
.equ XH 27
|
||||
.equ XL 26
|
||||
.equ YH 29
|
||||
.equ YL 28
|
||||
.equ ZH 31
|
||||
.equ ZL 30
|
||||
|
||||
.equ SREG_C 0 ; Carry Flag
|
||||
.equ SREG_Z 1 ; Zero Flag
|
||||
.equ SREG_N 2 ; Negative Flag
|
||||
.equ SREG_V 3 ; Two's Complement Overflow Flag
|
||||
.equ SREG_S 4 ; Sign Bit
|
||||
.equ SREG_H 5 ; Half Carry Flag
|
||||
.equ SREG_T 6 ; Bit Copy Storage
|
||||
.equ SREG_I 7 ; Global Interrupt Enable
|
10
avr/tn25.h
Normal file
10
avr/tn25.h
Normal file
@ -0,0 +1,10 @@
|
||||
.equ FLASHEND 0x03ff ; Note: Word address
|
||||
.equ IOEND 0x003f
|
||||
.equ SRAM_START 0x0060
|
||||
.equ SRAM_SIZE 128
|
||||
.equ RAMEND 0x00df
|
||||
.equ XRAMEND 0x0000
|
||||
.equ E2END 0x007f
|
||||
.equ EEPROMEND 0x007f
|
||||
.equ EEADRBITS 7
|
||||
|
74
avr/tn254585.h
Normal file
74
avr/tn254585.h
Normal file
@ -0,0 +1,74 @@
|
||||
; *** Registers ***
|
||||
|
||||
.equ SREG 0x3f
|
||||
.equ SPH 0x3e
|
||||
.equ SPL 0x3d
|
||||
.equ GIMSK 0x3b
|
||||
.equ GIFR 0x3a
|
||||
.equ TIMSK 0x39
|
||||
.equ TIFR 0x38
|
||||
.equ SPMCSR 0x37
|
||||
.equ MCUCR 0x35
|
||||
.equ MCUSR 0x34
|
||||
.equ TCCR0B 0x33
|
||||
.equ TCNT0 0x32
|
||||
.equ OSCCAL 0x31
|
||||
.equ TCCR1 0x30
|
||||
.equ TCNT1 0x2f
|
||||
.equ OCR1A 0x2e
|
||||
.equ OCR1C 0x2d
|
||||
.equ GTCCR 0x2c
|
||||
.equ OCR1B 0x2b
|
||||
.equ TCCR0A 0x2a
|
||||
.equ OCR0A 0x29
|
||||
.equ OCR0B 0x28
|
||||
.equ PLLCSR 0x27
|
||||
.equ CLKPR 0x26
|
||||
.equ DT1A 0x25
|
||||
.equ DT1B 0x24
|
||||
.equ DTPS 0x23
|
||||
.equ DWDR 0x22
|
||||
.equ WDTCR 0x21
|
||||
.equ PRR 0x20
|
||||
.equ EEARH 0x1f
|
||||
.equ EEARL 0x1e
|
||||
.equ EEDR 0x1d
|
||||
.equ EECR 0x1c
|
||||
.equ PORTB 0x18
|
||||
.equ DDRB 0x17
|
||||
.equ PINB 0x16
|
||||
.equ PCMSK 0x15
|
||||
.equ DIDR0 0x14
|
||||
.equ GPIOR2 0x13
|
||||
.equ GPIOR1 0x12
|
||||
.equ GPIOR0 0x11
|
||||
.equ USIBR 0x10
|
||||
.equ USIDR 0x0f
|
||||
.equ USISR 0x0e
|
||||
.equ USICR 0x0d
|
||||
.equ ACSR 0x08
|
||||
.equ ADMUX 0x07
|
||||
.equ ADCSRA 0x06
|
||||
.equ ADCH 0x05
|
||||
.equ ADCL 0x04
|
||||
.equ ADCSRB 0x03
|
||||
|
||||
|
||||
; *** Interrupt vectors ***
|
||||
|
||||
.equ INT0addr 0x0001 ; External Interrupt 0
|
||||
.equ PCI0addr 0x0002 ; Pin change Interrupt Request 0
|
||||
.equ OC1Aaddr 0x0003 ; Timer/Counter1 Compare Match 1A
|
||||
.equ OVF1addr 0x0004 ; Timer/Counter1 Overflow
|
||||
.equ OVF0addr 0x0005 ; Timer/Counter0 Overflow
|
||||
.equ ERDYaddr 0x0006 ; EEPROM Ready
|
||||
.equ ACIaddr 0x0007 ; Analog comparator
|
||||
.equ ADCCaddr 0x0008 ; ADC Conversion ready
|
||||
.equ OC1Baddr 0x0009 ; Timer/Counter1 Compare Match B
|
||||
.equ OC0Aaddr 0x000a ; Timer/Counter0 Compare Match A
|
||||
.equ OC0Baddr 0x000b ; Timer/Counter0 Compare Match B
|
||||
.equ WDTaddr 0x000c ; Watchdog Time-out
|
||||
.equ USI_STARTaddr 0x000d ; USI START
|
||||
.equ USI_OVFaddr 0x000e ; USI Overflow
|
||||
|
||||
.equ INT_VECTORS_SIZE 15 ; size in words
|
9
avr/tn45.h
Normal file
9
avr/tn45.h
Normal file
@ -0,0 +1,9 @@
|
||||
.equ FLASHEND 0x07ff ; Note: Word address
|
||||
.equ IOEND 0x003f
|
||||
.equ SRAM_START 0x0060
|
||||
.equ SRAM_SIZE 256
|
||||
.equ RAMEND 0x015f
|
||||
.equ XRAMEND 0x0000
|
||||
.equ E2END 0x00ff
|
||||
.equ EEPROMEND 0x00ff
|
||||
.equ EEADRBITS 8
|
9
avr/tn85.h
Normal file
9
avr/tn85.h
Normal file
@ -0,0 +1,9 @@
|
||||
.equ FLASHEND 0x0fff ; Note: Word address
|
||||
.equ IOEND 0x003f
|
||||
.equ SRAM_START 0x0060
|
||||
.equ SRAM_SIZE 512
|
||||
.equ RAMEND 0x025f
|
||||
.equ XRAMEND 0x0000
|
||||
.equ E2END 0x01ff
|
||||
.equ EEPROMEND 0x01ff
|
||||
.equ EEADRBITS 9
|
43
tools/tests/avra/blink_tn45.asm
Normal file
43
tools/tests/avra/blink_tn45.asm
Normal file
@ -0,0 +1,43 @@
|
||||
; TODO: implement instructions that are commented out
|
||||
; REGISTER USAGE
|
||||
;
|
||||
; R1: overflow counter
|
||||
; R16: tmp stuff
|
||||
|
||||
.inc "avr.h"
|
||||
.inc "tn254585.h"
|
||||
.inc "tn45.h"
|
||||
|
||||
main:
|
||||
ldi r16, RAMEND&0xff
|
||||
out SPL, r16
|
||||
ldi r16, RAMEND}8
|
||||
out SPH, r16
|
||||
|
||||
;sbi DDRB, 0
|
||||
;cbi PORTB, 0
|
||||
|
||||
; To have a blinking delay that's visible, we have to prescale a lot.
|
||||
; The maximum prescaler is 1024, which makes our TCNT0 increase
|
||||
; 976 times per second, which means that it overflows 4 times per
|
||||
; second.
|
||||
in r16, TCCR0B
|
||||
ori r16, 0x05 ; CS00 + CS02 = 1024 prescaler
|
||||
out TCCR0B, r16
|
||||
|
||||
;clr r1
|
||||
|
||||
loop:
|
||||
in r16, TIFR ; TIFR0
|
||||
sbrc r16, 1 ; is TOV0 flag clear?
|
||||
rcall toggle
|
||||
rjmp loop
|
||||
|
||||
toggle:
|
||||
ldi r16, 0b00000010 ; TOV0
|
||||
out TIFR, R16
|
||||
inc r1
|
||||
;cbi PORTB, 0
|
||||
sbrs r1, 1 ; if LED is on
|
||||
;sbi PORTB, 0
|
||||
ret
|
1
tools/tests/avra/blink_tn45.expected
Normal file
1
tools/tests/avra/blink_tn45.expected
Normal file
@ -0,0 +1 @@
|
||||
å
¿à¿·`¿·ýÐüÏà¿”þ•
|
@ -1,11 +1,12 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
AVRA=../../emul/zasm/avra
|
||||
ZASM=../../zasm.sh
|
||||
AVRINC=../../../avr
|
||||
|
||||
cmpas() {
|
||||
FN=$1
|
||||
EXPECTED=$(xxd ${FN%.*}.expected)
|
||||
ACTUAL=$(cat ${FN} | $AVRA | xxd)
|
||||
ACTUAL=$(cat ${FN} | "${ZASM}" -a "${AVRINC}" | xxd)
|
||||
if [ "$ACTUAL" = "$EXPECTED" ]; then
|
||||
echo ok
|
||||
else
|
||||
|
@ -12,3 +12,5 @@ sbrs r1, 3
|
||||
rjmp foo
|
||||
rcall baz
|
||||
baz:
|
||||
out 0x2e, r12
|
||||
in r0, 0x9
|
||||
|
Binary file not shown.
@ -6,15 +6,22 @@
|
||||
# binary. For example, "zasm.sh -o 4f < foo.asm" assembles foo.asm as if it
|
||||
# started with the line ".org 0x4f00".
|
||||
|
||||
# The -a flag makes us switch to the AVR assembler
|
||||
|
||||
# readlink -f doesn't work with macOS's implementation
|
||||
# so, if we can't get readlink -f to work, try python with a realpath implementation
|
||||
ABS_PATH=$(readlink -f "$0" || python -c "import os; print(os.path.realpath('$0'))")
|
||||
DIR=$(dirname "${ABS_PATH}")
|
||||
ZASMBIN="${DIR}/emul/zasm/zasm"
|
||||
|
||||
usage() { echo "Usage: $0 [-o <hexorg>] <paths-to-include>..." 1>&2; exit 1; }
|
||||
usage() { echo "Usage: $0 [-a] [-o <hexorg>] <paths-to-include>..." 1>&2; exit 1; }
|
||||
|
||||
org='00'
|
||||
while getopts ":o:" opt; do
|
||||
while getopts ":ao:" opt; do
|
||||
case "${opt}" in
|
||||
a)
|
||||
ZASMBIN="${DIR}/emul/zasm/avra"
|
||||
;;
|
||||
o)
|
||||
org=${OPTARG}
|
||||
;;
|
||||
@ -26,8 +33,6 @@ done
|
||||
shift $((OPTIND-1))
|
||||
|
||||
# wrapper around ./emul/zasm/zasm that prepares includes CFS prior to call
|
||||
DIR=$(dirname "${ABS_PATH}")
|
||||
ZASMBIN="${DIR}/emul/zasm/zasm"
|
||||
CFSPACK="${DIR}/cfspack/cfspack"
|
||||
INCCFS=$(mktemp)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user